首先大致介绍下几种Unity混合树:Blend Tree,可以有多种模式:
1. 1D混合:只有一个参数,即横坐标。纵坐标是动作权重,横轴上每一个点,对应的各动作权重之和为100%。每个动作分支有自己的100%权重点,即只播放这一个动作。这个值左边是淡入、右边是淡出。Threshold的范围随便设,反正引擎最后都会归一化处理。
1D混合适用于单轴状态过渡,如:idle==>walk==>run==>fast run的速度过渡。Runleft==>Run forward==>RunRight的转角过渡。
2. 2D混合:2D混合又细分了 Simple Directional(方向单一)、Freeform Directional(方向自由)、Freeform Cartesian(笛卡尔自由)三种模式。这三种模式官方文档建议:第一种用于每个位移方向只有一个动作;第二种用于有多个位移方向的同时,有的方向会有多个动作;第三种的X、Y轴就不是表示两个位移方向了,你可以定义一个轴为旋转,一个轴为位移。
3. Direct直接混合模式:混合树里套混合树,似乎适用于复杂的标签控制等。
接下来我介绍下我试验的一个小例子,用一下2D混合模式。
资源是Unity商店里的剑术动作包,里面有一套不同方向的走路动画,包括:向东、西、南、北,以及4个对角线方向,共8个方向的走路动画。这些动画有一个共同点:目光方向都是一个。如下图,看地面的Root Transform罗盘,走路方向是向左,大致为红箭头方向,但Body 的forward方向是蓝箭头方向。
把这8个动作(勾选Apply Root Motion)放入混合树,加上idle,9个动作,形成了如下的圆形阵列。idle在中间,8个方向的走路放到对应方向的坐标位置。参数为BlendX和BlendY,用虚拟轴控制。红点表示当前参数坐标,有圈的点是参与动画融合的点,圈的大小表示权重。
?
?附上代码,通过IsWalk参数把状态转移到混合树里。这里还加了个“敌人”,最后的效果是玩家始终看向敌人的“决斗模式”:
using UnityEngine;
namespace BlendTreeTest
{
public class PlayerWalkTest : MonoBehaviour
{
private Animator playerWalk;
public Transform enemy;
void Awake()
{
playerWalk = GetComponent<Animator>();
}
void Update()
{
transform.LookAt(enemy);
float x = Input.GetAxis("Horizontal");
float y = Input.GetAxis("Vertical");
if (x == 0 && y == 0)
{
playerWalk.SetBool("IsWalk", false);
}
else
{
playerWalk.SetBool("IsWalk", true);
playerWalk.SetFloat("BlendX", x);
playerWalk.SetFloat("BlendY", y);
}
}
}
}
|