角色和动画
This commit is contained in:
@@ -1,36 +1,19 @@
|
||||
extends Node
|
||||
class_name PlayerAnimator
|
||||
## 角色动作状态机 —— 只负责「把运动状态翻译成播放哪段动画」,完全不碰移动。
|
||||
##
|
||||
## 挂在 Player/Body 下,与具体模型解耦:换角色模型只要在检视面板重新指定
|
||||
## animation_player(或让它自动找),代码里没有任何硬编码的节点路径。
|
||||
##
|
||||
## 对外接口只有一个:set_motion()。方向、加速度、重力、输入全归控制器管;
|
||||
## 本组件只读入一个「运动快照」,输出到 AnimationPlayer。反向不回写任何东西。
|
||||
##
|
||||
## 为什么状态与倍率必须是可复制属性:
|
||||
## 远端玩家物理与输入都关着,手里只有 position 和 Body.rotation,
|
||||
## 算不出水平速度,也分不清是上升还是下落。所以权威端把结论复制过去,
|
||||
## 远端只在 setter 里回放。
|
||||
## 对应的同步条目(Sync.root_path = "..",即 Player 节点):
|
||||
## Body/PlayerAnimator:anim_state
|
||||
## Body/PlayerAnimator:anim_speed
|
||||
|
||||
## 角色动作状态。权威端每物理帧算一次,再靠 Sync 复制给远端回放。
|
||||
enum AnimState { IDLE, WALK, SPRINT, JUMP, FALL }
|
||||
enum AnimState { IDLE, WALK, CROUCH, RUN, FALL, SNEAK, JUMP }
|
||||
|
||||
## 状态 → 片段名。取自 character-male-e.glb 的动作库,换动作库改这里。
|
||||
const ANIM_CLIPS: Dictionary = {
|
||||
AnimState.IDLE: "idle",
|
||||
AnimState.WALK: "walk",
|
||||
AnimState.SPRINT: "sprint",
|
||||
AnimState.CROUCH: "crouch",
|
||||
AnimState.RUN: "run",
|
||||
AnimState.SNEAK: "SNEAK",
|
||||
AnimState.JUMP: "jump",
|
||||
AnimState.FALL: "fall",
|
||||
}
|
||||
|
||||
## 需要循环的状态。glb 里每个片段的 loop_mode 都是 NONE,
|
||||
## 不补循环的话 idle/walk/sprint 播一遍就定在最后一帧。
|
||||
const ANIM_LOOPED: Array[int] = [AnimState.IDLE, AnimState.WALK, AnimState.SPRINT]
|
||||
## 需要循环的状态。
|
||||
const ANIM_LOOPED: Array[int] = [AnimState.IDLE, AnimState.WALK, AnimState.RUN]
|
||||
|
||||
@export_group("接线")
|
||||
## 要驱动的 AnimationPlayer。留空则在本节点的兄弟子树里自动找一个。
|
||||
@@ -73,8 +56,6 @@ var anim_speed: float = 1.0:
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
if animation_player == null:
|
||||
animation_player = _auto_find_animation_player()
|
||||
if animation_player == null:
|
||||
push_warning("%s 没绑定 AnimationPlayer,角色不会有动画" % get_path())
|
||||
return
|
||||
@@ -138,13 +119,6 @@ func _play(clip: String, blend: float) -> void:
|
||||
animation_player.play(clip, blend)
|
||||
|
||||
|
||||
## 兜底:在同一层视觉节点里找一个 AnimationPlayer。只在没接线时生效。
|
||||
func _auto_find_animation_player() -> AnimationPlayer:
|
||||
var parent := get_parent()
|
||||
if parent == null:
|
||||
return null
|
||||
return parent.find_child("AnimationPlayer", true, false) as AnimationPlayer
|
||||
|
||||
|
||||
func _patch_loop_modes() -> void:
|
||||
for state in ANIM_LOOPED:
|
||||
|
||||
Reference in New Issue
Block a user