在之前的章節,我們分別設計了角色的動畫以及移動的程式碼,但兩者未被合拼,移動時沒有移動的動畫。因此這次我們將會去了解如何讓兩者可以融合。
首先,我們要利用動畫器去管理人物的不同動畫動作,在我們之前建立 Animator 的位置,我們可以找到人物的 Animator-Controller,雙擊打開它。
打開後,我們可以看到兩個我們之前建立的動作 Idle 以及 Run,另外還有連接到 Idle 的 Entry、Exit 和 Any State。
動畫器的操作概念,是利用箭頭連接不同的動作,並為每個箭頭設定他的條件。Entry 代表一開始時以及被連到 Exit 後會播放的動畫,Any State 則是代表在任何一個動作正在播放的情況下,如果從 Any State 拉出去的箭頭條件被滿足,就會跳到它指向的動畫。
如果你的預設動畫不是 Idle,你可以右鍵 Idle 去設為預設狀態。
現在,我們要讓角色可以在移動時由 Idle 狀態轉到 Run 狀態,我們先要從 Idle 建立箭頭到 Run,右鍵 Idle 建立過渡再左鍵點擊 Run。
然後要為這個箭頭過渡設定條件,要設定條件我們就建立和需要讀取人物移動的參數,我們在動畫器左側打開參數頁,點選右上角的加號建立 float,並命名為 speed。
然後點擊剛剛建立的箭頭,我們可以在 Conditions 條件區點擊加號建立新的條件 Speed Greater 0 速度大於0。
再到上方打開 Setting,把過渡時間設為0,退出時間取消打勾,這些都是一些 3D unity 才會較常用的動作過渡功能。
再建立一個從跑步狀態回到站立狀態的過渡,右鍵 Run 建立過渡拉出箭頭到 Idle,並一樣的更改箭頭的設定,過渡時間設為0,退出時間取消打勾,以及建立條件 Speed less 0.01 速度低於0.01。
現在播過遊戲,你會看到人物雖然移動時還是站立動畫,但如果在動畫器中改變 Speed 的數值,你會看到人物就會開始播放跑步動作,改回0就會變站立狀態。
確認沒有問題後,我們便可以把人物移動的腳本中的數值輸入到動畫器裹了。打開 PlayerMovement,我們要先建立一個 [SerializeField] 的動畫器變數:
[SerializeField] private Animator animator;
然後回到 Unity,我們可以把同樣在人物元件中的 Animator 拉到我們腳本的 Animator 欄位中。
接著我們就可以把 Rigidbody 的 velocity.x 數值和動畫器的參數作連接。在腳本的 FixedUpdate() 中呼叫 animator.SetFloat(),前面的是參數名稱,要注意大小寫需要正確,後面為輸入到動畫器參數的數值,因為不需要考量左右方向,所以需要把數值變為絕對值:
// 動畫參數設定
animator.SetFloat("speed", Mathf.Abs(rb.velocity.x));
現在播放遊戲,角色應該能順利在走動時切換站立和走動的動畫了。
接下來我們要把跳躍也加進遊戲,先為場景中的人物再建立 PlayerJump 以及 PlayerFall 兩個動作。
然後把所有的動畫像下圖一樣連接,並建立新的 bool 參數 isJumping 和 float 參數 upSpeed,isJumping 將會讀取角色是否在進行跳躍,upSpeed 則是記錄玩家的上下速率去判決是否在下降。
連到 Jump 的兩個箭頭把條件設定為 isJumping 為 true 時。
從 Jump 到 Fall 的箭頭條件為 upSpeed 小於 0 時。
從 Fall 到 Exit 的條件為 isJumping 為 false 時。
再到腳本中更新 animator 相關的程式碼:
// 動畫參數設定
animator.SetFloat("speed", Mathf.Abs(rb.velocity.x));
animator.SetBool("isJumping", isJumping);
animator.SetFloat("upSpeed", rb.velocity.y);
這樣基本上就完成了,播放遊戲時會順利有跳躍動畫。但有人可能會發現,按住空白鍵時,動畫會維持在 Fall 的狀態,為了更好的效果,我們可以再增加一個從 Fall 回到 Jump 的過渡,條件設為 upSpeed 大於0時。
到此人物基本動畫就順利連接到移動系統了。如果各位之後要開發出更多不同的技能如衝刺、蹲下等,也只需要新增更多不同的參數去進行過渡即可。