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的程式碼:
複製完成後,請將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); } } }
留言
張貼留言