获取摄像机的视口区域

常用的摄像机有两种、一种是正交摄像机,另一种是透视摄像机,由于正交相机的视口范围是固定不变的,因此这里只讨论透视摄像机,它是由原点向外扩散的视锥体,这里引用下雨松MOMO的一篇博客《Unity3D研究院之获取摄像机的视口区域》中代码如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class cameraUI : MonoBehaviour {

    private Camera theCamera;

    //距离摄像机8.5米 用黄色表示
    public float upperDistance = 8.5f;
    //距离摄像机12米 用红色表示
    public float lowerDistance = 12.0f;

    private Transform tx;
    void Start () {
        if (!theCamera)
        {
            theCamera = Camera.main;//获取MainCamera
        }
        tx = theCamera.transform;
    }
	
	// Update is called once per frame
	void Update () {
        FindUpperCorners();
        FindLowerCorners();
    }

    void FindUpperCorners()
    {
        Vector3[] corners = GetCorners(upperDistance);

        // for debugging
        Debug.DrawLine(corners[0], corners[1], Color.yellow); // UpperLeft -> UpperRight
        Debug.DrawLine(corners[1], corners[3], Color.yellow); // UpperRight -> LowerRight
        Debug.DrawLine(corners[3], corners[2], Color.yellow); // LowerRight -> LowerLeft
        Debug.DrawLine(corners[2], corners[0], Color.yellow); // LowerLeft -> UpperLeft
    }


    void FindLowerCorners()
    {
        Vector3[] corners = GetCorners(lowerDistance);

        // for debugging
        Debug.DrawLine(corners[0], corners[1], Color.red);
        Debug.DrawLine(corners[1], corners[3], Color.red);
        Debug.DrawLine(corners[3], corners[2], Color.red);
        Debug.DrawLine(corners[2], corners[0], Color.red);
    }


    Vector3[] GetCorners(float distance)
    {
        Vector3[] corners = new Vector3[4];
        
        //获取相机的视野区域角度(默认60°),取的图中对应粉红色所示角度的弧度值
        float halfFOV = (theCamera.fieldOfView * 0.5f) * Mathf.Deg2Rad;
        float aspect = theCamera.aspect;//相机的宽高比

        float height = distance * Mathf.Tan(halfFOV);//根据三角函数计算出distance距离之外的视野高度
        float width = height * aspect;//根据宽高比算出宽度

        // UpperLeft 计算视野区域左上角坐标
        corners[0] = tx.position - (tx.right * width);//x坐标
        corners[0] += tx.up * height;//y坐标
        corners[0] += tx.forward * distance;//z坐标

        // UpperRight
        corners[1] = tx.position + (tx.right * width);
        corners[1] += tx.up * height;
        corners[1] += tx.forward * distance;

        // LowerLeft
        corners[2] = tx.position - (tx.right * width);
        corners[2] -= tx.up * height;
        corners[2] += tx.forward * distance;

        // LowerRight
        corners[3] = tx.position + (tx.right * width);
        corners[3] -= tx.up * height;
        corners[3] += tx.forward * distance;

        return corners;
    }
}

算法示意图如下:

代码中distance参数即为图中1所示线条

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值