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




留言
張貼留言