zoukankan      html  css  js  c++  java
  • 判断游戏对象是否在摄像机视口的一个方法

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

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

  • 相关阅读:
    第三次随笔作业
    第二次随笔作业
    第一次随笔
    第四次随笔作业
    第三次随笔作业
    第二次随笔作业
    第一次博客
    第四次作业
    第三次作业(2)
    第二次随笔(修改版3)
  • 原文地址:https://www.cnblogs.com/jiahuafu/p/6734174.html
Copyright © 2011-2022 走看看