Unity-动画状态机使用细节记录
Unity动画控制器Animator功能非常强大,总结一些具体使用细节,在动作游戏中很实用;
1.动画烘焙
不同动画之间,可能存在角色朝向,重心高度不一致;
可以在动画Eidt界面设置RootTransform Rotation重新烘焙旋转;
RootTransformPosition(Y)烘焙高度,地面动作选择feet,烘焙在脚上;
设置完烘焙必须点Apply才能生效;
2.动作镜像
有些单手动作,左右手都可以做,动画机添加bool参数,动作Inspector界面Mirror勾选Parameter;
将bool参数设置进去,代码动态调节bool参数切换左右手;
3.StateMachineBehaviour
Unity动画机没有直接的api判断动画播放结束,StateMachineBehaviour可以做到;
动画状态机生命周期:
OnStateEnter
OnStateUpdate
OnStateExit
创建FSMOnExit脚本继承StateMachineBehaviour,重写OnStateExit方法,监听到有退出消息向上传递方法名,在角色控制脚本中实现该方法;
该脚本挂载在动画机中需要监听的state上;
TIps:SendMessageUpwards效率很低,建议改成事件机制;
public class FSMOnExit : StateMachineBehaviour { public string[] onExitMessages; override public void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) { for (int i = 0; i < onExitMessages.Length; ++i) { animator.gameObject.SendMessageUpwards(onExitMessages[i]); } } }
4.trigger累积清空
Unity动画机的trigger有个出名的”bug“,trigger会累积1次;
造成的效果就是,起跳后空中按跳,落地会再次起跳;
同样攻击也会如此;
解决办法与上述方法相同,在OnStateExit、OnStateEnter按需求重置trigger;
也可以选中在关键帧动画事件中重置Trigger,可以实现连击时机判定(前置动作过半再次按下攻击才可连击);
public class FSMClearSignals : StateMachineBehaviour { public string[] clearAtEnter; public string[] clearAtExit; override public void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) { foreach (string key in clearAtEnter) { animator.ResetTrigger(key); } } override public void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) { foreach (string key in clearAtExit) { animator.ResetTrigger(key); } } }
5.连击动作混合
连击动作之间不需要收招,如果是同一个Layer的动作,使用官方混合,拖动时间线同时可以预览效果;
ExitTime:该状态有多个后续连线状态,中间没有其他条件的情况下,ExitTime决定先进入的状态;
InterruptionSoure:在混合状态时(重叠部分),该状态被打断返回的状态,默认返回Next;
可设置Current State,Next State;
6.动画Layer设置
Layer可用隔开常规行为动作、攻击、面部表情、以及不同职业动作;
创建动画层可以设置weight权重,和Mask骨骼遮罩;
Defend层,由于防御只需要右手动作一直举盾,其他动作一致,添加RightHandMask;
Asset面板右键Create-Avatar Mask,把不需要的骨骼都标红;
层与层之间会更具weight混合——这就让我们可以通过代码来插值计算在不同之间做动画连贯处理;
比如BaseLayer=>Attack层做了插值计算后;
7.动画曲线
动画过程中可以设置曲线,通过代码可获得曲线的值;
比如这里,我希望攻击时,角色向前跨出一步,但是又不希望匀速滑步,要求起手时跨出一大段距离,逐渐减少,有个惯性的效果;设置如下曲线;
代码中:通过动画机获取参数attack1hAVelocity,会返回动画时间对应的曲线值;
model.transform.forward * mAnima.GetFloat("attack1hAVelocity");
8.RootMotion
有些动画播放时位置会改变,Animator动画机勾选Apply Root Motion,表示使用动画中的位移;
Unity脚本生命周期中有一个OnAnimaRootMove,实现该方法动画中的位移只会受到脚本控制;
代码中,当播放attack1hC动画时,OnAnimaRootMove累积动画中的位置,在FixedUpdate中赋予Rigidbody;
这样可以做到前面动画曲线的效果,这种方法会更符合美术需求;
9.onAnimationIK
在OnAnimationIK周期方法中代码控制骨骼节点的位置;
我就动作不符合需求且没有美术配合的时候用用;
也有很多高级IK算法,可以模拟出各种炫酷飘逸的效果;油管大佬
public class LeftArmAnimaFix : MonoBehaviour { private Transform leftArmLow; [SerializeField]private Vector3 offset; private Animator mAnima; private void Start() { mAnima = GetComponent<Animator>(); leftArmLow = mAnima.GetBoneTransform(HumanBodyBones.LeftLowerArm); } public void OnAnimatorIK(int layerIndex) { leftArmLow.localEulerAngles += offset; mAnima.SetBoneLocalRotation(HumanBodyBones.LeftLowerArm,Quaternion.Euler(leftArmLow.localEulerAngles)); } }
- Unity动画,状态机的使用
- C# FSM (仿Unity 中的Mecanim动画系统的状态机)
- [WPF]DataGridTemplateColumn使用ComboBox绑定Dictionary细节记录
- 关于Unity中旧版动画系统的使用
- 从BouncingBall.java中学习使用属性动画记录
- 在unity中使用spine动画
- squirrel-foundation状态机的使用细节
- Java项目中使用log记录日志的一些细节
- Unity4.x新动画系统Mecanim使用
- cocostudio1.6UI编辑器中动画使用 cocos2dx3.3 播放问题记录
- unity插件使用--Unitybmob插件使用记录
- 将3DMax编辑的动画,导入给已经绑定蒙皮好的模型给Unity使用
- 使用Unity实现一个简单的UV动画
- unity功能记录--使用摄像机
- Unity3D——在Unity中使用DragonBones动画
- Unity 动画状态机学习及其相关知识
- 记录以下boost::shared_ptr的一个使用细节
- 学习笔记:Unity战斗卡牌游戏(三)-----代码加载预设 及 Tween动画使用及播放回掉
- Unity使用Hotween动画插件遇到的坑
- Theano 使用、开发与测试的各种细节记录