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);
}
}
}






留言
張貼留言