目录
Unity Mecanim动画系统 之 动画层(Layers)和 动画遮罩(Avatar Mask)的简单使用
一、简单介绍
二、动画层 和 动画遮罩
1、为什么动画中会有层的概念
2、如何使用层动画
3、注意点
4、创建动画遮罩的两种方式
三、效果预览
四、实现步骤
五、关键代码:
Unity中的一些基础知识点。便于后期开发使用。
Unity动画系统,也称为“Mecanim”,提供了以下功能:
简单的工作流程,设置动画的所有元素,包括对象,角色和属性。
支持导入外部创建的动画片段和使用内置动画编辑器制作的动画片段。
人型动画重新定位,动画角色的运动控制可以被所有的角色模型共享,即角色的外观(SkinedMesh)和运动(Animator)是分离的,它们互相组合之后形成最终的动画。
用于编辑动画状态的的简化工作流程,即动画控制器。
方便预览动画片段,以及片段之间的插值过渡。 这使得动画师可以独立于程序员工作,在不运行游戏的情况下,可以对原型和预览动画进行预览。
管理动画与可视化编程工具之间的复杂交互。
不同的身体部位可以使用不同的动画逻辑控制。
动画的分层和掩蔽功能。
好处是有的,类似项目管理
第一:分离动画组
第二:规范动画制作
第三:提供更丰富的动画制作
Ps:其实跟我们的动画融合树差不多
1)添加动画层
2)添加参数
注意:参数是执行动画的触发条件
3)给第二层的触发线绑定参数
绑定的过程中,其实我们会发现New State就代指第一层动画组,而参数帮助我们过渡了层。当然动画是显示不出来的,但是动画片段确实执行了。
在动画层之间切换的过程中,其实主要是通过参数的满足与否来进行层动画执行操作,但是有一个前提就是层的权重 如下图:
层的设置参数说明:
weight :权重,对应着这一层动画在所有层动画中所占的比例。以上图来说明,new layer中的weight为0,模型的动画效果就是base layer中的动画;0-1之间,模型的动画效果就是这两层动画的混合;
mask :遮罩,手动控制模型哪些骨骼参与动画哪些不参与
blending:混合模式—additive和override;additive 两种动画相叠加,并不算融合;override 两种动画相融合;
sync :同步层 就是让该层复刻其他层的动画,其他层可以从Source Layer 选择。
Timing:当前层和Source层同一个状态使用的动画时间长度不一致时,不勾选timing那么复制的层按Source层的时间播放(效果就是复制层动画可能会变快或变慢,Source层动画播放速度不变),勾选timing则Source层按复制层的时间播放(效果就是Source层动画可能会变快或变慢,复制层动画播放速度不变),只有勾选sync,timing才可以勾选;
IK Pass :表示启动IK动画;
1)权重问题决定动画能不能显示出来
如果不设置权重,你会发现即便分好层,而且在状态机中发现动画执行了,但是界面的角色并没有显示出来。
前面的分享已经提到过使用代码控制动画的参数,这里如何通过代码设置权重呢?
[SerializeField]
private Animator ani;
void Start () {
// 表示设置动画第二层的权重为1
ani.SetLayerWeight(1, 1);
}
1)第一种就是create一个avatar Mask,如下:
humanoid 对人体骨骼模型的遮罩,红色代表不参与动画,绿色就是正常参与动画。动画遮罩在混合动画中表现出色,上面说的调整weight值也能实现两种动画的混合,但是这种混合出来的动画看起来很别扭,远没有动画遮罩效果好。
transforms可以导入某一avatar的全部骨骼点,动画具体到对骨骼点的控制;
2)第二种遮罩,就是直接在动画剪辑的属性上更改,如图一为humanoid类型的动画剪辑属性:
图二为generic类型的动画剪辑属性:
这种遮罩更改之后,所有使用到该动画剪辑的地方都会享受到这种遮罩效果;
目标:新建 动画 Layer ,和 Avatar Mask 遮罩,实现边跑边举的动作
1、导入带动画的模型到场景中
2、构建一个 Animator Controoller
3、在 Base Layer 添加一个 Blend Tree,实现 走跑状态的控制
(实现可以参考网址:https://blog.csdn.net/u014361280/article/details/106035344)
4、新建一个Layer 为 HandsLayer,来控制手的上举动作(空动画和上举动画拖入)
5、新建一个 Avatar Mask
6、Avatar Mask 仅只有收可以手臂、手、对应 IK 可以动,其他屏蔽掉
7、把 Avatar Mask 赋值给第二层 HandsLayer
8、新建脚本,控制动画的切换
9、把脚本挂载到游戏模型上
10、运行场景,即可以看到,游戏模型即可以跑也可以上举
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player : MonoBehaviour
{
// 动画控制机
private Animator anim;
// 参数 转为 StringToHash ID
private int speedForwardId = Animator.StringToHash("SpeedForward");
private int turnLeftRightId = Animator.StringToHash("TurnLeftRight");
private int vaultId = Animator.StringToHash("IsVault");
// Start is called before the first frame update
void Start()
{
// 获取 动画控制机
anim = GetComponent();
}
// Update is called once per frame
void Update()
{
if (anim !=null) {
// 根据混合数的数值上下限设置后面的 乘以比例
anim.SetFloat(speedForwardId,Input.GetAxis("Vertical")*4.15f);
anim.SetFloat(turnLeftRightId, Input.GetAxis("Horizontal")*122.8f);
}
// 监视上举动作
VaultHandler();
}
// 监视上举动作
void VaultHandler() {
// 上举动作
if (Input.GetKeyDown(KeyCode.Space))
{
// 比重激活HandsLayer
anim.SetLayerWeight(1, 1);
anim.SetBool(vaultId, true);
}
// 释放上举动作
if (Input.GetKeyUp(KeyCode.Space))
{
// 比重失活HandsLayer
anim.SetLayerWeight(1, 0);
anim.SetBool(vaultId, false);
}
}
}