1. 介绍
做好了走、跑、转弯后,我们就需要来点更加高级的动画了。
我们使用自带动画学习笔记2中的翻墙Vault动画,来控制人物翻墙。
在[动画学习笔记4](https://www.cnblogs.com/Fflyqaq/p/10777793.html)的基础上添加Vault动画。 ![](https://img2018.cnblogs.com/blog/1355434/201904/1355434-20190427134224868-1278682975.png) 添加一个参数**Vault**,设置当人物处于跑的状态并且Vault参数为true时会自动翻墙。 ![](https://img2018.cnblogs.com/blog/1355434/201904/1355434-20190427134439683-1900554000.png)
2. 问题
问题1:如何判断当人物跑向墙体时,在一定范围内触发跳跃动画?
问题2:跳跃动画如果只是播放的话,很可能会出现穿模现象,如何让人物的手正好按着墙翻过去呢?
2.1 问题1
解决思路:
- 新建一个坐标用于存储跳跃时,手要按下的位置
- 判断人物是否处于跑的状态
- 使用射线检测,当人物正前方一段距离为要跳跃墙面时,获取此物体最上面的点为要按下的点
下面新方法的介绍:
anim.GetCurrentAnimatorStateInfo(0).IsName("LocalMotion"):判断当前播放的动画是否为LocalMotion动画,返回bool
public static bool Raycast(Vector3 origin, Vector3 direction, out RaycastHit hitInfo,float maxDistance = Mathf.Infinity):射线起点,射线方向,碰撞物体信息,检测最大距离
private Animator anim;
private Vector3 matchTarget = Vector3.zero; //匹配手按下的位置
void Start () {
anim = gameObject.GetComponent<Animator>();
}
void Update()
{
ProcessVault();
}
private void ProcessVault()
{
bool isVault = false;
//只有物体在Blend Tree动画下才需要检测,0是层数,默认状态是第0层
if (anim.GetFloat(speedZID) > 3 && anim.GetCurrentAnimatorStateInfo(0).IsName("LocalMotion"))
{
//射线起点,射线方向,碰撞物体信息,检测最大距离
//起点在脚部向上一点,射线方向是人物正前方,
RaycastHit hit;
if (Physics.Raycast(transform.position + Vector3.up * 0.3f, transform.forward, out hit, 4.0f))
{
//Obstacle是要跳跃墙面的tag
if (hit.collider.tag == "Obstacle")
{
//只有一定距离时才会触发,不然贴着墙走就会跳了
if (hit.distance > 3)
{
Vector3 point = hit.point;
//修改碰撞点y坐标为:碰撞体的y位置+碰撞体的尺寸高度
point.y = hit.collider.transform.position.y + hit.collider.bounds.size.y;
matchTarget = point;
isVault = true;
}
}
}
}
anim.SetBool(valutID, isVault);
}
2.2. 问题2
问题2的解决方法就要靠我们的MatchTarget了,上面获取了手要按下的点后,只需要让手按在这里就行了。
anim.IsInTransition(0):该层动画是否在进行动画的过渡,返回bool
void MatchTarget (Vector3 matchPosition, Quaternion matchRotation, AvatarTarget targetBodyPart, MatchTargetWeightMask weightMask, float startNormalizedTime,float targetNormalizedTime):
参数1:要匹配点的位置。
参数2:匹配的目标点旋转角度的四元数(不太懂,写Quaternion.identity)。
参数3:要匹配的人物位置(AvatarTarget.LeftHand表示人物骨骼的左手)
参数4:position和rotation占的权重(因为我们只匹配位置,所以如下设置位置权重1,旋转权重0)。
参数5:从动画的什么时候开始匹配。
参数6:什么时候结束(这需要自己慢慢调试,多试试就好了)
private void ProcessVault()
{
if (anim.GetCurrentAnimatorStateInfo(0).IsName("Vault") && anim.IsInTransition(0) == false)
{
//当正为跳墙的状态时候触发
anim.MatchTarget(matchTarget, Quaternion.identity, AvatarTarget.LeftHand, new MatchTargetWeightMask(Vector3.one, 0), 0.32f, 0.4f);
}
}