Unity中的相機你們確定都十分熟悉,主要有兩種攝像機,即透視攝像機(Perspective)和正交攝像機(Orthographic)。
正交相機適用於作2D用途。正交相機有兩個特別的屬性Size和Aspect;算法
Size:正交攝像機顯示高度
Aspect:攝像機顯示區域的寬、高比ide
根據上面屬性能夠計算正交相機渲染畫面的大小:函數
camera.height=camera.orthographicSize*2f camera.width=camera.height*camera.aspect
包圍盒算法是一種求離散點集最優包圍空間的方法,基本思想就是用體積稍大且特性簡單的幾何體(包圍盒)來近似地代替複雜的集合對象。
以下圖,三個物體的包圍盒。
code
計算方案:orm
- 求得物體(組)的正交投影範圍;
- 移動正交相機到物體組上方的中心位置,並自動調整Size。
Unity中的包圍盒用結構體——Bounds來表示對象
public GameObject obj;//要包圍的物體 public Camera setCamera;//正交相機 public float ScreenScaleFactor;//佔屏比例係數
private void Start() { var bound = GetBoundPointsByObj(obj); var center = bound.center; var extents = bound.extents; setCamera.transform.position = new Vector3(center.x, center.y, center.z - 10); SetOrthCameraSize(center.x - extents.x, center.x + extents.x, center.y - extents.y, center.y + extents.y); }
計算全部物體包圍盒:(求得最終包圍盒的中心點,而後再從中心點開始逐步向外計算包圍盒,bounds.Encapsulate(Bounds bounds)即爲擴大包圍盒函數。)blog
/// <summary> /// 獲取物體包圍盒 /// </summary> /// <param name="obj">父物體</param> /// <returns>物體包圍盒</returns> private Bounds GetBoundPointsByObj(GameObject obj) { var bounds = new Bounds(); if (obj != null) { var renders = obj.GetComponentsInChildren<Renderer>(); if (renders != null) { var boundscenter = Vector3.zero; foreach (var item in renders) { boundscenter += item.bounds.center; } if (obj.transform.childCount > 0) boundscenter /= obj.transform.childCount; bounds = new Bounds(boundscenter, Vector3.zero); foreach (var item in renders) { bounds.Encapsulate(item.bounds); } } } return bounds; }
相機若要在該物體組的中心點處:(下面爲註釋代碼)it
camera.position = new Vector3(bound.center.x, bound.center.y, bound.center.z+k);
設置正交相機的Size:io
/// <summary> /// 設置正交相機的Size /// </summary> /// <param name="xmin">包圍盒x方向最小值</param> /// <param name="xmax">包圍盒x方向最大值</param> /// <param name="ymin">包圍盒y方向最小值</param> /// <param name="ymax">包圍盒y方向最大值</param> private void SetOrthCameraSize(float xmin, float xmax, float ymin, float ymax) { float xDis = xmax - xmin; float yDis = ymax - ymin; float sizeX = xDis / ScreenScaleFactor / 2 / SetCamera.aspect; float sizeY = yDis / ScreenScaleFactor / 2; if (sizeX >= sizeY) setCamera.orthographicSize = sizeX; else setCamera.orthographicSize = sizeY; }