diff --git a/src/editor/playtest/playtest_body.gd b/src/editor/playtest/playtest_body.gd index b8fa27e..12bb8b9 100644 --- a/src/editor/playtest/playtest_body.gd +++ b/src/editor/playtest/playtest_body.gd @@ -175,9 +175,15 @@ func _fahren(delta: float, input: Dictionary) -> void: _apply_look() return - # Welt-Richtung aus dem Blickwinkel (y-only, wie Client). - var forward := -transform.basis.z - var right := transform.basis.x + # Welt-Richtung aus dem Blickwinkel (y-only, wie Client). WICHTIG: aus + # yaw_deg bauen, NICHT aus transform.basis — die Kamera-Drehung steckt + # im look_cam-Kindknoten, der Körperknoten selbst rotiert nicht (Sly- + # Befund 20.10.: WASD lief sonst stur in eine Himmelsrichtung). Die + # Quest rotiert dagegen den ganzen Origin mit dem Kopf — hier + # entspricht yaw_deg diesem Kopf-Yaw. Identisch zu view_direction(). + var yaw_rad := deg_to_rad(yaw_deg) + var forward := Vector3(-sin(yaw_rad), 0.0, -cos(yaw_rad)) + var right := Vector3(cos(yaw_rad), 0.0, -sin(yaw_rad)) var dir := Vector3.ZERO var ad2: Variant = input.get("auto_dir", null) if ad2 is Vector3 and (ad2 as Vector3).length_squared() > 0.0: diff --git a/tests/test_playtest.gd b/tests/test_playtest.gd index 2b909ff..31af635 100644 --- a/tests/test_playtest.gd +++ b/tests/test_playtest.gd @@ -63,6 +63,7 @@ func _run_all() -> void: await _test_wall_blocks_player() await _test_step_up_semantics() await _test_run_and_jump() + await _test_yaw_relatives_laufen() await _test_bauteile_treppe_tuer() _test_exit_restores_editor() @@ -332,6 +333,39 @@ func _test_run_and_jump() -> void: _check(absf(body.fuss_hoehe() - feet0) < 0.05, "Landung wieder auf Terrainhöhe") +## --- Test 5b: Laufrichtung folgt der Blickrichtung (Sly-Befund 20.10.) ------ +## Bug: WASD benutzte transform.basis des Körpers, aber die Kamera-Drehung +## steckt im look_cam-Kindknoten → WASD lief stur in eine Himmelsrichtung. +## Fix: Richtung aus yaw_deg bauen (wie view_direction(), wie Quest-Kopf-Yaw). +func _test_yaw_relatives_laufen() -> void: + print("Testgruppe: Laufrichtung folgt Blickrichtung (yaw)") + var body := _body() + if body == null: + _check(false, "Playtest-Body aktiv (Vorbedingung)") + return + var start := Vector3(body.position) + # Blick nach -Z (yaw 0): W muss nach -Z laufen. + body.set("yaw_deg", 0.0) + body.set("auto_input", {"fwd": true}) + for i in 20: + await physics_frame + body.set("auto_input", {}) + var d0 := Vector3(body.position) - start + _check(d0.z < -1.0 and absf(d0.x) < 0.6, + "yaw 0° + W → Bewegung nach -Z (d=%.1f, %.1f)" % [d0.x, d0.z]) + # Blick um 90° gedreht (nach -X): W muss nach -X laufen, NICHT weiter -Z. + body.set("position", start) + body.set("velocity", Vector3.ZERO) + body.set("yaw_deg", 90.0) + await physics_frame + body.set("auto_input", {"fwd": true}) + for i in 20: + await physics_frame + body.set("auto_input", {}) + var d1 := Vector3(body.position) - start + _check(d1.x < -1.0 and absf(d1.z) < 0.6, + "yaw 90° + W → Bewegung folgt Blick nach -X (d=%.1f, %.1f)" % [d1.x, d1.z]) + ## --- Test 6: Rückkehr stellt den Editor-Zustand wieder her ------------------ func _test_exit_restores_editor() -> void: print("Testgruppe: Rückkehr in den Editor (Dokument + Undo unverändert)")