Related Posts Plugin for WordPress, Blogger...

4-6 Eliminating ThirdPersonCharacter.cs

本章重構要來刪除ThirdPersonCharacter,相關功能將會合併至CharacterMovement.cs。首先,請如下圖將ThirdPersonCharacter.cs內的程式碼一步一步貼到CharacterMovement.cs,注意檢查於CharacterMovement.cs中有同樣使用到rigidbody跟animator的部分,便不需要複製。

複製完成後,請將ThirdPersonCharacter.cs刪除。

刪除後應該會發現程式碼中提示匯入ThirdPersonCharacter的部分為紅字,請依序將紅字的部分刪除吧,已經不需要了。

Player中原本放置ThirdPersonCharacter的地方會顯示Nothing Selected,請將這部分也刪掉。修改完成後,部分數值如movingTurnSpeed、stationaryTurnSpeed應會有所改變,請大家自己確認看看唷。

以下提供新的CharacterMovement的程式碼:

using System;
using UnityEngine;
using UnityEngine.AI;
using RPG.CameraUI;

namespace RPG.Character{
 [RequireComponent(typeof (NavMeshAgent))]
 public class CharacterMovement : MonoBehaviour
 {
  [SerializeField] float walkMoveStopRadius = 0.2f;
  [SerializeField] float attackMoveStopRadius = 5f;
  [SerializeField] float moveSpeedMultiplier = 1f;
  [SerializeField] float animationSpeedMultiplier = 1f;
  [SerializeField] float movingTurnSpeed = 360f;
  [SerializeField] float stationaryTurnSpeed = 180f;
  [SerializeField] float moveThreshold = 1f;

  NavMeshAgent agent = null;
  Animator animator = null;
  Rigidbody myRigidbody = null;
  float turnAmount;
  float forwardAmount;

     private void Start()
     {
   CameraRaycaster cameraRaycaster = Camera.main.GetComponent();
   animator = GetComponent ();

   myRigidbody = GetComponent ();
   myRigidbody.constraints = RigidbodyConstraints.FreezeRotation;

   agent = GetComponent ();
   agent.updateRotation = false;
   agent.updatePosition = true;

   cameraRaycaster.onMouseOverWalkable += OnMouseOverWalkable;
   cameraRaycaster.onMouseOverEnemy += OnMouseOverEnemy;
     }

  public void Move(Vector3 movement)
  {
   SetForwardAndTurn (movement);
   ApplyExtraTurnRotation();
   UpdateAnimator();
  }

  private void SetForwardAndTurn(Vector3 movement){
   // 將Wolrd相對的向量轉換成Local相對的向量
   if (movement.magnitude > moveThreshold) {
    movement.Normalize ();
   }
   // 將Worldspace的方向轉換成LocalSpace
   Vector3 localMovement = transform.InverseTransformDirection(movement);
   turnAmount = Mathf.Atan2(localMovement.x, localMovement.z);
   forwardAmount = localMovement.z;
  }

  void UpdateAnimator()
  {
   // update the animator parameters
   animator.SetFloat("Forward", forwardAmount, 0.1f, Time.deltaTime);
   animator.SetFloat("Turn", turnAmount, 0.1f, Time.deltaTime);
   animator.speed = animationSpeedMultiplier;
  }

  void ApplyExtraTurnRotation()
  {
   // help the character turn faster (this is in addition to root rotation in the animation)
   float turnSpeed = Mathf.Lerp(stationaryTurnSpeed, movingTurnSpeed, forwardAmount);
   transform.Rotate(0, turnAmount * turnSpeed * Time.deltaTime, 0);
  }

  void Update(){
   if (agent.remainingDistance > agent.stoppingDistance) {
    Move(agent.desiredVelocity);
   } else {
    Move (Vector3.zero);
   }
  }

  void OnMouseOverWalkable(Vector3 destination){
   if (Input.GetMouseButton (0)) {
    // 設置地點為滑鼠點擊的位置
    agent.SetDestination(destination);
    GetComponent ().stoppingDistance = walkMoveStopRadius;
   }
  }

  void OnMouseOverEnemy(Enemy enemy){
   if (Input.GetMouseButton (0)) {
    // 設置地點為Enemy的位置
    agent.SetDestination(enemy.transform.position);
    GetComponent ().stoppingDistance = attackMoveStopRadius;
   }
  }

  void OnAnimatorMove(){
   if (Time.deltaTime > 0) {
    Vector3 velocity = (animator.deltaPosition * moveSpeedMultiplier) / Time.deltaTime;
    // 保持y軸的速度不變
    velocity.y = myRigidbody.velocity.y;
    myRigidbody.velocity = velocity;
   }
  }

  void OnDrawGizmos(){
   //繪製攻擊範圍
   Gizmos.color = new Color(255f, 0f, 0f, 0.5f);
   Gizmos.DrawWireSphere (transform.position, attackMoveStopRadius);
  }
 }
}



留言