Unity---動畫系統學習(5)---使用MatchTarget來匹配動畫


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

解決思路:

  1. 新建一個坐標用於存儲跳躍時,手要按下的位置
  2. 判斷人物是否處於跑的狀態
  3. 使用射線檢測,當人物正前方一段距離為要跳躍牆面時,獲取此物體最上面的點為要按下的點

下面新方法的介紹:
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);
        }
    }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM