Unity中通常的做法是基础模型是FBX文件,每个动画也是个单独的FBX文件。Unity导入FBX后还可以继续修改,比如修改动画名。Godot是不建议在引擎内部修改的,它认为这样会破坏继续在DCC软件中模型文件的再次编辑,尽量所有东西都可以在3DMAX或者Blender中编辑,导出后直接在Godot中使用。Godot可以把FBX里的动画另存出来保存.res文件,这样就可以在引擎内修改名字。
Godot的作者真的是很牛,他的理念我也是非常认可的,他不喜欢用第三方闭源库(不知道它内部干了啥),除非对方是开源的。所以一开始Godot是不建议使用FBX的,因为需要引入一个黑盒的执行文件才能解析FBX的结构,Godot建议大家使用glTF而不是FBX,它是公开的格式有很多开源的代码,Godot开箱即用。
FBX的使用需求很旺盛,Unity这边来的开发者都希望使用FBX而非glTF,Godot开始是引入了一个插件FBX2glTF,导入FBX模型后将它转换成glTF,尽量不影响开发者,直到Godot4.3引入一个开源的Ufbx 插件,至此开发者可以直接完全使用FBX在Godot中。
如图所示,导入FBX文件后,选择所有动画文件(不包括模型文件)在Import中修改Animation Libray后点击Reimport。
然后把模型拖入Hierarchy中,并且创建AnimationPlayer对象,下方打开Animation窗口点击Manage Animations开始导入动画。
接着导入上面Reimport所有的fbx动画。
创建脚本,并且绑定到A_Npc_010_skin的父节点Node3D上。这段代码也比较好理解,就是在Hierarchy中找到AnimationPlayer对象,设置循环,播放动画,监听事件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
using Godot; public partial class NewScript : Node { public override void _Ready() { var name = "A_Npc_010"; //通过路径获取AnimationPlayer对象 var animationPlayer = GetNode<AnimationPlayer>($"{name}_skin/AnimationPlayer"); //设置为循环播放 var anim = animationPlayer.GetAnimation($"{name}@run01/Take 001"); anim.LoopMode = Animation.LoopModeEnum.Linear; //播放动画名 animationPlayer.Play($"{name}@run01/Take 001"); //监听动画播放开始完成事件 animationPlayer.AnimationStarted += (anim_name) => { Godot.GD.Print($"{anim_name} start {Time.GetTicksMsec() / 1000f}"); }; animationPlayer.AnimationFinished += (anim_name) => { Godot.GD.Print($"{anim_name} finish {Time.GetTicksMsec() / 1000f}"); }; } } |
如果希望动画混合,第二个参数就是混合时间,表示播放新动画和老动画在同时播放。
animationPlayer.Play($”{name}@run01/Take 001″,1f);
如果希望动画从中间某个时间点开始播放,可以使用Seek
animationPlayer.Play($”{name}@eat01/Take 001″);
animationPlayer.Seek(2f,true);
常见的功能还有,动画队列,播放速度,时间,等等都可以设置。
目前通过代码我们可以非常灵活的控制动画的播放了,Godot也支持像Unity那种动画状态机AnimationControll连线的方法设置条件AnimationTree,动画混合状态,Mask部分骨骼不被动画控制等。
通常情况下尽量还是通过纯代码控制动画才会更加灵活,这也是Unity那边很多开发者宁愿使用Playable也不愿意用AnimationControl的原因。
- 本文固定链接: https://www.xuanyusong.com/archives/5136
- 转载请注明: 雨松MOMO 于 雨松MOMO程序研究院 发表