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-动画状态机使用细节记录的更多相关文章
- unity动画状态机的学习
简单贴一下步骤,备忘 添加多个动画到动画控制器 创建transition,添加转换条件 在代码里面获取animator组件,然后animator.setXXX即可
- Unity插件 - MeshEditor(六) 变形动画状态机
变形动画状态机--MeshAnimator,是针对MeshAnimation的状态管理器,有大量类似Unity animator的功能,但MeshAnimator操作会更加简便,更加直观,居家旅(zh ...
- Unity Animator动画状态机 深入理解(一)
接触Unity以来就已经有了Animator,Animation用的少,不过也大概理解他俩之间的一个区别于联系. 图中其实就是Animator和Animation之间的区别于联系了,啊!你肯定会告诉我 ...
- Unity动画知识之二:Animator动画状态机
上次我们讲过Unity游戏动画从入门到住院,今天我们来讲一下动画状态机. 好了,现在我们已经成功的导入了动画.接下来要玩的东西就很装13啦.因为大部分动画师是用不到这家伙的,需要掌握这个技能的,至少也 ...
- Unity问答——请问一下动画状态机怎么判断动画是否播完了?
这篇博客源自我在泰课在线的回答.链接:http://www.taikr.com/group/1/thread/233 问:请问一下动画状态机怎么判断动画是否播完了? 答: 1. 脚本参考 Animat ...
- Unity3D中通过Animator动画状态机获取任意animation clip的准确播放持续时长
Unity3d 4及之前的版本中动画的播放用的animation,可直接获取其播放持续长度.但5.x及以后的版本中都是用animator来播放动画了. https://docs.unity3d.com ...
- Unity 动画知识之一
Unity现在已经用的很广泛啦,可是却一直没有什么美术向的教程. 程序用方面的内容在各个论坛都有讨论,但是美术似乎很弱势啊. 明明美术也很需要掌握引擎方面的内容嘛! 山谷里的野百合还有春天呢 我们美术 ...
- Unity 动画系统目录 之 Animation
返回 Unity 动画系统目录 官方文档 Animation:https://docs.unity3d.com/ScriptReference/Animation.html Animator:http ...
- Unity动画优化
Unity动画优化 https://blog.csdn.net/TracyZly/article/details/79991593 Unity中Animator做UI动画的一些细节 https://b ...
随机推荐
- 拓扑排序 python
现在你总共有 numCourses 门课需要选,记为 0 到 numCourses - 1.给你一个数组 prerequisites ,其中 prerequisites[i] = [ai, bi] , ...
- margin 塌陷bug 触发bfc
1.bfc block format context 2.如何触发一个盒子的bfc position:absolute; display: inline-block float:left/right; ...
- Anaconda 01_安装问题
一. 创建环境 1.打开cmd 使用如下语句创建环境 conda create -n 环境名 2. 查看当前conda所有环境 conda info --envs 3.激活环境(其中一句) Co ...
- 创建一个 20G 的分区,并格式化为 ext4 文件系统
创建一个 20G 的分区,并格式化为 ext4 文件系统,并完成如下要求: (1)block 大小为 2048,预留空间 20%,卷标为 MYDATA #fdisk /dev/sdb -->n ...
- sql注入之简要注入
#mysql简要注入流程 mysql注入简要流程如下图: 由于还没学习完先结合sqlilabs的第一关讲解信息收集的一部分和数据注入的information_schema的有据查询. #sqli-la ...
- CF1404E Bricks (最大权独立集)
考虑把答案进行转化,通过分矩形条,我们能去掉一些夹在#之间的边 那么答案= #个数 - 能去掉的边个数 但去掉是有限制的,同一个#格子的横边和竖边不能同时去掉 把边转化成点,限制变成边. 横竖边的点 ...
- 解释AOP?
面向切面的编程,或AOP, 是一种编程技术,允许程序模块化横向切割关注点,或横切典型的责任划分,如日志和事务管理.
- 如何使用 Spring Boot 实现分页和排序?
使用 Spring Boot 实现分页非常简单.使用 Spring Data-JPA 可以实现将可分页的传递给存储库方法.
- 面试问题之C++语言:如何避免内存泄漏?
转载于:https://www.php.cn/csharp-article-416104.html 1.不要手动管理内存,可以尝试在适用的情况下使用智能指针. 2.使用string而不是char*.s ...
- Java 中的 HashSet,内部是如何工作的?
HashSet 的内部采用 HashMap 来实现.由于 Map 需要 key 和 value,所以 所有 key 的都有一个默认 value.类似于 HashMap,HashSet 不允许重复的 k ...