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

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

  • 相关阅读:
    BZOJ 3744 Gty的妹子序列
    BZOJ 3872 Ant colony
    BZOJ 1087 互不侵犯
    BZOJ 1070 修车
    BZOJ 2654 tree
    BZOJ 3243 向量内积
    1003 NOIP 模拟赛Day2 城市建设
    CF865D Buy Low Sell High
    CF444A DZY Loves Physics
    Luogu 4310 绝世好题
  • 原文地址:https://www.cnblogs.com/jiahuafu/p/6734174.html
Copyright © 2011-2022 走看看