判断游戏对象是否在摄像机视口的一个方法

简介:

本人菜鸟,用了笨方法实现。大家有更好的方法不吝赐教。
就是对游戏对象绘制一个长方体包围盒,然后用Camera.WorldToViewportPoint()处理。

 

 


将附件代码拖到场景中的要检测的游戏对象即可。比较简单的代码。

复制代码
using UnityEngine;
using System.Collections;
/// <summary>
/// 脚本挂到需要检测是否在摄像机视口内的游戏对象上。
/// By Braith
/// 2014-09-24
/// </summary>
public class CameraViewCheck : MonoBehaviour 
{
    private Transform _target;
    public Camera _camera;
    private bool _gameObjectView = true;
    private float _targetSize_width; //对象宽度,X
    private float _targetSize_height;//对象高度,Y
    private float _targetSize_depth; //对象深度,Z
    private Vector3 _vector01;
    private Vector3 _vector02;
    private Vector3 _vector03;
    private Vector3 _vector04;
    private Vector3 _vector05;
    private Vector3 _vector06;
    private Vector3 _vector07;
    private Vector3 _vector08;
    private Vector3 _viewPos01;
    private Vector3 _viewPos02;
    private Vector3 _viewPos03;
    private Vector3 _viewPos04;
    private Vector3 _viewPos05;
    private Vector3 _viewPos06;
    private Vector3 _viewPos07;
    private Vector3 _viewPos08;
    // Use this for initialization
    void Start () 
    {
        _target                    =             this.transform;
        _camera                    =             Camera.main;
        _targetSize_width          =             _target.renderer.bounds.size.x;
        _targetSize_height         =             _target.renderer.bounds.size.y;
        _targetSize_depth          =             _target.renderer.bounds.size.z;
    }
    
    // Update is called once per frame
    void Update ()
    {
        _vector01 = new Vector3(_target.position.x - _targetSize_width * 0.5f, _target.position.y + _targetSize_height * 0.5f, _target.position.z - _targetSize_depth * 0.5f);//摄像机视口左上角点1。
        _vector02 = new Vector3(_target.position.x + _targetSize_width * 0.5f, _target.position.y + _targetSize_height * 0.5f, _target.position.z - _targetSize_depth * 0.5f);//摄像机视口右上角点1。
        _vector03 = new Vector3(_target.position.x - _targetSize_width * 0.5f, _target.position.y - _targetSize_height * 0.5f, _target.position.z - _targetSize_depth * 0.5f);//摄像机视口左下角点1。
        _vector04 = new Vector3(_target.position.x + _targetSize_width * 0.5f, _target.position.y - _targetSize_height * 0.5f, _target.position.z - _targetSize_depth * 0.5f);//摄像机视口右下角点1。

        _vector05 = new Vector3(_target.position.x - _targetSize_width * 0.5f, _target.position.y + _targetSize_height * 0.5f, _target.position.z + _targetSize_depth * 0.5f);//摄像机视口左上角点2。
        _vector06 = new Vector3(_target.position.x + _targetSize_width * 0.5f, _target.position.y + _targetSize_height * 0.5f, _target.position.z + _targetSize_depth * 0.5f);//摄像机视口右上角点2。
        _vector07 = new Vector3(_target.position.x - _targetSize_width * 0.5f, _target.position.y - _targetSize_height * 0.5f, _target.position.z + _targetSize_depth * 0.5f);//摄像机视口左下角点2。
        _vector08 = new Vector3(_target.position.x + _targetSize_width * 0.5f, _target.position.y - _targetSize_height * 0.5f, _target.position.z + _targetSize_depth * 0.5f);//摄像机视口右下角点2。

        //Camera.WorldToViewportPoint 世界转视窗位置
        _viewPos01 = _camera.WorldToViewportPoint(_vector01);
        _viewPos02 = _camera.WorldToViewportPoint(_vector02);
        _viewPos03 = _camera.WorldToViewportPoint(_vector03);
        _viewPos04 = _camera.WorldToViewportPoint(_vector04);
        _viewPos05 = _camera.WorldToViewportPoint(_vector05);
        _viewPos06 = _camera.WorldToViewportPoint(_vector06);
        _viewPos07 = _camera.WorldToViewportPoint(_vector07);
        _viewPos08 = _camera.WorldToViewportPoint(_vector08);

        BoundsDrawRay();//绘制游戏对象包围轮廓

        if (
            (_viewPos01.x > 1 || _viewPos01.x < 0 || _viewPos01.y > 1 || _viewPos01.y < 0) &&
            (_viewPos02.x > 1 || _viewPos02.x < 0 || _viewPos02.y > 1 || _viewPos02.y < 0) &&
            (_viewPos03.x > 1 || _viewPos03.x < 0 || _viewPos03.y > 1 || _viewPos03.y < 0) &&
            (_viewPos04.x > 1 || _viewPos04.x < 0 || _viewPos04.y > 1 || _viewPos04.y < 0) &&
            (_viewPos05.x > 1 || _viewPos05.x < 0 || _viewPos05.y > 1 || _viewPos05.y < 0) &&
            (_viewPos06.x > 1 || _viewPos06.x < 0 || _viewPos06.y > 1 || _viewPos06.y < 0) &&
            (_viewPos07.x > 1 || _viewPos07.x < 0 || _viewPos07.y > 1 || _viewPos07.y < 0) &&
            (_viewPos08.x > 1 || _viewPos08.x < 0 || _viewPos08.y > 1 || _viewPos08.y < 0)
            )
        {
            _gameObjectView = false;
        }
        else if
            (
            _viewPos01.z < 0 &&
            _viewPos02.z < 0 &&
            _viewPos03.z < 0 &&
            _viewPos04.z < 0 &&
            _viewPos05.z < 0 &&
            _viewPos06.z < 0 &&
            _viewPos07.z < 0 &&
            _viewPos08.z < 0
            )
        {
            _gameObjectView = false;
        }
        else
        {
            _gameObjectView = true;

        }

        if (!_gameObjectView)//游戏对象不在摄像机视口内
        {
            _target.renderer.material.color = Color.red;
            Debug.Log("对象移出了摄像机视口");
        }
        else//游戏对象在摄像机视口内
        {
            Debug.Log("对象在摄像机视口内");
            _target.renderer.material.color = Color.white;
        }


    }

    void BoundsDrawRay()
    {
        Debug.DrawRay(_vector01, _vector02 - _vector01, Color.red);
        Debug.DrawRay(_vector02, _vector04 - _vector02, Color.red);
        Debug.DrawRay(_vector03, _vector01 - _vector03, Color.red);
        Debug.DrawRay(_vector04, _vector03 - _vector04, Color.red);
        
        Debug.DrawRay(_vector05, _vector06 - _vector05, Color.red);
        Debug.DrawRay(_vector06, _vector08 - _vector06, Color.red);
        Debug.DrawRay(_vector07, _vector05 - _vector07, Color.red);
        Debug.DrawRay(_vector08, _vector07 - _vector08, Color.red);
        
        Debug.DrawRay(_vector01, _vector05 - _vector01, Color.red);
        Debug.DrawRay(_vector02, _vector06 - _vector02, Color.red);
        Debug.DrawRay(_vector03, _vector07 - _vector03, Color.red);
        Debug.DrawRay(_vector04, _vector08 - _vector04, Color.red);
    }
}
复制代码

 

---------------------------------------------------------------------------------------------------------

楼主实现的方法,可以直接调用Unity自带的。

//物体在摄像机视口的6个面内,包括部分位于
public bool IsVisibleFrom(Renderer renderer, Camera camera)
{
    Plane[] planes = GeometryUtility.CalculateFrustumPlanes(camera);
    return GeometryUtility.TestPlanesAABB(planes, renderer.bounds);
}

不过如果是要求全部位于视口内的话,可以借鉴楼主的方法去稍作修改。

本文转自jiahuafu博客园博客,原文链接http://www.cnblogs.com/jiahuafu/p/6734174.html如需转载请自行联系原作者


jiahuafu

相关文章
|
1月前
|
容器
ThreeJs同一个场景多个相机的显示
这篇文章讲解了如何在Three.js中实现多相机功能,通过创建和布置多个相机及渲染器,从而能够在同一场景中从不同角度观察3D模型。
70 1
|
3月前
|
图形学
小功能⭐️Unity 如何判断物体是否在摄像机视野内或外
小功能⭐️Unity 如何判断物体是否在摄像机视野内或外
【Unity3D--自由观察模型】模型自动旋转+触屏旋转和缩放
展示3D模型,同时实现模型自动旋转和触屏旋转和缩放
368 0
|
前端开发 JavaScript
【Three.js入门】渲染第一个场景及物体(轨道控制器、坐标轴辅助器、移动缩放旋转)
【Three.js入门】渲染第一个场景及物体(轨道控制器、坐标轴辅助器、移动缩放旋转)
290 0
|
Windows
笔记本电脑亮度调整无效、字体大小改变的解决方案
本文介绍Windows电脑系统更新或重装系统后,出现屏幕亮度最高且无法调整、电脑字体变小等问题的解决方法~
479 1
笔记本电脑亮度调整无效、字体大小改变的解决方案
|
编译器 API 图形学
【unity细节】基于unity子对象(如相机)为什么无法进行z轴的拖拽移动和z轴自动归位的问题
【unity细节】基于unity子对象(如相机)为什么无法进行z轴的拖拽移动和z轴自动归位的问题
151 0
|
开发工具 开发者
在屏幕的任意位置拖拽,控制精灵移动
在屏幕的任意位置按住拖拽,然后控制屏幕中指定的精灵移动,这个前几天@stack发过一个示例,刚好最近又有几位同学来问,说是看不懂其中的逻辑。索性就在这里详细的讲一下,原理很简单,理解透了原理,其中的积木逻辑也就很容易理解了。
109 0
iOS-横竖屏管理,支持所有方向旋转时用代码控制允许旋转&不允许旋转
iOS-横竖屏管理,支持所有方向旋转时用代码控制允许旋转&不允许旋转
221 0
简简单单修改游戏对象的材质颜色,一起来看看(Unity3D)
前段时间比较忙,好久没更新博客了,感觉技术都下降了,还是要坚持输出呀。 孔子曰:&quot;学而不思则罔,思而不学则殆&quot;,不能光学习,还要学会思考,要能用起来。 将自己学到的东西记录下来,这样会让学习更加有效。
|
图形学 索引
Unity 之 查找游戏物体的几种方式解析
一篇小白也能看懂的查找游戏物体的方式解析 -- Unity 之 查找物体的几种方式。
1681 0
Unity 之 查找游戏物体的几种方式解析