Unity相機(jī)范圍適應(yīng)物體大小
情形
相機(jī)是游戲向玩家展示的主要手段。大部分時(shí)候,相機(jī)的位置和范圍可以提前設(shè)定,在游戲中不會(huì)做變化。但有些時(shí)候,我們希望相機(jī)在游戲當(dāng)中能夠調(diào)整位置和范圍,以顯示某一物體。
具體一點(diǎn),說一下我遇到的情況。我希望顯示的物體是一個(gè)由玩家自定義自己制造的飛船。這個(gè)飛船可大可小,在玩家把它做出來之前,游戲是無法確定它的大小的。自然地,用來跟隨飛船的攝像機(jī)也無法確定位置和范圍。我希望在玩家制作完畢飛船之后,能夠使相機(jī)適應(yīng)飛船的尺寸,在屏幕中合適的顯示出飛船的全部。
方法
下面提供我的解決方法。我的解決方法假設(shè)相機(jī)正對(duì)需要適應(yīng)顯示的物體的中心。如果不是這樣,需要對(duì)代碼做一些小改動(dòng),但總體做法是適用的。
public class CameraManager:MonoBehaviour
{
// 對(duì)攝像機(jī)的引用,可以在面板中設(shè)置,也可以在初始化時(shí)獲取。
public Camera cam;
// 需要顯示的物體的中心位置。
public Transform root;
// 物體的半徑。即物體里中心最遠(yuǎn)的地方到中心的距離。
public float radius;
// 一些參數(shù),在面板中調(diào)試。
// 兩個(gè)參數(shù)增大都會(huì)使屏幕中物體變小。
// 半徑和相機(jī)范圍的關(guān)系參數(shù)
public float radiusToSizeFactor=2;
// 半徑和相機(jī)距離的關(guān)系參數(shù)
public float radiusToDistanceFactor=2;
// 傳入物體的中心位置和物體半徑。
public void PrepareCamera(Transform center, float r)
{
// 根據(jù)參數(shù)設(shè)置相機(jī)到物體的距離。
cam.transform.localPosition = new Vector3(0, 0, -radiusToDistanceFactor * radius);
// 如果需要顯示的物體不是正對(duì)相機(jī)中心,修改這個(gè)向量的初值。
Vector3 worldPos = new Vector3(0, radius, 0);
// 把向量轉(zhuǎn)換到世界坐標(biāo)系,因?yàn)橄鄼C(jī)的接口只接受世界坐標(biāo)
worldPos = root.TransformPoint(worldPos);
// 獲得點(diǎn)在相機(jī)屏幕中的相對(duì)位置,如正好在屏幕左下角的點(diǎn)返回(0, 0, z),正好在右上角的點(diǎn)返回(1, 1, z)。z為物體離相機(jī)的深度距離,在這里沒有用處。
Vector3 viewPos = cam.WorldToViewportPoint(worldPos);
// 根據(jù)參數(shù)調(diào)整相機(jī)范圍。這里我用的是正交相機(jī),如果使用透視相機(jī),這里應(yīng)該修改fieldOfView。
// 如果參數(shù)為2,則物體最多占到屏幕的1/2高度。
cam.orthographicSize *= radiusToSizeFactor * viewPos.y;
}
}
結(jié)語
Unity并沒有給出他所用的Camera.orthograpicSize 和Camera.fieldOfView 是如何計(jì)算的,具有什么意義。所以沒辦法直接計(jì)算出合適的值,只能通過相對(duì)關(guān)系做放大和縮小。還是有那么一點(diǎn)不直觀。
|