一.使用向量原理轉換到目標方向
為了讓角色的自身y轉向目標方向,並且以最小角度旋轉,要點是獲得當前方向與目標方向的叉值,從而判斷應該旋轉的方向
float rotateSpeed;
//相對目標位置運動
void trackPosition02(Vector3 tarPosition)
{
Vector3 targetDir = tarPosition - transform.position;
Vector3 up = transform.up;
float angle = Vector3.Angle(targetDir, up);
if (angle <= Time.fixedDeltaTime * rotateSpeed) return;//判斷角度是否小於臨界值,如果小於,那么不需要旋轉,此處用於避免旋轉抖動
Vector3 cross = Vector3.Cross(up, targetDir);
if (cross.z > 0) transform.Rotate(new Vector3(0, 0, rotateSpeed0* Time.deltaTime)); else transform.Rotate(new Vector3(0, 0, -rotateSpeed0* Time.deltaTime));
}
可能unity提供了更簡單的判定方式,知道的老兄留個評論
二.利用角度符號判斷轉到目標方向
這里原理和一相同,只是判斷角度的方式是使用判斷兩者的角度差,而不是向量的叉值
float angle = Vector3.SignedAngle(transform.up, target.position - transform.position, Vector3.forward);
transform.Rotate(new Vector3(0, 0, Mathf.Sign(angle) * speed * Time.deltaTime));
三.有角度限制的轉到目標方向
這里角度限制是指在局部坐標系內的角度限制,比如某個TD坦克,它的炮塔只能在正方向的-30度到正30度之間旋轉,
但是除了計算局部旋轉,還要加上父物體的旋轉角度
using System.Collections; using System.Collections.Generic; using UnityEngine; public class RotateTest : MonoBehaviour { // The target marker. public Transform target; // Angular speed in radians per sec. public float speed; //Vector3.up方向為0角度方向 //局部坐標系內的最小角度和最大角度 public float minAngle; public float maxAngle; //局部坐標系內的最小角度和最大角度轉換到直接坐標系的值 public float minAngleInWorld; public float maxAngleInWorld; void Update() { //父親物體的當前角度 float offsetAngle = Vector3.SignedAngle(Vector3.up, transform.parent.transform.up,Vector3.forward); minAngleInWorld = minAngle + offsetAngle; maxAngleInWorld = maxAngle + offsetAngle; //當前的目標方向相對世界坐標Up方向的角度,用於判斷是否在設定的范圍內 float angle = Vector3.SignedAngle(Vector3.up, target.position - transform.position, Vector3.forward); //當前自身與目標的角度方向差,用於決定旋轉方向 float signAngle = Vector3.SignedAngle(transform.up, target.position - transform.position, Vector3.forward); if (angle > minAngleInWorld && angle < maxAngleInWorld) transform.Rotate(new Vector3(0, 0, Mathf.Sign(signAngle)*speed * Time.deltaTime)); /* float angle = Vector3.SignedAngle(transform.up, target.position - transform.position, Vector3.forward); transform.Rotate(new Vector3(0, 0, Mathf.Sign(angle) * speed * Time.deltaTime)); */ } }
四.利用unity的接口旋轉
//數學意義的轉到目標方向 protected void RotateToDir(Vector3 dir) { float angle = Vector3.SignedAngle(Vector3.up, dir, Vector3.forward); Quaternion rotation00 = Quaternion.Euler(0, 0, angle); transform.rotation = Quaternion.RotateTowards(transform.rotation, rotation00, Time.fixedDeltaTime * computeRotateSpeed); }