1-5 Click Mouse To Move
本單元要來製作角色人物會隨著滑鼠點擊地圖上的位置進行移動。首先,請使用課程提供的PlayerMovement.cs,程式碼如下,自己於Unity內新增檔案後複製上去吧,也加上註解了。
確認加入後,可以先執行遊戲,此時會發現Console視窗出現錯誤訊息。
錯誤訊息顯示為PlayerMovement第24行出現錯誤,應該是因為找不到cameraRaycaster物件。此時請見第14行,知道cameraRaycaster物件是先找到場景中的Main Camera,再取得Main Camera中的cameraRaycaster。
但是,目前的cameraRaycaster放在Camera Arm中,而非Main Camera。
using System; using UnityEngine; using UnityStandardAssets.Characters.ThirdPerson; [RequireComponent(typeof (ThirdPersonCharacter))] public class PlayerMovement : MonoBehaviour { ThirdPersonCharacter m_Character; // A reference to the ThirdPersonCharacter on the object CameraRaycaster cameraRaycaster; Vector3 currentClickTarget; private void Start() { cameraRaycaster = Camera.main.GetComponent(); m_Character = GetComponent (); currentClickTarget = transform.position; } // Fixed update is called in sync with physics private void FixedUpdate() { if (Input.GetMouseButton(0)) { print("Cursor raycast hit" + cameraRaycaster.layerHit); switch (cameraRaycaster.layerHit) { case Layer.Walkable: //取得滑鼠點擊到的物件的位置 currentClickTarget = cameraRaycaster.hit.point; break; case Layer.Enemy: print ("Not moving to enemy."); break; default: print ("Unexpected layer found."); break; } } //將點擊到的物件位置減去自己的位置,取得相減後的向量,告知ThirdPersonCharacter物件依向量移動 //後面兩個false分別為蹲下和跳躍 m_Character.Move(currentClickTarget - transform.position, false, false); } }
確認加入後,可以先執行遊戲,此時會發現Console視窗出現錯誤訊息。
錯誤訊息顯示為PlayerMovement第24行出現錯誤,應該是因為找不到cameraRaycaster物件。此時請見第14行,知道cameraRaycaster物件是先找到場景中的Main Camera,再取得Main Camera中的cameraRaycaster。
但是,目前的cameraRaycaster放在Camera Arm中,而非Main Camera。
所以,將Camera Raycaster和Cursor一併移動到Main Camera中吧。(Cursor內也有用到Camera Raycaster,故一起移動)
再度執行,會發現點擊地圖後,角色可以移動了!可是移動得好慢.......
你可以調整數值,讓他跑得很快。當我調整的數值如下時,便會發現角色會一直原地繞圈圈,就像個傻瓜一樣!哈哈。
問題發生的原因,是因移動的速度數值太大,人物角色移動一次跨越太遠的距離,導致人物角色無法精確移動到滑鼠點擊的位置。此時,就會發生角色原地繞圈問題。所以,接下來我們要加一段if條件式,用來偵測當移動距離『太小』時,就不要移動了。
計算移動距離,我們使用Unity Vector3物件中的magnitude方法。如不清楚公式,請參考下列網址:
求單一座標點或兩座標點之間的距離長度
修改後的PlayerMovement如下。再度執行便能解決原地繞圈圈的問題。
using System; using UnityEngine; using UnityStandardAssets.Characters.ThirdPerson; [RequireComponent(typeof (ThirdPersonCharacter))] public class PlayerMovement : MonoBehaviour { [SerializeField] float walkMoveStopRadius = 0.2f; ThirdPersonCharacter m_Character; // A reference to the ThirdPersonCharacter on the object CameraRaycaster cameraRaycaster; Vector3 currentClickTarget; private void Start() { cameraRaycaster = Camera.main.GetComponent(); m_Character = GetComponent (); currentClickTarget = transform.position; } // Fixed update is called in sync with physics private void FixedUpdate() { if (Input.GetMouseButton(0)) { print("Cursor raycast hit" + cameraRaycaster.layerHit); switch (cameraRaycaster.layerHit) { case Layer.Walkable: //取得滑鼠點擊到的物件的位置 currentClickTarget = cameraRaycaster.hit.point; break; case Layer.Enemy: print ("Not moving to enemy."); break; default: print ("Unexpected layer found."); break; } } //將點擊到的物件位置減去自己的位置,取得相減後的向量 Vector3 playerToClickPoint = currentClickTarget - transform.position; //計算該向量的距離,若距離太短,就不要移動了(可避免人物角色原地移動) if (playerToClickPoint.magnitude >= walkMoveStopRadius) { //告知ThirdPersonCharacter物件依向量移動,後面兩個false分別為蹲下和跳躍 m_Character.Move(playerToClickPoint, false, false); } else { m_Character.Move(Vector3.zero, false, false); } } }
留言
張貼留言