Camera---获得摄像机的视口区域(转载大神雨松MOMO)



本文固定链接: http://www.xuanyusong.com/archives/3036
转载请注明: 雨松MOMO 2014年07月31日 于 雨松MOMO程序研究院 发表

摄像机分为两种,一种是正交摄像机还有一种是透视摄像机。正交摄像机无论远近它的视口范围永远是固定的,但是透视摄像机是由原点向外扩散性发射,也就是距离越远它的视口区域也就越大。那么我们如何获取距离摄像机任意距离的视口区域呢?如下图所示,分别用红色和黄色两种颜色将计算出来的视口区域标记了出来。



Unity3D研究院之获取摄像机的视口区域 - 雨松MOMO程序研究院 - 1


 


下面上代码,把如下脚本挂在摄像机出直接运行游戏即可看到。
using UnityEngine;
using System.Collections;
 
public class CameraView : 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;
}
tx = theCamera.transform;
}


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

float halfFOV = ( theCamera.fieldOfView * 0.5f ) * Mathf.Deg2Rad;
float aspect = theCamera.aspect;

float height = distance * Mathf.Tan( halfFOV );
float width = height * aspect;

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

// 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;
}
}
这个脚本是我在逛国外网站无意间发现的,我这里翻译成了C#语言。http://answers.unity3d.com/questions/509466/scale-box-collider-to-camera-view-1.html?sort=oldest


我们可以根据文章里的算法计算出视口3D的坐标点,有了坐标信息那么想干什么都好干了,呵呵。
我的修改版,可以直接输入参数,任意获得某深度的视口区域:需要将脚本挂在在主摄像机上
using UnityEngine;
using System.Collections;
public class CameraRange : MonoBehaviour
{
    private Camera theCamera;
    private Transform tx;
    void Awake()
    {
        if (!theCamera)
        {
            theCamera = Camera.main;
        }
        tx = theCamera.transform;
    }
    //发现在某一点的透视摄像机坐标
    public Vector3[] GetCorners(float distance)
    {
        //0上左 1上右 2下左 3下右
        Vector3[] corners = new Vector3[4];
        float halfFOV = (theCamera.fieldOfView * 0.5f) * Mathf.Deg2Rad;
        float aspect = theCamera.aspect;


        float height = distance * Mathf.Tan(halfFOV);
        float width = height * aspect;


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


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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值