1.新建一個朝上的UI Rotation爲(0,0,0)
2.腳本掛在1中的UI上,Target設置爲要追蹤的物體,self設置爲攝像機。(當攝像機移動時,UI會指向Target)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DirectionTest : MonoBehaviour {
public Transform target; //目標
public Transform self; //自己
public float direction; //箭頭旋轉的方向,或者說角度,只有正的值
public Vector3 u; //叉乘結果,用於判斷上述角度是正是負
float devValue = 10f; //離屏邊緣距離
float showWidth; //由devValue計算出從中心到邊緣的距離(寬和高)
float showHeight;
Quaternion originRot; //箭頭原角度
// 初始化
void Start()
{
originRot = transform.localRotation;
}
void Update()
{
// 每幀都重新計算一次,主要是調試使用方便
showWidth = Screen.width / 2 - devValue;
showHeight = Screen.height / 2 - devValue;
// 計算向量和角度
Vector3 forVec = self.forward; //計算本物體的前向量
Vector3 angVec = (target.position - self.position).normalized; //本物體和目標物體之間的單位向量
Vector3 targetVec = Vector3.ProjectOnPlane(angVec - forVec, forVec).normalized; //這步很重要,將上述兩個向量計算出一個代表方向的向量後投射到本身的xy平面
Vector3 originVec = self.up;
direction = Vector3.Dot(originVec, targetVec); //再跟y軸正方向做點積和叉積,就求出了箭頭需要旋轉的角度和角度的正負
u = Vector3.Cross(originVec, targetVec);
direction = Mathf.Acos(direction) * Mathf.Rad2Deg; //轉換爲角度
u = self.InverseTransformDirection(u); //叉積結果轉換爲本物體座標
// 給與旋轉值
transform.localRotation = originRot * Quaternion.Euler(new Vector3(0f, 0f, direction * (u.z > 0 ? 1 : -1)));
//// 計算當前物體在屏幕上的位置
//Vector2 screenPos = Camera.main.WorldToScreenPoint(target.position);
////if(Vector3.Dot(forVec, angVec) < 0)
//// 不在屏幕內的情況
//if (screenPos.x < devValue || screenPos.x > Screen.width - devValue || screenPos.y < devValue || screenPos.y > Screen.height - devValue || Vector3.Dot(forVec, angVec) < 0)
//{
// Vector3 result = Vector3.zero;
// if (direction == 0) //特殊角度0和180直接賦值,大家知道tan90會出現什麼結果
// {
// result.y = showHeight;
// }
// else if (direction == 180)
// {
// result.y = -showHeight;
// }
// else //非特殊角
// {
// // 轉換角度
// float direction_new = 90 - direction;
// float k = Mathf.Tan(Mathf.Deg2Rad * direction_new);
// // 矩形
// result.x = showHeight / k;
// if ((result.x > (-showWidth)) && (result.x < showWidth)) // 角度在上下底邊的情況
// {
// result.y = showHeight;
// if (direction > 90)
// {
// result.y = -showHeight;
// result.x = result.x * -1;
// }
// }
// else // 角度在左右底邊的情況
// {
// result.y = showWidth * k;
// if ((result.y > -showHeight) && result.y < showHeight)
// {
// result.x = result.y / k;
// }
// }
// if (u.z > 0)
// result.x = -result.x;
// }
// transform.localPosition = result;
//}
//else // 在屏幕內的情況
//{
// transform.position = screenPos;
//}
}
}