如何解决Godot 引擎将 AnimationPlayer 键值设置为当前值
如何将动画的键值设置为动画中引用的对象的当前值,类似于将 null 传递给 initial_val 和/ 或 Tween 节点的 final_val 参数?
“将初始值设置为 null 使用属性的当前值。”补间节点文档
我的回答是我目前尝试过的方法,但我担心它太复杂了。
解决方法
使用此方法,我可以使用参数 _node_names 中指定的节点的当前值将现有动画的关键值设置为指定的轨道位置 _animation_position 和可选,该节点的特定属性传入_property_names,否则,动画中存在的所有与该节点相关的属性都将被更改。
func Animation_Set_Current_Values(_animation_player: AnimationPlayer,_animation_name: String = "",_animation_position: int = 0,_node_names: Array = [],_property_names: Array = [],_disable_unwanted: bool = true,_play_animation: bool = true) -> void:
if not _node_names.empty():
if not _animation_player.get_animation_list().empty():
# Use the first animation in the animation player if no animation name is specified for convenience
var _detected_animation_name: String = _animation_name if (
not _animation_name.empty() and _animation_player.has_animation(_animation_name)) else _animation_player.get_animation_list()[0]
var _animation: Animation = _animation_player.get_animation(_detected_animation_name)
# Store detected track / node information: Node_Name: [{_property: _track_count},...]
var _track_data: Dictionary = {}
if _animation.get_track_count() != 0:
for _track in _animation.get_track_count():
var _track_path: NodePath = _animation.track_get_path(_track)
var _node_path: String = (_track_path as String).split(":")[0]
var _node_property: String = (_track_path as String).split(":")[1]
var _node: Object = _animation_player.get_parent().get_node(_node_path)
if _node != null:
if not _track_data.has(_node): _track_data[_node] = []
_track_data[_node].append({_node_property: _track})
if _disable_unwanted: _animation.track_set_enabled(_track,false)
# Set track keys values to the current initial values
if not _track_data.empty():
for _track_data_node in _track_data.keys():
if _node_names.has(_track_data_node.name):
for _track_data_property in _track_data[_track_data_node]:
var _track_data_property_name: String = _track_data_property.keys().front()
var _track_data_property_track_idx: int = _track_data_property.values().front()
var _node_property = _track_data_node.get(_track_data_property_name)
if _node_property != null:
if _property_names.has(_track_data_property_name) or _property_names.empty():
if _animation_position <= _animation.track_get_key_count(_track_data_property_track_idx) - 1:
_animation.track_set_key_value(_track_data_property_track_idx,_animation_position,_node_property)
_animation.track_set_enabled(_track_data_property_track_idx,true)
# Optionally,play the animation if specified
if _play_animation: _animation_player.play(_detected_animation_name)
,
在以下场景中正确转换两个动画:考虑一个角色挥舞剑,有两个动画:“swing”和“parry”,如果我在“swing”动画仍在进行的时候播放“parry”动画
您有两个动画并且想要在它们之间进行混合。 这不是您要问的 (XY problem)。
使用 AnimationPlayer
,您可以指定任意两个动画之间的过渡时间。 包括一个动画和它本身,当你告诉 Godot 在播放同一动画时播放动画时会发生这种情况。
在动画面板(在编辑器的底部)中,选择第一个动画(在您的示例中为“swing”),单击“Animation”按钮并选择“Edit Transitions”。它将打开所选动画的“交叉动画混合时间”对话框。
对话框将显示所有带有数字的动画,默认为 0。这是 Godot 将动画混合的时间,以秒为单位。
0(默认)表示瞬时。也就是说,如果您播放另一个动画(在您的示例中为“招架”),它将捕捉到该动画的起始值……这不是您想要的。而是增加时间。
请注意,Godot 不会插值到新动画的起始值,它会插值到新动画播放的当前值。
重申一下这个场景,在播放第一个动画(比如“摇摆”)时,你播放第二个动画(比如“招架”)。
第二个动画播放,但设置的值不会是动画中的值。相反,它们将是当前值和动画中的值之间的一些插值。插值将使得在开始时当前值保持不变,并且在您在“交叉动画混合时间”对话框中配置的任何时间之后,该值就是动画中的值。
是的,这是一个线性插值。 至少据我所知,请记住,我们很少希望过渡时间过长。
如果用当前值替换动画的初始值,则动画将在第二个关键帧处满足动画的值。
您可以改为使过渡时间与第二个关键帧匹配。 不完全相同,因为您可以在不同时间拥有不对齐的关键帧轨道,并且您可以控制每个轨道的插值方式。然而,我在这里介绍的方法工作量要少得多(根本没有代码)。
如果您不想要线性插值,或者您想要在两个以上的动画之间进行插值,请使用 AnimationTree。另见Controlling animation states。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。