README: заметки для будущего меня; тестовые сцены в tools/test
- Договорённости с владельцем, замеры мувсета (стенами высоту не набрать), исправление подтягивания, конвейер Parkour и его грабли, ловушка с ресурсами, загружаемыми по строке - tools/test: measure_movement, mantle_test, parkour_gaps, parkour_tour, parkour_check.txt Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WxZo3ekR5m1af437Qzqwc1
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
extends Node
|
||||
# Подтягивание на уступы: тонкая полка и сплошной блок, коллизия «коробка» и «меш», ходьба и спринт, высоты 1,2–2,7 м.
|
||||
# Запуск: godot --headless --path . res://tools/test/mantle_test.tscn -- --client (ожидание: везде «ДА»)
|
||||
var root3d: Node3D
|
||||
var p
|
||||
# kind: "thin" (полка 0.6 м, под ней пусто) или "block" (сплошной блок от пола); shape: "box" или "mesh"
|
||||
func build(kind: String, shape: String, h: float) -> void:
|
||||
if root3d: root3d.queue_free()
|
||||
await get_tree().physics_frame
|
||||
root3d = Node3D.new(); add_child(root3d)
|
||||
var sb := StaticBody3D.new(); root3d.add_child(sb)
|
||||
var fl := CollisionShape3D.new(); var fb := BoxShape3D.new(); fb.size = Vector3(60, 1, 60); fl.shape = fb; fl.position = Vector3(0, -0.5, 0); sb.add_child(fl)
|
||||
var size := Vector3(10, 0.6, 12) if kind == "thin" else Vector3(10, h, 12)
|
||||
var cy := h - 0.3 if kind == "thin" else h * 0.5
|
||||
var cs := CollisionShape3D.new()
|
||||
if shape == "box":
|
||||
var b := BoxShape3D.new(); b.size = size; cs.shape = b
|
||||
else:
|
||||
var m := BoxMesh.new(); m.size = size; cs.shape = m.create_trimesh_shape()
|
||||
cs.position = Vector3(0, cy, -8 - size.z * 0.5) # передняя грань на z=-8
|
||||
sb.add_child(cs)
|
||||
func trial(kind: String, shape: String, h: float, sprint: bool) -> String:
|
||||
await build(kind, shape, h)
|
||||
p = (load("res://player/player.tscn") as PackedScene).instantiate()
|
||||
root3d.add_child(p)
|
||||
p.global_position = Vector3(0, 1.17, 0)
|
||||
await get_tree().physics_frame
|
||||
Input.action_press("move_forward")
|
||||
if sprint: Input.action_press("sprint")
|
||||
var f := 0; var jumped := false; var ok := false
|
||||
while f < 420:
|
||||
await get_tree().physics_frame; f += 1
|
||||
var dz: float = p.global_position.z + 8.0 # до грани
|
||||
if not jumped and dz < (-1.0 if not sprint else 0.0) + 2.4 and p.is_on_floor() and f > 30:
|
||||
jumped = true; Input.action_press("jump")
|
||||
if jumped and p.is_on_floor() and p.global_position.z < -8.2 and absf(p.global_position.y - (h + 1.16)) < 0.35:
|
||||
ok = true; break
|
||||
for a in ["move_forward","sprint","jump"]: Input.action_release(a)
|
||||
var res := "ДА " if ok else "нет"
|
||||
p.queue_free()
|
||||
return res
|
||||
func _ready() -> void:
|
||||
print("высота уступа: 1.2 1.6 2.0 2.4 2.7")
|
||||
for kind in ["thin", "block"]:
|
||||
for shape in ["box", "mesh"]:
|
||||
for sprint in [false, true]:
|
||||
var row := "%-5s %-4s %-6s " % [kind, shape, "спринт" if sprint else "ходьба"]
|
||||
for h in [1.2, 1.6, 2.0, 2.4, 2.7]:
|
||||
row += await trial(kind, shape, h, sprint) + " "
|
||||
print(row)
|
||||
get_tree().quit()
|
||||
Reference in New Issue
Block a user