1. 程式人生 > >Unity3d--實現第三人稱視角(相機跟隨)

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()中