Unity中的相机大家肯定都十分熟悉,主要有两种摄像机,即透视摄像机(Perspective)和正交摄像机(Orthographic)。 正交相机适用于做2D用途。正交相机有两个特别的属性Size和Aspect;

Size:正交摄像机显示高度 Aspect:摄像机显示区域的宽、高比

根据上面属性可以计算正交相机渲染画面的大小:

camera.height=camera.orthographicSize*2f

camera.width=camera.height*camera.aspect

包围盒算法是一种求离散点集最优包围空间的方法,基本思想就是用体积稍大且特性简单的几何体(包围盒)来近似地代替复杂的集合对象。 如下图,三个物体的包围盒。

计算方案:

  1. 求得物体(组)的正交投影范围;
  2. 移动正交相机到物体组上方的中心位置,并自动调整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)即为扩大包围盒函数。)

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

相机若要在该物体组的中心点处:(下面为注释代码)

camera.position = new Vector3(bound.center.x, bound.center.y, bound.center.z+k);

设置正交相机的Size:

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