WIP checkpoint: PC2: Basic visible player character representation
This commit is contained in:
+11
-3
@@ -34,11 +34,19 @@ func _ready() -> void:
|
||||
# scene root. The lookup walks the full subtree (recursive=true) so
|
||||
# it finds the marker whether it is a direct child of the level or
|
||||
# nested deeper.
|
||||
var spawn := get_tree().current_scene.find_child("PlayerSpawn", true, false)
|
||||
#
|
||||
# current_scene is null in headless --script mode and in any scene
|
||||
# before the main scene is fully swapped in, so guard it rather than
|
||||
# blindly dereferencing.
|
||||
var current_scene: Node = get_tree().current_scene
|
||||
var spawn: Node = null
|
||||
if current_scene != null:
|
||||
spawn = current_scene.find_child("PlayerSpawn", true, false)
|
||||
|
||||
if spawn is Node3D:
|
||||
global_position = spawn.global_position
|
||||
global_position = (spawn as Node3D).global_position
|
||||
# Align player forward with spawn yaw (optional polish).
|
||||
var spawn_yaw := spawn.rotation.y
|
||||
var spawn_yaw := (spawn as Node3D).rotation.y
|
||||
rotation.y = spawn_yaw
|
||||
else:
|
||||
push_warning("player.gd: no PlayerSpawn marker found; spawning at origin")
|
||||
|
||||
@@ -7,8 +7,8 @@ extends SceneTree
|
||||
## Loads the test level, verifies the player is present, spawned at the
|
||||
## PlayerSpawn marker, and has the expected CharacterBody3D structure.
|
||||
|
||||
var passed := 0
|
||||
var failed := 0
|
||||
var _passed := 0
|
||||
var _failed := 0
|
||||
|
||||
|
||||
func _initialize() -> void:
|
||||
@@ -20,60 +20,65 @@ func _run() -> void:
|
||||
await process_frame
|
||||
print("SMOKE: loading test level scene")
|
||||
|
||||
# Load the test level scene (which now includes the player).
|
||||
# Load the test level scene (which includes the player).
|
||||
var packed: PackedScene = load("res://scenes/worlds/test_level.tscn")
|
||||
var level: Node3D = packed.instantiate()
|
||||
|
||||
# Order matters: set_current_scene() requires the node's parent to already
|
||||
# be root, so add_child() must come first. This mirrors what a real
|
||||
# change_scene_to_packed() does at runtime.
|
||||
root.add_child(level)
|
||||
current_scene = level
|
||||
|
||||
print("SMOKE: level instantiated, waiting for ready")
|
||||
await level.ready
|
||||
print("SMOKE: level ready")
|
||||
|
||||
# 1. Verify the player node exists in the scene tree.
|
||||
var player := level.get_node("Player")
|
||||
var player: Node = level.get_node("Player")
|
||||
_check("Player node exists in test level", player != null)
|
||||
_check("Player is a CharacterBody3D", player is CharacterBody3D)
|
||||
|
||||
# 2. Verify the player has the expected child structure.
|
||||
var collision := player.get_node("CollisionShape3D")
|
||||
var collision: Node = player.get_node("CollisionShape3D")
|
||||
_check("Player has CollisionShape3D", collision != null)
|
||||
_check("CollisionShape3D has a shape", collision.shape != null)
|
||||
_check("CollisionShape3D has a shape",
|
||||
collision is CollisionShape3D and (collision as CollisionShape3D).shape != null)
|
||||
|
||||
var mesh := player.get_node("CapsuleMesh")
|
||||
var mesh: Node = player.get_node("CapsuleMesh")
|
||||
_check("Player has CapsuleMesh", mesh != null)
|
||||
_check("CapsuleMesh has a mesh", mesh.mesh != null)
|
||||
_check("CapsuleMesh has a mesh",
|
||||
mesh is MeshInstance3D and (mesh as MeshInstance3D).mesh != null)
|
||||
|
||||
# 3. Verify the player spawned at the PlayerSpawn marker position.
|
||||
var spawn_marker: Marker3D = level.get_node("PlayerSpawn")
|
||||
_check("PlayerSpawn marker exists", spawn_marker != null)
|
||||
|
||||
# The player's _ready() should have moved it to the spawn marker's
|
||||
# global position. Since both are direct children of the root, their
|
||||
# global positions equal their local positions.
|
||||
# global position. Since both are direct children of the level root
|
||||
# (and the level root is at the origin), their global positions equal
|
||||
# their local positions.
|
||||
var expected_pos: Vector3 = spawn_marker.global_position
|
||||
_check("Player spawned at PlayerSpawn position",
|
||||
player.global_position == expected_pos)
|
||||
|
||||
# 4. Verify the player script class_name is correct.
|
||||
var script := player.get_script()
|
||||
# 4. Verify the player script class_name is correct and has the
|
||||
# movement constants defined.
|
||||
var script: GDScript = player.get_script() as GDScript
|
||||
_check("Player has a script attached", script != null)
|
||||
_check("Player script is Player class", script is GDScript)
|
||||
var constants: Dictionary = script.get_script_constant_map()
|
||||
_check("Player has WALK_SPEED constant", constants.has("WALK_SPEED"))
|
||||
_check("Player has GRAVITY constant", constants.has("GRAVITY"))
|
||||
_check("Player has JUMP_VELOCITY constant", constants.has("JUMP_VELOCITY"))
|
||||
|
||||
# 5. Verify the player has movement constants defined.
|
||||
_check("Player has WALK_SPEED constant",
|
||||
script.get_constant("WALK_SPEED") != null)
|
||||
_check("Player has GRAVITY constant",
|
||||
script.get_constant("GRAVITY") != null)
|
||||
_check("Player has JUMP_VELOCITY constant",
|
||||
script.get_constant("JUMP_VELOCITY") != null)
|
||||
|
||||
print("\n=== SMOKE RESULT: %d/%d passed ===" % [passed, passed + failed])
|
||||
quit(0 if failed == 0 else 1)
|
||||
print("\n=== SMOKE RESULT: %d/%d passed ===" % [_passed, _passed + _failed])
|
||||
quit(0 if _failed == 0 else 1)
|
||||
|
||||
|
||||
func _check(description: String, condition: bool) -> void:
|
||||
if condition:
|
||||
print(" PASS: ", description)
|
||||
passed += 1
|
||||
_passed += 1
|
||||
else:
|
||||
printerr(" FAIL: ", description)
|
||||
failed += 1
|
||||
_failed += 1
|
||||
|
||||
Reference in New Issue
Block a user