using UnityEngine;
using System.Collections;
public class SmoothFollow : MonoBehaviour {
public float distance = 10.0f;//目標物體與攝像機之間在世界座標基礎上保持水平上的距離
public float height = 5.0f;//攝像機與目標物體之間的高度差
public float heightDamping = 2.0f;//高度變化阻尼
public float rotationDamping = 3.0f;//旋轉變化阻尼
public float offsetHeight = 1.0f;//在攝像機採用lookAt()方法時讓他關注的座標向上偏移1個單位
Transform selfTransform;//定義一個對自身的引用
public Transform Target;//目標物體引用
[AddComponentMenu("Camera-Control/Smooth Follow")]
void Start () {
selfTransform = GetComponent<Transform>();//獲得自身的組件信息
}
void LateUpdate () {//使用這個更新方法就是保證每幀刷新時,物體先變化,然後攝像機纔跟隨的
if (!Target)
return;//安全保護
float wantedRotationAngle = Target.eulerAngles.y;//目標物體的角度
float wantedHeight = Target.position.y + height;//目標物體的高度
float currentRotationAngle = selfTransform.eulerAngles.y;//當前攝像機的角度
float currentHeight = selfTransform.position.y;//當前攝像機的高度
currentRotationAngle = Mathf.LerpAngle(currentRotationAngle, wantedRotationAngle, rotationDamping * Time.deltaTime);//執行每一幀時爲達到平滑變化的目的,採用線性插值方法每次變化一點
currentHeight = Mathf.Lerp(currentHeight, wantedHeight, heightDamping * Time.deltaTime);//如上
Quaternion currentRotation = Quaternion.Euler(0, currentRotationAngle, 0);//因爲旋轉角的變化不好用具體的變化角度表示,而四元數剛好可以表示角度繞哪個軸旋轉多少度,表示角度的變化值
selfTransform.position = Target.position;//這一步是整個跟隨算法核心的步驟,目的是將目標物體的世界座標位置付給攝像機,如此攝像機的位置就和目標位置重疊,此時只需要根據上面存儲的攝像機的位置信息,恢復攝像機的應有位置即可。再次注意,此處改變只是世界座標的position改變,並沒有涉及攝像機自身的鏡頭朝向,及旋轉。所以說可以利用上面記錄的旋轉角的變化量(四元數)來處理攝像機的變化。
selfTransform.position -= currentRotation * Vector3.forward * distance;//攝像機此時的位置參數減去角度變化的四元數乘以水平偏移量的積,如此就可以得出攝像機在目標物體後方的位置及狀態。
Vector3 currentPosition = transform.position;//把上面已變化一部分的攝像機位置信息暫存下來
currentPosition.y = currentHeight;//改變高度
selfTransform.position = currentPosition;//改變過的信息給攝像機
selfTransform.LookAt(Target.position + new Vector3(0, offsetHeight, 0));//使攝像機關注目標物體的座標中心且是用攝像機的本地座標,另外需要注意的是,攝像機關注的是物體本地座標的z軸方向
}
}