Related Posts Plugin for WordPress, Blogger...

1-8 Gamepad Movement Mode

本章要簡單介紹如何設置搖桿模式,於遊戲中按下快捷鍵G,便可以切換成滑鼠移動,或是WASD移動方式。於Unity中,WASD移動模式亦能夠對應到搖桿的移動模式。

首先,我們先將Player上不需要用到的ThirdPersonUserControll關閉。



接著,修改PlayerMovement.cs的內容,程式碼與註解如下:

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;
        
 bool isInDircetMode = false;

    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.GetKeyDown(KeyCode.G)){
   //切換GamePad Mode
   isInDircetMode = !isInDircetMode;
  }

  if (isInDircetMode) {
   ProcessDirectMovement ();
  } else {
   ProcessMouseMovement ();
  }

    }

 private void ProcessDirectMovement(){
  // read inputs
  float h = Input.GetAxis("Horizontal");
  float v = Input.GetAxis("Vertical");

  // calculate camera relative direction to move:
  Vector3 m_CamForward = Vector3.Scale(Camera.main.transform.forward, new Vector3(1, 0, 1)).normalized;
  Vector3 m_Move = v*m_CamForward + h*Camera.main.transform.right;

  m_Character.Move(m_Move, false, false);
 }

 private void ProcessMouseMovement(){
  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);
  }
 }
}



由於部分程式碼於先前文章中已有諸多說明,如不清楚的讀者可以自行連結到
1-5 Click Mouse To Move 
自己比較一下新版PlayerMovement跟舊版有哪些差異。

最後,遊戲執行時出現下列的錯誤訊息。該訊息於CursorAffordance.cs中,當cameraRaycaster沒有Hit任何物件時會顯示。推估原因應是在專案剛起始時,cameraRaycaster的Update還未執行,而CursorAffordance的Update先執行了。

所以,要解決這個Bug,我們將CursorAffordance的Update修改為LateUpdate,讓Cursor鼠標的更換等到所有Update都執行完後再執行。

留言