1. 介紹
做好了走、跑、轉彎后,我們就需要來點更加高級的動畫了。
我們使用自帶動畫學習筆記2中的翻牆Vault動畫,來控制人物翻牆。
在[動畫學習筆記4](https://www.cnblogs.com/Fflyqaq/p/10777793.html)的基礎上添加Vault動畫。  添加一個參數**Vault**,設置當人物處於跑的狀態並且Vault參數為true時會自動翻牆。 
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);
}
}