58.3D动画-动画分层和遮罩
58.1 知识点
动画分层的主要目的
动画分层的作用
- 游戏中会有这样的需求
- 人物健康状态时播放正常动画
- 人物非健康状态时播放特殊动画
- 比如血量低于一定界限,人物的大部分动作将表现为虚弱状态
- 我们可以利用动画分层来快速实现这样的功能
动画分层和动画遮罩结合使用
- 3D游戏中我们常常会面对这样的需求
- 人物站立时会有开枪动作
- 人物跑动时会有开枪动作
- 人物蹲下时会有开枪动作
- 从表现上来看光是开枪动作可能就有3种
- 如果要让美术同学做3种开枪动作费时又费资源
- 我们是否可以这样做
- 比如开枪动画只影响上半身
- 下半身根据实际情况播放站立,跑动,蹲下动作
- 通过上下半身播放不同的动画就可以达到动画的组合播放
动画分层的两个目的
- 两套不同层动作的切换
- 结合动画遮罩让两个动画叠加在一起播放
- 提升动画多样性,节约资源
如何使用动画分层
新建一个动画层
设置动画层参数
Weight 权重
当动画同时播放时,如果选择的是叠加状态,会根据权重决定叠加的比例
Mask 动画遮罩
该层动画全部都会受该遮罩的影响
可以在创建遮罩文件并赋值给这个参数
遮罩文件可以设置不受影响的区域,动画播的时候不收影响的区域就没效果。这个和模型文件的Animation页签下的选项效果一样,不过只影响这一层。
Blending 混合方式
Override:覆盖方式,播放该层动画时忽略其他层信息
Additive:叠加方式,会和其它层动画叠加播放
Sync 是否同步其它层
主要用于直接从另一个层复制状态过来,在该层中进行修改
适用于比如正常状态下有待机走路跑步等等动作,但是受伤状态下动作会改变,可以利用同步层方便我们进行编辑
选择后会多一个Source Layer表示你要复制哪一层的状态
比如直接复制普通层1,修改上面的动画选项为蹲下的待机和走路,这样调大这一层的权重就会播放蹲下的待机和走路
Timing 源层
当选中Sync同步其它层时,该参数激活
选中,会采用折中方案调整同步层上的动画时长(基于权重计算)
不选中,动画时长将使用原始层做为母版
IK Pass IK处理
反向动力学,之后讲解IK的时候再讲解
在该层中设置状态机
注意:结合遮罩使用时默认状态一般为Null状态,空动画不会关联任何动画剪辑
可以创建新的空状态作为一层的默认播放动画,这样就算该层有权重也不会有任何影响
根据需求创建动画遮罩
动画层权重代码控制
Animator.SetLayerWeight方法 设置动画层权重
//Animator中的设置动画层权重GetLayerIndex方法
animator.SetLayerWeight(animator.GetLayerIndex("MyLayer2"), 1);
总结
- 利用动画分层我们可以做到
- 上下半身播放两个动画进行组合,比如上半身扔炸弹,下半身待机移动蹲下
- 快速制作正常状态和受伤状态的动作切换
58.2 知识点代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Lesson58_3D动画_动画分层和遮罩 : MonoBehaviour
{
private Animator animator;
void Start()
{
#region 知识点一 动画分层的主要目的
//动画分层的作用
//游戏中会有这样的需求
//人物健康状态时播放正常动画
//人物非健康状态时播放特殊动画
//比如血量低于一定界限,人物的大部分动作将表现为虚弱状态
//我们可以利用动画分层来快速实现这样的功能
//动画分层和动画遮罩结合使用
//3D游戏中我们常常会面对这样的需求
//人物站立时会有开枪动作
//人物跑动时会有开枪动作
//人物蹲下时会有开枪动作
//从表现上来看光是开枪动作可能就有3种
//如果要让美术同学做3种开枪动作费时又费资源
//我们是否可以这样做
//比如开枪动画只影响上半身
//下半身根据实际情况播放站立,跑动,蹲下动作
//通过上下半身播放不同的动画就可以达到动画的组合播放
//动画分层的主要就是达到这两个目的
//1.两套不同层动作的切换
//2.结合动画遮罩让两个动画叠加在一起播放
//提升动画多样性,节约资源
#endregion
#region 知识点二 如何使用动画分层
//1.新建一个动画层
//2.设置动画层参数
//3.在该层中设置状态机(注意:结合遮罩使用时默认状态一般为Null状态)
//4.根据需求创建动画遮罩
animator = this.GetComponent<Animator>();
//Animator中的设置动画层权重GetLayerIndex方法
animator.SetLayerWeight(animator.GetLayerIndex("MyLayer2"), 1);
#endregion
#region 总结
//利用动画分层我们可以做到
//1.上下半身播放两个动画进行组合,比如上半身扔炸弹,下半身待机移动蹲下
//2.快速制作正常状态和受伤状态的动作切换
#endregion
}
}
58.3 练习题
在之前练习题的基础上,按J键可以让人物上半身播放一个其他动画
创建新的一层动画,权重设置为1。创建动画遮罩设置屏蔽的下半身并关联。在这一层添加一个空动画设置成默认播放
添加播放上半身动画参数,进行连线关联
添加控制的代码
if (Input.GetKeyDown(KeyCode.J))
animator.SetTrigger("Fall");
为角色制作受伤时,基础动画改变的功能
创建新的层,源层关联第一层,动画剪辑设置为受伤时的相关动画,比如受伤的走路,受伤的默认
代码控制层级的权重
if (Input.GetKeyDown(KeyCode.K))
animator.SetLayerWeight(animator.GetLayerIndex("New Layer 0"), 1);
if (Input.GetKeyDown(KeyCode.L))
animator.SetLayerWeight(animator.GetLayerIndex("New Layer 0"), 0);
58.4 练习题代码
// 引用命名空间
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// 定义一个名为 Lesson58_练习题 的类,并继承 MonoBehaviour
public class Lesson58_练习题 : MonoBehaviour
{
// 声明私有变量 animator,类型为 Animator,表示当前游戏对象的动画控制器
private Animator animator;
// 声明公有变量 roundSpeed,类型为 float,表示角色旋转的速度
public float roundSpeed = 30;
// 在 Start 函数中获取当前游戏对象的动画控制器
void Start()
{
animator = this.GetComponent<Animator>();
}
// 在 Update 函数中实现功能
void Update()
{
// 使用 animator.SetInteger 设置动画控制器中名为 "Speed" 的参数值,使用 Input.GetAxisRaw 获取垂直方向的按键输入
animator.SetInteger("Speed", (int)Input.GetAxisRaw("Vertical"));
// 如果空格键被按下,则设置名为 "Jump" 的布尔类型参数为 true
if (Input.GetKeyDown(KeyCode.Space))
animator.SetBool("Jump", true);
// 根据水平方向的按键输入和旋转速度值,绕着 Y 轴旋转当前游戏对象
this.transform.Rotate(Vector3.up, Input.GetAxisRaw("Horizontal") * roundSpeed * Time.deltaTime);
#region 练习题一
// 如果按键 J 被按下,则设置名为 "Fall" 的触发器为 true
if (Input.GetKeyDown(KeyCode.J))
animator.SetTrigger("Fall");
#endregion
#region 练习题二
// 如果按下键 K,则设置动画控制器中名为 "New Layer 0" 的 Layer 权重值为 1
if (Input.GetKeyDown(KeyCode.K))
animator.SetLayerWeight(animator.GetLayerIndex("New Layer 0"), 1);
// 如果按下键 L,则设置动画控制器中名为 "New Layer 0" 的 Layer 权重值为 0
if (Input.GetKeyDown(KeyCode.L))
animator.SetLayerWeight(animator.GetLayerIndex("New Layer 0"), 0);
#endregion
}
// 声明公有函数 JumpOver,用于在动画结束时将名为 "Jump" 的布尔类型参数设置为 false
public void JumpOver()
{
animator.SetBool("Jump", false);
}
}
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com