Feat/14 movement overhaul #20
@@ -8,7 +8,7 @@ class_name SkinnedPlayerModel
|
||||
|
||||
var skeleton: Skeleton3D
|
||||
var animation_player: AnimationPlayer
|
||||
var animation_tree: AnimationTree
|
||||
var _anim_debug_timer: float = 0.0
|
||||
|
||||
func _ready() -> void:
|
||||
if model_path != "":
|
||||
@@ -31,18 +31,39 @@ func load_model(path: String) -> void:
|
||||
|
||||
add_child(scene)
|
||||
|
||||
# Find skeleton and animation player
|
||||
skeleton = find_skeleton(scene)
|
||||
# Debug: print the full scene tree
|
||||
print("SkinnedPlayerModel: scene tree after instantiation:")
|
||||
_print_tree(scene, 0)
|
||||
|
||||
# Find animation player — search entire tree including the scene root itself
|
||||
animation_player = find_animation_player(self)
|
||||
if not animation_player:
|
||||
animation_player = find_animation_player(scene)
|
||||
|
||||
skeleton = find_skeleton(self)
|
||||
if not skeleton:
|
||||
skeleton = find_skeleton(scene)
|
||||
|
||||
if animation_player:
|
||||
print("SkinnedPlayerModel: loaded '%s' with %d animations" % [
|
||||
path, animation_player.get_animation_list().size()
|
||||
])
|
||||
for anim in animation_player.get_animation_list():
|
||||
print(" - %s" % anim)
|
||||
var anim_list = animation_player.get_animation_list()
|
||||
print("SkinnedPlayerModel: found AnimationPlayer with %d animations:" % anim_list.size())
|
||||
for anim in anim_list:
|
||||
print(" - %s (length: %.2f)" % [anim, animation_player.get_animation(anim).length])
|
||||
# Auto-play idle
|
||||
if animation_player.has_animation("Idle"):
|
||||
animation_player.play("Idle")
|
||||
print("SkinnedPlayerModel: playing 'Idle'")
|
||||
elif anim_list.size() > 0:
|
||||
animation_player.play(anim_list[0])
|
||||
print("SkinnedPlayerModel: playing first anim: %s" % anim_list[0])
|
||||
else:
|
||||
print("SkinnedPlayerModel: no animation player found")
|
||||
print("SkinnedPlayerModel: WARNING - no AnimationPlayer found in scene tree")
|
||||
|
||||
func _print_tree(node: Node, depth: int) -> void:
|
||||
var indent = " " * depth
|
||||
print("%s%s (%s)" % [indent, node.name, node.get_class()])
|
||||
for child in node.get_children():
|
||||
_print_tree(child, depth + 1)
|
||||
|
||||
func find_skeleton(node: Node) -> Skeleton3D:
|
||||
if node is Skeleton3D:
|
||||
@@ -72,6 +93,15 @@ func _process(delta: float) -> void:
|
||||
if not animation_player:
|
||||
return
|
||||
|
||||
# Debug: print animation state occasionally
|
||||
_anim_debug_timer += delta
|
||||
if _anim_debug_timer > 2.0:
|
||||
_anim_debug_timer = 0.0
|
||||
if animation_player.is_playing():
|
||||
print("SkinnedPlayerModel: playing '%s' (pos: %.2f)" % [animation_player.current_animation, animation_player.current_animation_position])
|
||||
else:
|
||||
print("SkinnedPlayerModel: NOT playing any animation")
|
||||
|
||||
# Get movement state from the state machine
|
||||
var sm = get_parent().get_node_or_null("MovementStateMachine")
|
||||
if not sm:
|
||||
@@ -84,25 +114,16 @@ func _process(delta: float) -> void:
|
||||
var vel = sm.player.velocity
|
||||
speed = Vector2(vel.x, vel.z).length()
|
||||
|
||||
# Only change animation if it's different from current
|
||||
var target_anim = "Idle"
|
||||
match state:
|
||||
"ground", "idle":
|
||||
if speed > 1.0:
|
||||
play_animation("Run")
|
||||
else:
|
||||
play_animation("Idle")
|
||||
"air":
|
||||
play_animation("Idle")
|
||||
"crouch":
|
||||
play_animation("Idle")
|
||||
"slide":
|
||||
play_animation("Run")
|
||||
"wall_run":
|
||||
play_animation("Run")
|
||||
"wall_cling":
|
||||
play_animation("Idle")
|
||||
"grapple":
|
||||
play_animation("Run")
|
||||
"dash":
|
||||
play_animation("Run")
|
||||
target_anim = "Run"
|
||||
"slide", "wall_run", "grapple", "dash":
|
||||
target_anim = "Run"
|
||||
_:
|
||||
play_animation("Idle")
|
||||
target_anim = "Idle"
|
||||
|
||||
if animation_player.current_animation != target_anim or not animation_player.is_playing():
|
||||
play_animation(target_anim)
|
||||
|
||||
@@ -17,7 +17,9 @@ var _fps_label: Label
|
||||
var _standalone_speed_label: Label
|
||||
var _player: CharacterBody3D
|
||||
var _debug_ui_panel: PanelContainer
|
||||
|
||||
var _third_person: bool = false
|
||||
var _third_person_camera: Camera3D
|
||||
var _fps_camera: Camera3D
|
||||
|
||||
func _ready() -> void:
|
||||
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
|
||||
@@ -45,6 +47,61 @@ func _ready() -> void:
|
||||
p.queue_free()
|
||||
)
|
||||
|
||||
func _unhandled_input(event: InputEvent) -> void:
|
||||
if event is InputEventKey and event.pressed and not event.echo:
|
||||
if event.keycode == KEY_F1:
|
||||
_toggle_third_person()
|
||||
|
||||
func _toggle_third_person() -> void:
|
||||
_third_person = not _third_person
|
||||
|
||||
# Find cameras
|
||||
if not _fps_camera:
|
||||
_fps_camera = _find_camera_in_player()
|
||||
if not _third_person_camera:
|
||||
_setup_third_person_camera()
|
||||
|
||||
if _third_person:
|
||||
# Switch to third person
|
||||
if _fps_camera:
|
||||
_fps_camera.current = false
|
||||
if _third_person_camera:
|
||||
_third_person_camera.current = true
|
||||
print("Third person: ON")
|
||||
else:
|
||||
# Switch to first person
|
||||
if _third_person_camera:
|
||||
_third_person_camera.current = false
|
||||
if _fps_camera:
|
||||
_fps_camera.current = true
|
||||
print("Third person: OFF")
|
||||
|
||||
func _find_camera_in_player() -> Camera3D:
|
||||
if not _player:
|
||||
return null
|
||||
# Search for Camera3D in player's children
|
||||
for child in _player.get_children():
|
||||
if child is Camera3D:
|
||||
return child
|
||||
for grandchild in child.get_children():
|
||||
if grandchild is Camera3D:
|
||||
return grandchild
|
||||
return null
|
||||
|
||||
func _setup_third_person_camera() -> void:
|
||||
if not _player:
|
||||
return
|
||||
_third_person_camera = Camera3D.new()
|
||||
_third_person_camera.name = "ThirdPersonCamera"
|
||||
_third_person_camera.fov = 75.0
|
||||
_third_person_camera.near = 0.1
|
||||
_third_person_camera.far = 200.0
|
||||
# Position behind and above the player
|
||||
_third_person_camera.position = Vector3(0, 2.0, -4.0)
|
||||
_third_person_camera.look_at(Vector3(0, 1.0, 0))
|
||||
_player.add_child(_third_person_camera)
|
||||
_third_person_camera.current = false
|
||||
|
||||
|
||||
func _build_materials() -> void:
|
||||
pass
|
||||
@@ -690,6 +747,12 @@ func _process(_delta: float) -> void:
|
||||
if not _player or not is_instance_valid(_player):
|
||||
return
|
||||
|
||||
# Third person camera follow
|
||||
if _third_person and _third_person_camera and _third_person_camera.current:
|
||||
var target_pos = _player.global_position + Vector3(0, 2.0, -4.0)
|
||||
_third_person_camera.global_position = _third_person_camera.global_position.lerp(target_pos, 0.1)
|
||||
_third_person_camera.look_at(_player.global_position + Vector3(0, 1.0, 0))
|
||||
|
||||
if _debug_ui_panel:
|
||||
_debug_ui_panel.visible = SettingsManager.show_debug_ui
|
||||
|
||||
|
||||
Reference in New Issue
Block a user