滑鼠點擊地板的人物移動或3D與2D射線中提到的射線(Ray)。
Unity導航系統前三篇。
Mecanim動畫系統Part1、Part3、Part4。
本文開始。
這次要做的是,使用滑鼠點擊地板的人物移動操控。
移動路徑規劃使用導航網格(NavMesh),移動目標位置使用射線(Ray)指定,人物動畫則是使用Mecanim動畫系統。
成果如下圖。
在開始實作目標之前,需要先把物件準備好,第一個是地板物件Floor。
使用Plane物件,新增tag命名為Floor並且選取,接著點擊Static下拉選單,選取Navigation Static。
接著是障礙物物件Obstacle。
使用Cube物件,新增tag命名為Obstacle並且選取,新增元件Nav Mesh Obstacle,然後勾選Carve選項。
最後是人物模型。
這裡使用UnityChan的人物模型,在模型下新增元件Nav Mesh Agent。
將地板、障礙物和人物模型都準備好後,就可以開始實作這次的目標。
第一步是產生導航網格(NavMesh),Window -> Navigation開啟導航視窗,點選Bake,也就是烘焙生成導航網格。
如果場景沒存檔,Unity會告訴你要存檔。
烘焙(Bake)完成後,可以在場景中看到藍色的網格,如下圖。
接著點選人物模型,新增控制用腳本,腳本內容如下。
using UnityEngine; public class Move : MonoBehaviour { private NavMeshAgent agent;////(1) private Vector3 target; void Start () { agent = GetComponent<NavMeshAgent>();////(2) target = transform.position; } void Update () { Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);////(3) RaycastHit hit; if (Input.GetMouseButtonDown(0) ////(4) && Physics.Raycast(ray, out hit) && hit.transform.gameObject.tag == "Floor") { target = hit.point;////(5) } agent.SetDestination(target);////(6) } }(1)腳本中有兩個重要變數,target負責記錄滑鼠點擊的位置,agent抓取target位置後移動。
(2)在Start初始化時,agent抓取模型下的元件,target設定目標位置,這裡就給它模型位置作為初始化的數值。
(3)取得攝影機到滑鼠位置的射線。
(4)當滑鼠點擊左鍵時 & 射線有打到物體 & 該物體的標籤為Floor時,判斷式成立。
(5)將target位置設定為點擊的位置。
(6)將agent的目標設為target。
執行後點擊地板,應該可以看到以下結果。
到這裡會依照點擊的位置移動,而且帶有迴避障礙物的功能,移動的的部分就算是完成了。
最後追加人物的動畫當作修飾,讓Unity醬動起來好看一點。
在模型下新增元件Animator,並且在專案中新增Animator Controller檔案後代入Animator元件。
選取Window -> Animator,或雙擊Animator Controller檔案開啟動畫編輯視窗,接著將準備好的動畫,待機與移動拖曳至動畫編輯視窗。
在動畫上右鍵選取Make Transition,建立兩個動畫之間的轉換,然後在Parameters中新增浮點數speed。
選取轉換的線,將Has Exit Time的勾選取消,Conditions新增動畫轉換的門檻,待機到移動為大於(Greater),移動到待機為小於(Less),數值這裡設定為0.01。
開啟人物模型的控制腳本,加入紅字的程式碼。
using UnityEngine; public class Move : MonoBehaviour { private NavMeshAgent agent; private Vector3 target; private Animator animator; void Start () { agent = GetComponent<NavMeshAgent>(); target = transform.position; animator = GetComponent<Animator>(); } void Update () { Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); RaycastHit hit; if (Input.GetMouseButtonDown(0) && Physics.Raycast(ray, out hit) && hit.transform.gameObject.tag == "Floor") { target = hit.point; } agent.SetDestination(target); animator.SetFloat("speed", agent.velocity.sqrMagnitude); } }以下是執行結果。
嗯‧‧‧有移動太快旋轉太慢的問題,將agent元件的參數Speed調整為2,Angular Speed調整為360。
再執行一次看看結果。
看起來好多了,以上就是加上導航網格的點擊地板移動,和先前相比,透過導航網格可以做出非直線的移動,同時也多了迴避障礙物的功能。
這次就到這裡。
素材連結:
Unity醬~~
以及‧‧‧
地板
沒有留言:
張貼留言