extends Node3D class_name LilguyBody const LERP_VELOCITY: float = 0.15 @export_category("Objects") @export var _character: CharacterBody3D = null @export var animation_player: AnimationPlayer = null func apply_rotation(_velocity: Vector3) -> void: var new_rotation_y = lerp_angle(rotation.y, atan2(_velocity.x, _velocity.z), LERP_VELOCITY) rotation.y = new_rotation_y func animate(_velocity: Vector3) -> void: if not animation_player: return # Don't override attack animation if it's playing if animation_player.is_playing() and animation_player.current_animation.begins_with("Attack"): return # Check if we're dashing if _character._is_dashing: if animation_player.current_animation != "Jump": _play_animation("Jump") return if not _character.is_on_floor(): if _velocity.y < 0: # Falling - use FallIdle animation _play_animation("FallIdle") else: _play_animation("Jump") return if _velocity: if _character.is_running() and _character.is_on_floor(): # Sprint animation = Run for Lilguy _play_animation("Run") return # Walk animation for normal movement _play_animation("Walk") return # Idle - use FallIdle or Idle if it exists if animation_player.has_animation("Idle"): _play_animation("Idle") else: _play_animation("FallIdle") func _play_animation(anim_name: String): if animation_player and animation_player.has_animation(anim_name): animation_player.play(anim_name) # Silently ignore if animation doesn't exist func play_attack(anim_name: String = "Attack_OneHand") -> void: if animation_player: # Play attack animation once (don't loop) if animation_player.has_animation(anim_name): animation_player.play(anim_name, -1, 1.0) animation_player.animation_set_next(anim_name, "") else: # Fallback to default if animation doesn't exist push_warning("Animation '%s' not found, using Attack_OneHand" % anim_name) animation_player.play("Attack_OneHand", -1, 1.0) animation_player.animation_set_next("Attack_OneHand", "")