Unity动画系统入门

这只是我觉得目前比较重要且在项目中遇到的知识点

想要更详细了解可以去看看Randy的博客:https://zhuanlan.zhihu.com/p/105029905
还可以去b站搜傅老师学黑魂复刻,也是会学到不少3D动画系统的东西

所遇问题及解决

  1. 问题:单个方向没有问题,斜着走时速度会达到1.414,也就是根号2

在B站学习傅老师的黑魂复刻教学学到的

 float input = Mathf.Sqrt(Dright * Dright + Dup * Dup);
 Dmag = input>1.0f?1.0f:input;//控制输入大小

缺点:在未到1.0f前曲线平滑,但在1.0f~1.414突然强制转换为1.0f,导致原本的增速整体变快

椭圆映射法

image-20200427095517285

public Vector2 SquareToCircle(Vector2 input)
{
	Vector2 output = Vector2.zero;
	output.x = input.x * Mathf.Sqrt(1 - (input.y * input.y) / 2.0f);
	output.y = input.y * Mathf.Sqrt(1 - (input.x * input.x) / 2.0f);
	return output;
}
  1. 问题:trigger触发变量快速连续按两下时会累计,然后连续播放两次

在切换动画机的状态添加脚本,使用On Enter和On Exit函数重置trigger

知识点

Animator窗口

tptqnx.png

Avatar:动画节点导引替身,与动画复用(尤其是人形动画复用)有关,通过配置和应用Avatar,可以实现不同FBX模型之间的动画复用

Apply Root Motion:是否将动画中的根节点位移,植入到Unity中的物体位移上

简单来说就是:是否要让动画师来决定角色的位移

RootMotion模式

  1. 勾选上时:导入的动画自带位移(动画师先前做动画时设置好的),优点:不会出现滑步现象(即是位移速度和动画不匹配)

  2. 不勾选上时:不带位移,若无脚本控制则是原地做动作,比如原地走路,优点:可以进行模型的位置修正

  3. 用OnAnimatorMove来使用脚本控制何时Apply,何时不用,当动画需要某些条件或者修正时

Update Mode:状态机播放动画的时间模式

Normal:使用游戏Upadte的更新模式,一般常用于普通角色动画

Animate Physics:使用物理周期的更新模式,用于角色与物体有物理交互或有物理位移时

Unscaled Time:不受TimeScal影响的更新模式,常用于GUI界面的动画

Culling Mode:剔除模式

Always Animate:无论物体是否被摄像机可见,总是计算所有节点的运动,完整的进行动画播放,常用于主角

Cull Update Transforms:当物体不被摄像机可见时,仅计算根节点的位移植入,保证物体位置上的正确,常用于配角以优化游戏,如GTA的路人

Cull Completely:当物体不被摄像机可见时,完全终止动画的运行,用于消耗性能较高的动画

状态面板

​ 图为动画控制器里状态机的一个状态面板

image-20200525090023402

Motion:这个State所引用的动画片段,Unity中的动画片段,分为两种

  1. 通过剪辑FBX中的整段动画生成的动画切片(Clip)

  2. 由Unity提供的Animation窗口创建出的动画片段(Clip)

Speed:控制动画的播放速度,1为正常速度,-1倒着放

可选中用Parameter控制:

  1. Multiplier:Speed的一个倍率因子,可用float

  2. Normalized Time:片段播放位置,取值0到1之间,可用float获取播放进度

  3. Mirror:是否进行左右翻转,可用bool控制

  4. Cycle Offset:偏移量,可用float

Foot IK:脚部的IK反向力学修正,如楼梯,上坡,爬梯

优先级

Transitions:从一个状态出发的过渡,存在优先级的顺序,越靠上方的过渡,优先级越大,我们可以通过拖动过渡来排列优先顺序

动画过渡面板

tpwtdx.png

​ 选中任意过渡线Gizmo,会出现如上动画过渡面板

用于调试

  1. Solo:勾选时,该State只能进行该过渡,其它过渡将无效

  2. Mute:勾选时,这个过渡将无效,当测试某两个动画间的过渡时,可用这个将其中可能过渡到别的动画的过渡线无效化

Settings:对过渡的加强版设置,可调整过渡细节

Interruption Source:打断来源,允许该过渡被来自CurrentState或NextState的其它过渡打断

动作游戏需注意此点掌握

Conditions:过渡条件,可添加多个动画参数,则最终决定于其所有参数交集

中间时间条就是二者过渡时的融合比例,可手动拉拽选择融合比例大小

Has Exit Time

勾选时上一个状态对于的动画片段必须被播放到末尾,才允许这个过渡被触发,不勾选可以在任意时刻进行过渡

如果你发现动画过渡有延迟或者是不流畅时,很大可能就是这个勾选了,但一般是有过度参数才将其选择取消勾选,若无过渡的Parameters参数,则大部分情况是对该过渡速度要求不高,建议勾选上

动画事件的插入

  1. 通过剪辑FBX中的整段动画生成的动画切片

    可以在FBX面板的Events处添加关键帧事件,对着想插入的时间点右键即可,还可选择参数和事件

    tpNvq0.png

  2. Animation窗口创建出的动画片段

    可以在Animation窗口先用白线确定事件插入时间点,再点击插入事件

    tpaktS.png

  3. StateMechineBehaviour提供的状态事件脚本

    选中任意状态,用Add Behaviour添加即可

    tprqu4.png

    每个状态事件脚本都有如下五个接口:

    1. OnStateEnter:当进入该状态的过渡被触发时调用

    2. OnStateUpdate:进入该状态时循环调用

    3. OnStateExit:如果曾进入过该状态,之后进入到其它状态时被调用

    4. OnStateMove:相当于Mono脚本中OnAnimatorMove的作用,使用之前提到的RootMotion模式三,但仅针对这个State状态运行时

    5. OnStateIK:相当于Mono脚本中的OnAnimatorIK的作用,但仅针对这个State状态运行时

    Enter和Exit很适合用于动画开始和结束的音效控制

  4. 通过普通脚本控制动画的进行和过程中的事件触发

脚本中获取动画参数的方法

Parameters动画参数分为四种:float,int,bool,trigger

Trigger的触发必须对当前状态机的运行状态进行判断

int runHash=Animator.StringToHash("Run");//这里的名称要与Animator窗口中,动画参数的名称对应
//通常对于调用频繁的动画参数我们使用哈希值进行快速访问

//下面设置/获取动画参数均有使用String参数名称进行映射的重载和使用哈希值进行映射的重载


//获取设置Float类型参数,通常结合Input轴线
animator.GetFloat(floatHash);
animator.SetFloat(floatHash, Input.GetAxis("Horizontal"));

//获取设置Int类型参数
animator.GetInteger(intHash);
animator.SetInteger(intHash,Number);

//获取设置Bool类型参数
animator.GetBool(boolHash);
animator.SetBool(boolHash, true / false);

//触发,取消触发Trigger的方法
animator.SetTrigger(triggerHash);
animator.ResetTrigger(triggerHash);

AnimatorStateInfo 动画器状态信息

animator.GetCurrentAnimatorStateInfo(layerID);

用来获取一个 AnimatorStateInfo 对象,有关当前或下一个状态zd的动画器信息版。

属性

fullPathHash 该状态的完整路径哈希值,层名+状态名

length 该状态的当前持续长度。

loop 该状态是否循环。

normalizedTime 该状态的归一化时间。

shortNameHash 使用Animator.StringToHash生成的哈希值。传递的字符串不包含父层的名权字。

tagHash 该状态的标签

tpJBb8.png

Animator.StringToHash("Base Layer.Walk");//获得state的fullPathHash
Animator.StringToHash("Walk");//获得state的shortNameHash
Animator.StringToHash("Walking");//获得Parameters变量

如果state和Parameters变量用一个名称"Walk",然后用Animator.StringToHash("Walk")将获得一样的哈希值

如果不用同一名称,然后Animator.StringToHash将获得不同的哈希值

posted @ 2020-08-26 09:41  AMzz  阅读(994)  评论(0编辑  收藏  举报
//字体