Unity正交相机智能包围物体(组)方案

前端开发 作者: 2024-08-26 00:55:01
# Unity正交相机智能包围物体(组)方案 一、技术背景 今晚是双十一,祝大家剁手愉快啊明天还得做个快乐的打工人,哈哈_~ 进入正题,最近要做个小地图显示,网上也有许多相关文章或技术实现,主要是通

Unity正交相机智能包围物体(组)方案

一、技术背景

二、相关概念

三、解决方案

  • 求得物体(组)的正交投影范围;
  • 移动正交相机到物体组上方的中心位置,并自动调整Size。
/// <summary>
/// 获取物体包围盒
/// </summary>
/// <param name="obj">父物体</param>
/// <returns>返回该物体(组)的包围盒</returns>
private Bounds GetBoundPointsByObj(GameObject obj)
{
    var bounds = new Bounds();
    if (obj != null)
    {//获得所有子物体的Render
        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;
}

3.2.1 正交相机位置计算

3.2.2 正交相机Size计算

public float ScreenScaleFactor;//占屏比例系数
/// <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;//x方向包围盒尺寸
    float yDis = ymax - ymin;//y方向包围盒尺寸
    float sizeX = xDis / ScreenScaleFactor / 2 / SetCamera.aspect;
    float sizeY = yDis / ScreenScaleFactor / 2;
    if (sizeX >= sizeY)//从X或Y方向选择一个合适的相机Size
        SetCamera.orthographicSize = sizeX;
    else
        SetCamera.orthographicSize = sizeY;
}

四、总结

public class Test : MonoBehaviour
{
    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);
    }
    /// <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;
    }
    /// <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 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;
    }
}
原创声明
本站部分文章基于互联网的整理,我们会把真正“有用/优质”的文章整理提供给各位开发者。本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
本文链接:http://www.jiecseo.com/news/show_68692.html