动画系统

动画系统

Godot 提供强大的动画系统,支持关键帧动画、骨骼动画等多种形式。

AnimationPlayer

AnimationPlayer 是最常用的动画节点。

基础用法

extends Node2D

@onready var animation_player = $AnimationPlayer

func _ready() -> void:
    # 播放动画
    animation_player.play("idle")

    # 播放特定部分的动画
    animation_player.play("run", 0.5)  # 从 0.5 秒开始

    # 暂停/继续
    animation_player.pause()
    animation_player.play()

    # 停止并重置
    animation_player.stop()

事件连接

extends Node2D

@onready var animation_player = $AnimationPlayer

func _ready() -> void:
    # 动画完成时调用
    animation_player.animation_finished.connect(_on_animation_finished)

    # 动画开始时调用
    animation_player.animation_started.connect(_on_animation_started)

func _on_animation_finished(anim_name: StringName) -> void:
    print("Animation finished: ", anim_name)

func _on_animation_started(anim_name: StringName) -> void:
    print("Animation started: ", anim_name)

动画混合

# 在编辑器中创建动画轨道
# 属性 -> Node 路径 -> 属性

# 位置轨道
"Node2D:position:x"
"Node2D:position:y"

# 旋转轨道
"Node2D:rotation_degrees"

# 缩放轨道
"Node2D:scale:x"
"Node2D:scale:y"

# 可见性
"Node2D:visible"

# Sprite 帧
"Sprite2D:frame"

AnimatedSprite2D

用于简单的精灵帧动画。

extends AnimatedSprite2D

func _ready() -> void:
    # 设置精灵表
    sprite_frames = preload("res://animations/player_frames.tres")

    # 播放动画
    play("idle")

    # 设置播放速度
    speed_scale = 1.5

    # 暂停动画
    pause()

    # 停止动画
    stop()

func _on_AnimatedSprite2D_animation_finished() -> void:
    print("Animation finished!")

AnimationTree

用于更复杂的动画状态机。

基础设置

extends CharacterBody2D

@onready var animation_tree = $AnimationTree
@onready var state_machine = animation_tree["parameters/playback"]

func _ready() -> void:
    animation_tree.active = true

func _physics_process(delta: float) -> void:
    var direction = Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down")

    # 设置状态机参数
    animation_tree["parameters/Idle/blend_position"] = direction
    animation_tree["parameters/Walk/blend_position"] = direction

    # 状态切换
    if direction != Vector2.ZERO:
        state_machine.travel("Walk")
    else:
        state_machine.travel("Idle")

AnimationBlendTree

# AnimationTree 设置
# Tree Root -> AnimationNodeBlendTree

# 混合空间(方向)
# AnimationNodeBlendSpace2D
# - Idle (中心点)
# - Walk (8个方向)
# - Run (边缘)

# 混合节点
# parameters/blend_amount (0.0 - 1.0)
# 混合两个动画

Tween

用于程序化动画。

extends Node2D

var tween: Tween

func animate_position() -> void:
    tween = create_tween()
    tween.tween_property(self, "position", Vector2(100, 100), 1.0)

func animate_color() -> void:
    tween = create_tween()
    tween.tween_property(self, "modulate", Color.RED, 0.5)

func animate_with_easing() -> void:
    tween = create_tween()
    tween.set_ease(Tween.EASE_IN_OUT)
    tween.set_trans(Tween.TRANS_QUART)
    tween.tween_property(self, "scale", Vector2(2, 2), 1.0)

func chained_animations() -> void:
    tween = create_tween()
    # 链式调用
    tween.tween_property(self, "position", Vector2(100, 0), 0.5)
    tween.tween_property(self, "position", Vector2(100, 100), 0.5)
    tween.tween_property(self, "position", Vector2(0, 100), 0.5)

func parallel_animations() -> void:
    tween = create_tween()
    # 并行动画
    var move_tween = tween.tween_property(self, "position", Vector2(100, 100), 1.0)
    var scale_tween = tween.parallel().tween_property(self, "scale", Vector2(2, 2), 1.0)
    var rotate_tween = tween.parallel().tween_property(self, "rotation", PI, 1.0)

动画回调和事件

在编辑器中添加动画事件

1. 打开 AnimationPlayer
2. 选择动画
3. 点击 "添加轨道" -> "函数调用轨道"
4. 添加关键帧
5. 设置调用的函数名
extends Node2D

func _on_step_left() -> void:
    print("Left foot step!")

func _on_step_right() -> void:
    print("Right foot step!")

func _on_attack_hit() -> void:
    # 攻击判定
    perform_attack()

骨骼动画 (Skeleton2D)

extends Skeleton2D

func _ready() -> void:
    # 获取骨骼
    var bone_index = find_bone("RightArm")

    # 设置骨骼旋转
    set_bone_rotation(bone_index, PI / 4)

    # IK 反向动力学
    var ik_constraint = get_node("IKConstraint_Limb")
    ik_constraint.target = get_node("IKTarget")

3D 动画

extends MeshInstance3D

@onready var animation_player = $AnimationPlayer

func _ready() -> void:
    # 播放 3D 模型动画
    animation_player.play("walk")

动画资源

SpriteFrames

# 创建 SpriteFrames 资源
var frames = SpriteFrames.new()

# 添加动画帧
frames.add_frame("idle", preload("res://sprites/idle_1.png"))
frames.add_frame("idle", preload("res://sprites/idle_2.png"))

# 设置动画速度
frames.set_animation_speed("idle", 8.0)
frames.set_animation_loop("idle", true)

常用动画类型

平移动画

func slide_right() -> void:
    var tween = create_tween()
    tween.tween_property(self, "position:x", position.x + 200, 0.5)

缩放动画

func pulse() -> void:
    var tween = create_tween()
    tween.set_loops()
    tween.tween_property(self, "scale", Vector2(1.2, 1.2), 0.3)
    tween.tween_property(self, "scale", Vector2.ONE, 0.3)

旋转动画

func spin() -> void:
    var tween = create_tween()
    tween.tween_property(self, "rotation_degrees", rotation_degrees + 360, 1.0)

颜色动画

func flash_color() -> void:
    var tween = create_tween()
    var original_color = modulate
    tween.tween_property(self, "modulate", Color.WHITE, 0.1)
    tween.tween_property(self, "modulate", original_color, 0.1)

动画优化

  1. 减少动画轨道数量:只动画化必要属性
  2. 使用压缩:启用动画压缩选项
  3. 优化帧率:适当降低动画采样率
  4. 重用动画:使用 AnimationTree 共享动画资源