ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Godot 动画状态机播放控制器 AnimationNodeStateMachinePlayback 完全指南

Godot 动画状态机播放控制器 AnimationNodeStateMachinePlayback 完全指南 文档教程游戏开发【免费下载链接】godot-docsGodot Engine official documentation项目地址https://gitcode.com/GitHub_Trending/go/godot-docs点击查看免费下载AnimationNodeStateMachinePlayback是 Godot 引擎中用于程序化控制 AnimationTree 状态机AnimationNodeStateMachine播放的核心运行时对象你不需要在编辑器里手动连线触发转场而是通过一行$AnimationTree.get(parameters/playback)拿到它再用travel()、start()、stop()等方法让角色在 Idle / Run / Jump 等动画状态之间按最短路径平滑切换。读完本文你将掌握该对象的全部方法与信号能独立写出基于状态机的角色动画控制系统并理解travel()背后 A* 路径规划与交叉淡入crossfade的工作机制。本文内容以 classes/class_animationnodestatemachineplayback.rst 类参考文档为主体并补充了 Using AnimationTree 教程、AnimationNodeStateMachine 与 AnimationNodeStateMachineTransition 类文档中的关联细节。一、这个类是什么状态机的遥控器在 Godot 的动画体系中AnimationNodeStateMachine状态机是放在AnimationTree根节点下的一种动画根节点它把多个AnimationRootNode组织成一张图节点即状态连线即转场状态之间可以按最短路径自动或手动切换。而AnimationNodeStateMachinePlayback就是附着在这张状态机图上的运行时播放控制句柄。它不是编辑器里的可视化节点而是一个继承自Resource→RefCounted→Object的运行时对象专门负责让某个状态开始/停止播放start()/stop()从当前状态沿最短路径旅行到目标状态travel()立刻跳到 travel 或自动前进auto advance给出的下一个状态next()查询当前状态、当前播放位置、当前动画长度、是否正在播放等运行时信息报告正在进行的交叉淡入crossfade的源节点、长度与位置通过state_started/state_finished信号通知状态切换的时刻。从继承链Resource RefCounted Object可以看出它本身是一个资源对象且其resource_local_to_scene属性被覆盖为true——这意味着它在场景中是局部资源场景的每个实例各自拥有独立的播放状态不会互相干扰。二、获取 Playback 对象状态机的 Playback 对象不会凭空出现它是AnimationTree节点对外暴露的一个导出参数。文档给出的标准获取方式是var state_machine $AnimationTree.get(parameters/playback) state_machine.travel(some_state)C# 对应写法var stateMachine GetNodeAnimationTree(AnimationTree).Get(parameters/playback).AsAnimationNodeStateMachinePlayback(); stateMachine.Travel(some_state);使用下标语法同样可以读取Using AnimationTree 教程 中 StateMachine travel 一节的写法var state_machine animation_tree[parameters/playback] state_machine.travel(SomeState)AnimationNodeStateMachinePlayback stateMachine (AnimationNodeStateMachinePlayback)animationTree.Get(parameters/playback); stateMachine.Travel(SomeState);关键前提来自教程原文状态机必须先运行起来才能 travel——要么调用start()要么把某个状态节点连接到Start端口详见 Using AnimationTree 教程 的 StateMachine travel 小节。三、播放控制核心 API这组方法是整个 Playback 对象的使用主体对应文档 Methods 表中的 4 个 void 方法。start(node, reset true)state_machine.start(Idle) # 从头开始播放 Idle state_machine.start(Run, false) # 从当前时间继续播放 Run不重置作用开始播放指定动画状态参数reset为true时动画从头播放为false时从当前位置继续注意node的类型是StringName在 GDScript 中直接传字符串字面量即可。stop()state_machine.stop()停止当前正在播放的动画。没有任何参数。travel(to_node, reset_on_teleport true)state_machine.travel(Run) # 沿最短路径切到 Run state_machine.travel(Run, false) # 若发生传送不重置目标动画作用从当前状态沿最短路径转场到另一个状态路径规划算法见下一节如果当前状态到目标状态之间没有连通路径状态机会传送teleport到目标状态此时动画直接切换reset_on_teleport为true时发生传送时目标动画从头播放为false时保留传送时的播放进度。这里与 AnimationNodeStateMachineTransition 的priority优先级属性联动优先级更低数值更小的转场在 travel 遍历状态图时会被优先选择。next()state_machine.next()如果存在由 travel 或自动前进advance计算出的下一条路径立即从当前状态切换到下一个状态。适合用在想跳过转场等待、立刻切状态的场景。四、travel() 的底层机制A* 最短路径与传送理解travel()之前需要先了解它在状态机图上做了什么。根据 AnimationNodeStateMachine 类文档与 Using AnimationTree 教程 的 StateMachine travel 一节You can instruct the graph to go from the current state to another one, while visiting all the intermediate ones. This is done via the A* algorithm. If there is no path of transitions starting at the current state and finishing at the destination state, the graph teleports to the destination state.也就是说有路径Godot 用A* 算法在状态图中计算从当前状态到目标状态的最短路径并依次途经所有中间状态每个中间转场按照各自配置的 xfade 时间、switch mode 执行无路径图直接传送到目标状态teleport此时travel()的reset_on_teleport参数决定目标动画是否从头播放。路径规划只会使用由AnimationNodeStateMachineTransition连接的节点见 AnimationNodeStateMachineTransition 描述所以要想 travel 能走通必须先给状态之间建立转场连线。与此相关AnimationNodeStateMachine上有一个allow_transition_to_self属性默认false若为true允许 travel 传送回自身状态且当travel()的 reset 选项开启时动画会被重启若为false传送到自身状态时什么都不发生。这在做按一下重新播放当前动画这类需求时很实用。路径可视化get_travel_path()var path: Array[StringName] state_machine.get_travel_path() for state_name in path: print(途经状态: , state_name)get_travel_path()返回当前由 A* 算法内部计算出的旅行路径类型为Array[StringName]。可以用来调试状态切换顺序、或结合 UI 显示角色下一步的动作。五、状态查询 API运行时信息这一组都是const方法无副作用不修改任何成员变量用于随时读取状态机的运行状态。方法返回类型含义is_playing()bool是否正在播放动画get_current_node()StringName当前正在播放的动画状态名get_current_play_position()float当前状态内的播放位置秒get_current_length()float当前状态的长度秒get_current_node() 的 crossfade 语义文档特别强调了一个容易踩坑的细节When using a cross-fade, the current state changes to the next state immediately after the cross-fade begins.一旦交叉淡入开始get_current_node()会立刻返回下一个状态而不是等淡入结束。所以在做读取当前状态的逻辑时如果正处于过渡期返回值已经是目标状态。同理AnimationNodeStateMachineTransition 的xfade_time说明中也注明状态机在淡入开始后立即切换当前状态。get_current_length() 的复合语义get_current_length()返回当前状态的长度但文档给了三条重要说明任意AnimationRootNode都可以作为状态而不仅是单个动画因此一个状态内可能包含多个动画此时返回的长度取决于状态内部节点的连接方式即哪个动画的时长说了算如果某个转场设置了不重置reset false返回的是当时剩余的长度因此它并不总是从头到尾的完整时长与get_current_play_position()配合使用时要注意这一点。六、交叉淡入Crossfade查询 API当travel()或自动前进触发了带xfade_time的转场时状态机内部会有一段旧状态渐出、新状态渐入的重叠播放区间。这组方法专门用来查询这段淡入过程方法返回类型含义get_fading_from_node()StringName正在淡出的起始状态名get_fading_from_length()float淡出源状态的长度无淡入时返回0get_fading_from_play_position()float淡出源状态当前的播放位置无淡入时返回0get_fading_length()float当前淡入动画的总时长无淡入时返回0get_fading_position()float当前淡入动画的播放位置无淡入时返回0典型用途if state_machine.get_fading_length() 0.0: var fade_from: StringName state_machine.get_fading_from_node() var fade_progress: float state_machine.get_fading_position() / state_machine.get_fading_length() # fade_progress 从 0 增长到 1可用于驱动镜头、特效等这套from length position组合可以帮助你在淡入尚未结束时就感知到过渡的源状态与进度比如实现旧动作的收尾动作盖过新动作之类的混合效果。七、信号捕捉状态切换的时刻Playback 对象对外暴露两个信号是驱动游戏逻辑如触发脚步声、粒子特效、攻击判定的常用入口state_started(state)state_machine.state_started.connect(func(state): print(状态开始播放: , state) )当state开始播放时发出。若state是一个设置为**分组模式grouped**的状态机其内部信号会以名称前缀的方式透传出来。state_finished(state)state_machine.state_finished.connect(func(state): print(状态播放结束: , state) )当state播放结束时发出。文档特别说明了它与 crossfade 的关系If there is a crossfade, this will be fired when the influence of the get_fading_from_node() animation is no longer present.即存在交叉淡入时state_finished会等到淡出源动画的影响力完全消失后才触发——也就是说旧状态的结束信号以淡出完成为准而不是以动画自然播完为准。这与get_current_node()淡入开始即切换的语义正好互补切换是即时的结束是等淡出的。八、与状态机类型和转场配置的联动Playback 对象本身不做转场决策它执行的是 AnimationNodeStateMachine 与 AnimationNodeStateMachineTransition 配置好的规则。理解下面几点才能把travel()/next()用得恰到好处状态机类型StateMachineType影响 start/stop 语义AnimationNodeStateMachine的state_machine_type属性默认ROOT定义了转场处理的模式STATE_MACHINE_TYPE_ROOT0回到开头视为从起始状态开始播放转到结束状态视为退出状态机STATE_MACHINE_TYPE_NESTED1回到开头视为回到当前状态内动画的开头转到结束状态或某状态没有转出连线视为退出状态机STATE_MACHINE_TYPE_GROUPED2分组模式由父级状态机控制不能独立运行父/祖先中必须存在 ROOT 或 NESTED 类型的状态机。当state是 grouped 状态机时Playback 的state_started/state_finished信号会带上前缀透传这一点在信号一节已提到。转场属性决定 travel 的表现在 AnimationNodeStateMachineTransition 中影响 Playback 行为的关键属性包括xfade_time / xfade_curve淡入时间与淡入曲线决定get_fading_*系列方法观测到的淡入过程switch_modeIMMEDIATE立即切换、SYNC立即切换并对齐播放位置、AT_END等当前状态播完再切advance_modeDISABLED不使用、ENABLED仅在 travel 时使用、AUTO自动前进条件与表达式为真时使用——next()判断是否有下一条路径时依据的正是 travel 路径与 AUTO 模式的自动前进priority数值越低在 travel 与 AUTO 前进中越优先reset切换时目标动画是否从头播放与travel()的reset_on_teleport参数配合。下面的图片展示了状态机编辑器的空初始界面默认含Start与End两个内置状态以及单个转场的属性面板——后者正是上面这些属性在编辑器中的落点完整的状态机搭建流程创建状态、连接转场、配置三种转场类型与 advance 条件/表达式、travel()的使用前提请参阅 Using AnimationTree 教程 的 StateMachine 与 StateMachine travel 两节。九、综合实战示例程序化控制角色状态机结合上述 API一个典型的角色按下按键切换到对应动画的控制器可以这样写extends CharacterBody3D onready var animation_tree: AnimationTree $AnimationTree # 缓存 playback 对象避免每帧重复 get var state_machine: AnimationNodeStateMachinePlayback func _ready() - void: state_machine animation_tree[parameters/playback] state_machine.state_started.connect(_on_state_started) state_machine.state_finished.connect(_on_state_finished) # 状态机必须先启动才能 travel state_machine.start(Idle) func _physics_process(_delta: float) - void: # 通过 advance condition 参数驱动自动转场编辑器里转场配置为 AUTO 条件变量 animation_tree[parameters/conditions/is_walking] velocity.length() 0.1 animation_tree[parameters/conditions/is_jumping] not is_on_floor() # 也可以随时强制 travel走最短路径 if Input.is_action_just_pressed(dash): state_machine.travel(Dash) func _on_state_started(state: StringName) - void: print(开始播放: , state) # 例如在 Run 开始时播放脚步循环音效 func _on_state_finished(state: StringName) - void: print(播放结束: , state) # 例如在 Attack 结束时清除攻击判定要点回顾travel()传目标状态名即可中间状态由 A* 自动规划无路径时会传送reset_on_teleport控制传送后是否重置动画next()用于立刻执行已规划好的下一步交叉淡入期间用get_fading_from_node()等方法观测过渡源信号注意 grouped 状态机的前缀透传与 crossfade 延迟触发语义。十、速查表方法、信号与继承继承链Object→RefCounted→Resourceresource_local_to_scene覆盖为true方法一览方法签名说明start(node: StringName, reset: bool true)开始播放指定状态stop()停止当前播放travel(to_node: StringName, reset_on_teleport: bool true)沿最短路径转场无路径则传送next()立即切换到 travel/自动前进给出的下一状态is_playing() - bool是否正在播放get_current_node() - StringName当前状态名淡入开始后即返回新状态get_current_play_position() - float当前状态播放位置get_current_length() - float当前状态长度可能返回剩余长度get_travel_path() - Array[StringName]A* 计算出的旅行路径get_fading_from_node() - StringName淡出源状态名get_fading_from_length() - float淡出源状态长度get_fading_from_play_position() - float淡出源状态播放位置get_fading_length() - float当前淡入总时长get_fading_position() - float当前淡入播放位置信号一览信号参数说明state_started(state: StringName)状态开始播放grouped 状态机信号带前缀透传state_finished(state: StringName)状态播放结束有 crossfade 时在淡出源影响力消失后触发延伸阅读Using AnimationTree 教程状态机的搭建、转场类型、Advance Condition / Expression、travel 的完整讲解AnimationNodeStateMachine 类参考状态机本身的属性state_machine_type、allow_transition_to_self、reset_ends与图操作方法AnimationNodeStateMachineTransition 类参考转场的 xfade、switch mode、advance mode、priority 等参数细节AnimationTree 类参考tree_root、anim_player、advance_expression_base_node等与 Playback 联动的基础配置。赞分享文档教程游戏开发【免费下载链接】godot-docsGodot Engine official documentation项目地址https://gitcode.com/GitHub_Trending/go/godot-docs点击查看免费下载相关推荐mesh2motion动画状态管理播放控制与状态同步机制mesh2motion动画状态管理播放控制与状态同步机制 引言3D动画状态管理的核心挑战 在3D角色动画系统中动画状态管理Animation State前端3D渲染图形学laravel-paystack订阅支付实战创建Plan、绑定客户并启用周期性扣费的完整教程laravel paystack订阅支付实战创建Plan、绑定客户并启用周期性扣费的完整教程 laravel paystack 是一款专为 Laravel 6如何快速上手Featureform从零开始的5步完整指南如何快速上手Featureform从零开始的5步完整指南 Featureform是一款虚拟特征存储工具能够将您现有的数据基础设施转变为功能完善的特征存储。本上一篇CVAT完整指南如何挑选免费的开源图像视频标注工具下一篇如何彻底解决Dell G15散热问题tcc-g15开源控制中心完整指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表