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; }