Unity3d--實現第三人稱視角(相機跟隨)
實現第三人稱視角有三種:
方案1:
最簡單的就是 直接 把主相機作為Player角色的子物體,並自行固定好相機的位置
方案2:
設定一個空的GameObject,並且與Player的旋轉和位置保持一致,然後將 主相機 設定成該GameObject的子物件。這種做法和方案 1 相似。
(這種做法好處在於 當模擬角色死亡倒地的時候比較方便,如果採用方案 1 ,只能是重新建立一個相機,因為角色倒地的時候,子物體相機也會視角倒地,所以效率肯定方案 2 高)
方案3:
通過程式碼動態改變相機的位置,使相機始終保持在自己想要的位置上,當物體旋轉時,同理。
- 程式碼實現相機跟隨物體,可使用一個介面函式Vector3.SmoothDamp() 平滑阻尼 。
函式介紹:隨著時間的推移,逐漸改變一個向量朝向預期的目標(有點類似受阻力減速運動)
在官方的手冊裡也有推薦用此函式 來實現 平滑的相機跟隨
Unity手冊—-Vector3.SmoothDamp() 傳送門
public static Vector3 SmoothDamp(
Vector3 current, //當前物體位置
Vector3 target, //目標位置
ref Vector3 currentVelocity, //當前速度,這個值由你每次呼叫這個函式時被修改
//雖然使用ref關鍵字,不過函式執行時會自動修改
//一般傳入引數值為0
float smoothTime, //到達目標的大約時間,較小的值將快速到達目標
float maxSpeed = Mathf.Infinity,//選擇允許你限制的最大速度(預設為正無窮)
float deltaTime = Time.deltaTime//自上次呼叫這個函式的時間(預設為Time.deltaTime)
);
- 以下程式碼為 相機跟隨物體 旋轉與移動 例項:
public GameObject thirdPersonPlayer; //角色
public GameObject FollowCamera; //跟隨相機
public float CameraSmoothTime = 0;
private Vector3 velocity = Vector3.zero;
void Update()
{
//相機跟隨旋轉
float x = RotateSpeed * Input.GetAxis("Mouse X");
//以下為相機與角色同步旋轉是
FollowCamera.transform.rotation = Quaternion.Euler(
FollowCamera.transform.rotation.eulerAngles +
Quaternion.AngleAxis(x, Vector3.up).eulerAngles
);//原理: 物體當前的尤拉角 + 滑鼠x軸上的增量所產生的夾角
thirdPersonPlayer.transform.rotation = Quaternion.Euler(
thirdPersonPlayer.transform.rotation.eulerAngles +
Quaternion.AngleAxis(x, Vector3.up).eulerAngles
);//同理
//------------------------------------------------------>>>>>>>>
//相機跟隨移動
Vector3 TargetCameraPosition = thirdPersonPlayer.transform.TransformPoint(new Vector3(0, 4.5f, -5.5f));//獲取相機跟隨的相對位置,再轉為世界座標
FollowCamera.transform.position = Vector3.SmoothDamp(
FollowCamera.transform.position,
TargetCameraPosition,
ref velocity,
CameraSmoothTime, //最好為0
Mathf.Infinity,
Time.deltaTime
);
}
CameraSmoothTime 個人建議設為 <=0.001(直接為0) :
由於平滑阻尼函式類似於減速運動,到達時間設定太長(例如0.5)的話,會出現相機跟隨太慢。
還有一種情況就是(例如0.01),相機完成平滑阻尼運動仍需時間,但時間太短,會使相機不停前後抖動,從而產生角色抖動的現象。
題外話,關於相機跟隨的一些建議與探討:
當物體移動和相機跟隨的重新整理頻率不同時,常常會出現物體抖動的問題,解決這個問題的最好方法是:
當角色的移動和旋轉放在Update()中,那麼就可以把所有相機的移動旋轉放在LateUpdate()。
這是為了在相機追蹤角色位置之前,確保角色已經完成移動與旋轉。如果相機在跟隨物體A時,畫面同時還有物體B,此時物體A和物體B的重新整理頻率需要保持一致,否則物體二仍然會出現抖動
例如:物體A使用rigidbody移動物體,物體B使用改變transform.position來移動且在Update中重新整理,此時物體B會發生抖動。
原因是物體A的rigidbody重新整理是在FixedUpdate()中,而物體B在Update(),重新整理頻率不同導致感覺物體B抖動
此時解決方法如果不改變物體A的移動方式則需要把物體B的重新整理放在FixedUpdate()中