Unity3D正交相機包圍盒計算方式

Unity中的相機你們確定都十分熟悉,主要有兩種攝像機,即透視攝像機(Perspective)和正交攝像機(Orthographic)。
正交相機適用於作2D用途。正交相機有兩個特別的屬性Size和Aspect;算法

Size:正交攝像機顯示高度
Aspect:攝像機顯示區域的寬、高比ide

根據上面屬性能夠計算正交相機渲染畫面的大小:函數

camera.height=camera.orthographicSize*2f

camera.width=camera.height*camera.aspect

包圍盒算法是一種求離散點集最優包圍空間的方法,基本思想就是用體積稍大且特性簡單的幾何體(包圍盒)來近似地代替複雜的集合對象。
以下圖,三個物體的包圍盒。
Unity3D正交相機包圍盒計算方式code

計算方案:orm

  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)即爲擴大包圍盒函數。)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;
    }
相關文章
相關標籤/搜索