🎈 Mixamo
🔸 简介
Mixamo
是Adobe
公司推出的在线免费角色动画库
,地址: https://www.mixamo.com/#/,我们可以在上面搜索开发所需的角色动画并下载使用。
🔸 使用说明
例如我们想为Avatar角色添加一个Idle
动画,在Search搜索栏中进行检索:
可以通过UPLOAD CHARACTER
上传我们自己的Avatar模型来预览动画效果:
点击DOWNLOAD
便可以下载对应的角色动画,下载完成后导入到Unity
中,在Import Settings
导入设置Rig
窗口中,将Animation Type
即动画类型改为Humanoid
人形动画:
🎈 Unity Animator
🔸 Blend Tree 混合树
Blend Tree
是Animator Controller
动画状态机中的一种特殊状态类型,用于多个动画之间的平滑混合
,每个动画对最终效果的影响由混合参数
控制,经常用于处理移动动画之间的混合。
例如我们在Mixamo
动画库下载了Idle
、Walk
、Sprint
,即静止、行走、奔跑三个动画,接下来想要使用Blend Tree
通过一个参数Speed
即移动速度来控制这三个动画之间的混合。
首先将这三个动画的Loop Time
都设置为true,表示它们都是循环播放
的:
在Animator
中通过右键 > Create State > From New Blend Tree
来创建一个混合树,命名为Move
,并创建参数Speed
:
双击进入混合树,添加三静止、行走、奔跑三个动画,由于我们使用一个参数Speed
来控制混合,所以Blend Type
使用默认的1D
方式,Threshold
阈值分别设置为0、10、25:
通过用户输入的值来设置Speed
参数:
using UnityEngine;
namespace SK.Framework.Avatar
{
/// <summary>
/// Avatar动画控制
/// </summary>
public class AvatarAnimatorController : AvatarMovementController
{
//动画参数
private static class AnimatorParameters
{
public readonly static int Speed = Animator.StringToHash("Speed");
}
private Animator animator;
protected override void Start()
{
base.Start();
animator = GetComponent<Animator>();
}
protected override void Update()
{
base.Update();
animator.SetFloat(AnimatorParameters.Speed, Mathf.Clamp01(input.magnitude) * speed);
}
}
}
🔸 动画融合
动画融合是指两个动画之间的融合播放,例如第三人称射击游戏中玩家边走边射击的动作,可以理解为移动+射击动画的融合播放:
这里我们以行走+打招呼的动画融合为例,我们在Mixamo
动画库中下载一个Wave
动画,在Animator
中创建一个新的Layer
层级,将Weight
权重设为1,Blending
设为Override
方式,并创建一个Avatar Mask
:
Avatar Mask
禁用掉除了右手和右臂之外的其它部位,因为我们打招呼的动作只需要右手和右臂起作用:
添加一个Trigger
类型的参数,用来触发Wave
动作:
假设用户按下快捷键1
时触发Wave
动作:
using UnityEngine;
namespace SK.Framework.Avatar
{
/// <summary>
/// Avatar动画控制
/// </summary>
public class AvatarAnimatorController : AvatarMovementController
{
//动画参数
private static class AnimatorParameters
{
public readonly static int Speed = Animator.StringToHash("Speed");
public readonly static int Wave = Animator.StringToHash("Wave");
}
private Animator animator;
protected override void Start()
{
base.Start();
animator = GetComponent<Animator>();
}
protected override void Update()
{
base.Update();
animator.SetFloat(AnimatorParameters.Speed, Mathf.Clamp01(input.magnitude) * speed);
if (Input.GetKeyDown(KeyCode.Alpha1))
{
animator.SetTrigger(AnimatorParameters.Wave);
}
}
}
}