Related Posts Plugin for WordPress, Blogger...

1-5 Click Mouse To Move

本單元要來製作角色人物會隨著滑鼠點擊地圖上的位置進行移動。首先,請使用課程提供的PlayerMovement.cs,程式碼如下,自己於Unity內新增檔案後複製上去吧,也加上註解了。


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

留言