您的位置:首页 > 其它

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

2017-04-19 16:34 429 查看
本人菜鸟,用了笨方法实现。大家有更好的方法不吝赐教。
就是对游戏对象绘制一个长方体包围盒,然后用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);
}


不过如果是要求全部位于视口内的话,可以借鉴楼主的方法去稍作修改。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐