游戏开发|Unity中的Animator动画详解
Unity中的Animator动画详解
- Animator动画导入
- Animator动画详解
- 动画类型选择
- Rig面板属性
- Mode面板属性
- Animation面板属性
- 动画片段
- 控制使用 Animator动画
- 创建动画控制器,添加需要播放的动画片段
- 创建动画状态
- Parameters面板
- 设置动画层内部状态
- 相关代码
- 注意事项
Animator动画导入 模型名+@+动画名的方式,可以直接组装使用动画;
直接将动画资源导入到unity中,一般包含模型、贴图、材质三种。
Animator动画详解 动画类型选择
文章图片
Rig面板属性
Animation Type | 不同的动画类型 |
---|---|
None | 无状态 |
Legacy | 老版Animation用的模式(无法使用状态机)。 |
Generic | (新版本)人形非人形都可以使用; |
Humanoid | (新版本)只能人形动画使用;选中后Apply按钮可点击确定是否可以使用; |
文章图片
Avatar Definition:骨骼获取方式;
Mode面板属性
Mode面板属性 | Value |
---|---|
Scale Factor | 缩放因子(控制模型大小) |
Mesh Compression | 网格压缩(用于优化,越高越消耗性能) |
Read/Write Enabled | 可读可写(模型需发生变化) |
Optimize Colliders | 优化的一种方式(一般选中默认模式) |
Generate Colliders | 自动给模型添加Colliders碰撞器 |
文章图片
Import Animation :导入动画;
Anim.Compression :优化动画的一种方式;
Rotation Error 、Position Error 、Scale Error :由上选择出现的三种优化类型;值越小越消耗性能,值越大越不精确;
Clips:动画片段,可以剪辑添加动画片段;+ 添加动画片段,-删除相关的动画片段;
动画片段
文章图片
点击上面的Clips里面的动画片段,弹出来相对应的动画片段;
start、End:本动画片段的开始结束时间;
Loop Time:本动画片段是否循环;
Loop Pose:循环时动画播放更加平滑(设置为循环动画状态);
Curves:动画曲线;
Events:动画事件回调;(写入的方法名字脚本必须在本物体上)
Mask: 动画遮罩
控制使用 Animator动画 模型添加Animator组件,
文章图片
Controller:动画控制器;
Avatar:骨骼配置,相同的骨骼可以共用一套动画;
Apply Root Motion :勾选后会使用模型自身的位移;
update Mode ;
Normal:正常的;
Animate Physics:物理更新;
Unscaled Time:忽略时间,常用语ui动画,不会因为暂停而不播放;
Culling Mode : 剔除模式;(优化的一种)
Always Animate :总是播放,不管我的相机是否照射到动画,本动画一直 会播放;
Cull Update Transforms : 相机外,剔除动画动作,但是留下位移;
Cull Completely: 相机外剔除动画动作位移;
创建动画控制器,添加需要播放的动画片段 Create ->Animator Controller创建动画控制器;
打开动画控制器,把相应的动画片段放到动画控制器中;
文章图片
Any State: 任何状态;(到的目标状态任意状态都可以到目标的状态)
Entry:退出状态;
Exit:进入状态;
Layers:动画层;
Parameters:本动画层的的数据层;
创建动画状态
1:让动画直接拖入到Animator 面板中去;可以直接用;
2:在Anmimator面板中点击右键,Create State->Empty;
文章图片
New State :动画片段名字,可修改自己需要的名字;
Motion:动画片段,可选择需要的动画片段;
Speed:播放动画片段速度;
Motion Time:
Mirror:镜像设置;
Cycle Offset:偏移量,动画起始帧多少去播放;
Foot Ik:动力学;
Write Defaults :写入默认值;
Transitions (动画片段过渡到其他动画片段的过渡设置)
如果有片段,动画点击后显示动画片段;如下图
文章图片
Solo:勾选后,只会在所有 勾选Solo 中切换,其他默认等同 勾选Mute ;
Mute:勾选后,不会切入到该状态 ;
Has Exit Time :本动画片段是否能被打断;
Conditions:过渡需要的条件;可以选择Parameters里面的创建的数据以及数据相关的判断条件;
窗口是动画的衔接,可以控制俩个动画的衔接程度,
文章图片
按钮左右滑动来控制俩个动画的重叠程度,从而让俩个动画衔接更自然;
Parameters面板
文章图片
+ :添加属性的类型;共有Floath、int、bool、Trigger、四种类型;
bool 和Trigger的区别:Trigger类似于bool,但是设置后会自动复位,可以认为我设置为true后会自动设置为自身为false; 比如攻击动画,需要攻击动画播放一次就自动回来,就可以选用Trigger;
设置动画层内部状态
鼠标右键点击某一个动画片段;
文章图片
Make Transition:添加过渡;
Set as Layer Default State :设置为默认状态(一般是idel的动画);
Copy/Paste:复制或者粘贴;
Create new BlendTree in State :在本动画状态机里创建个BlendTree;
Delete :删除本动画状态;
相关代码 1.bool isHuman { get; } 是否是人形动画;
2.bool isInitialized { get; } 检测动画是否初始化成功;
当没有控制器时会提示Not initialized,此时调用isInitialized返回False,反之返回True;
文章图片
3.int layerCount { get; }动画层数;
4.float speed { get; set; }动画的整体速度,影响其中的每一个动画剪辑;
5.bool stabilizeFeet { get; set; } 过渡和混合时,脚自动稳定;
6.static int StringToHash(string name) 注意这个是静态方法,通过字符串取得参数的hash值;
7.CrossFade(…) 系列接口;混合过渡并且播放
第四个参数normalizedTime要说一下,是0-1的范围,表示目标动画剪辑从哪里开始播放;
animator.CrossFade("Jump", 0.2f, 0, 0.5f);
调用后从中间一半0.5处开始播放
8.CrossFade(…) 系列接口;混合过渡并且播放
混合并且按照实际时间进行。这里的实际时间是指Time.time的时间;
CrossFade是按照动画的自身时间进行混合。如果动画10秒,混合持续时间0.2,会在2秒后混合完成
CrossFadeInFixedTime是按照实际时间进行混合。如果动画10秒,混合持续时间0.2,会在0.2秒后混合完成
使用CrossFade或CrossFadeInFixedTime混合时,如果混合时间大于动画自身长度,动画自身会被滞留在最后一帧,直到混合结束
9.AnimatorTransitionInfo GetAnimatorTransitionInfo(int layerIndex);
获得当前动画的过渡信息
10.T GetBehaviour() 和 T[ ]GetBehaviours()
返回挂载在AnimatorController上的行为脚本StateMachineBehaviour
通常StateMachineBehaviour之间的交互会经常用到。
11.Transform GetBoneTransform(HumanBodyBones humanBoneId)
[人形动画]获取骨骼的Transform对象,参数是枚举形。
如果被临时删除了或者没有绑定这个关节,会返回空;
ebug.Log("GetBoneTransform: " + animator.GetBoneTransform(HumanBodyBones.LeftFoot));
//print GetBoneTransform: joint_FootLT (UnityEngine.Transform)
12.AnimatorClipInfo[] GetCurrentAnimatorClipInfo(int layerIndex);
获得当前层正在播放的剪辑数组,并且获取到的时间长度(clip.length)不受Animator速度影响。
如果想获取全部原始剪辑,可以用runtimeAnimatorController.animationClip;
13.AnimatorStateInfo GetCurrentAnimatorStateInfo(int layerIndex);
获得当前所处的动画状态
返回的结构中.length是动画总长度,normalizedTime是归一化的动画当前时间;
注意取到的length属性会受到Animator速度缩放影响;
文章图片
另外,取到的归一化时间normalizedTime在播放循环动画时,会无限增长
(如果要获取不受缩放影响的原始剪辑,可以用runtimeAnimatorController.animationClip或者GetCurrentAnimatorClipInfo,区别在于一个能取到全部,一个只能取到当前播放的);
13***.bool HasState(int layerIndex, int stateID);
配合Animator.StringToHash可以直接转换成stateID; ***
Debug.Log(animator.HasState(0, Animator.StringToHash("Idle")));
//print True
14.bool IsInTransition(int layerIndex);
是否正处于过渡,很常用的一个接口,如果忽视了过渡的判断,就会有意想不到的bug
if(!animator.IsInTransition(0) && animator.GetCurrentAnimatorStateInfo(0).IsName("Idle"))
{
//Do something.
}
14.Play(…)系列接口
需要注意normalizedTime参数,区间在0-1之间,直接影响到目标动画剪辑从哪个时间点开始播放
15.void Rebind();
重新绑定动画器的所有动画的属性和网格数据。
有时根骨骼坐标会被锁定,重置坐标后,调用该方法即可解决。
15.void ResetTrigger(…);
重设该触发参数为False;
如果是当前状态播放结束再跳转的话,会用到这个方法,在结束之前可以重置回False;
16.GetSet各类型参数系列(SetFloat,SetBool,SetInteger,SetTrigger)
最常用的接口
但需要注意下float类型数据,可以单独设置阻尼,具体看这篇
https://www.cnblogs.com/hont/p/5086101.html
17.void SetBoneLocalRotation(…);
[人形动画]设置某个骨骼的本地旋转
18.void Vector3 GetIKHintPosition(AvatarIKHint hint) & SetIKHintPosition(AvatarIKHint hint, Vector3 hintPosition)
[人形动画]获取/设置IK Hint位置;
19.float GetIKHintPositionWeight(AvatarIKHint hint) & void SetIKHintPositionWeight(AvatarIKHint hint, float value)
[人形动画]获取/设置IK Hint位置权重;
20.Vector3 GetIKPosition(AvatarIKGoal goal) & void SetIKPosition(AvatarIKGoal goal, Vector3 goalPosition)
[人形动画]获取/设置IK位置;
21.float GetIKPositionWeight(AvatarIKGoal goal) & void SetIKPositionWeight(AvatarIKGoal goal, float value)
[人形动画]获取/设置和获取IK位置权重;
22.Quaternion GetIKRotation(AvatarIKGoal goal) & void SetIKRotation(AvatarIKGoal goal, Quaternion goalRotation)
[人形动画]获取/设置IK旋转;
23.float GetIKRotationWeight(AvatarIKGoal goal) & void SetIKRotationWeight(AvatarIKGoal goal, float value)
[人形动画]获取/设置IK旋转权重;
IK相关操作请参考这篇:https://www.cnblogs.com/hont/p/5096855.html
24.void SetLayerWeight(int layerIndex, float weight)
设置层权重
24.void SetTarget(AvatarTarget targetIndex, float targetNormalizedTime)
[人形动画]在动画播放前得到播放后的坐标和旋转。
25.void StartPlayback()
开始回放
26.void StartRecording(int frameCount)
开始录制
注意参数中的frameCount是需要录制长度的帧数
如果参数小于1,则不会限制录制时间
27.void StopPlayback()
停止回放
28.void StopRecording()
停止录制
录制与回放具体 https://www.cnblogs.com/hont/p/5095237.html
29.void Update(float deltaTime)
Animator直接开放出了Update接口,如果你只是想更新动画信息而不前进播放动画,deltaTime参数可以设为0;
在做下一个状态指向判断时,非常有效;
30.AnimatorClipInfo[] GetNextAnimatorClipInfo(int layerIndex)
返回下一个状态的剪辑信息,如果没有下一个状态返回该结构体的默认值
经过测试,修改过播放信息并不会立即执行,会在Animator刷新时更新该值,或者手动调用Animator的Update更新该值
31.AnimatorStateInfo GetNextAnimatorStateInfo(int layerIndex)
返回下一个状态的信息,如果没有下一个状态返回该结构体的默认值
经过测试,修改过播放信息并不会立即执行,会在Animator刷新时更新该值,或者手动调用Animator的Update更新该值
注意事项 【游戏开发|Unity中的Animator动画详解】1:如果是人形动画,需要将动画都设置为HumAnoid模式;
2:关掉位移方式;1:Animator 下的Apply Root Motion 关闭;则不会有位移上的变化;2:动画如果是人形动画,则还可以选择此动画下面的Animation的相关设置(如下图);可以实现保留部分位移;
文章图片
推荐阅读
- 深入理解Go之generate
- 游戏IP(立足于玩家情感的粉丝经济)
- 标签、语法规范、内联框架、超链接、CSS的编写位置、CSS语法、开发工具、块和内联、常用选择器、后代元素选择器、伪类、伪元素。
- 人生游戏--是游戏,还是人生()
- 「按键精灵安卓版」关于全分辨率脚本的一些理解(非游戏app)
- (小说)月流水几亿的火爆游戏养成记
- 游戏治愈了我无聊之症
- Unity和Android通信系列文章2——扩展UnityPlayerActivity
- 我的软件测试开发工程师书单
- echart|echart 双轴图开发