How to detect all GameObjects within the Camera FOV? Unity3D

僤鯓⒐⒋嵵緔 提交于 2019-12-06 09:53:48
COBO

Using Draco18s' answer, below is how to implement what he said.

Create a new Script and name it CheckWalls and attach the below code

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CheckWalls : MonoBehaviour
{
    Renderer[] renderers;

    void Awake ()
    {
        GameObject walls = GameObject.FindGameObjectWithTag ("Wall");
        renderers = walls.GetComponentsInChildren<Renderer> ();
    }

    void Update() 
    {
        OutputVisibleRenderers(renderers);
    }

    void OutputVisibleRenderers (Renderer[] renderers)
    {
        foreach (var renderer in renderers)
        {
            // output only the visible renderers' name
            if (IsVisible(renderer)) 
            {
                Debug.Log (renderer.name + " is detected!");    
            }           
        }

        Debug.Log ("--------------------------------------------------");
    }

    private bool IsVisible(Renderer renderer) 
    {
        Plane[] planes = GeometryUtility.CalculateFrustumPlanes(Camera.main);

        if (GeometryUtility.TestPlanesAABB(planes , renderer.bounds))
            return true;
        else
            return false;
    }
}

Step 1: Calculate the camera's frustum planes.

Step 2: Test each wall's collider against them, the example script on that page has literally everything you need.

If the object is inside the volume defined by the planes, then its visible to the camera (and TestPlanesAABB(...) returns true), otherwise it is not.

If you want to know if an object is visible from a "camera" (that is, not a camera component, but an object that acts like a security camera, but is not doing any actual rendering) the planes can be computed from an arbitrary point (Vector3), view direction (Vector3), and field of view (a ratio, as a float). I don't have the code I wrote on hand, but can fetch it if needed.

The trick here is whether you want to detect the first visible part of that game object, or if you want to 'detect' it from the object's center.

If you want to do this with the visible part, it might be simpler to attach a script to those objects to check visibility.

If you are okay with "detecting" it once the center is visible, you can do it from the camera.

Either way, the first thing I'd do is use GameObject. FindGameObjectsWithTag. FindGameObjectsWithTag

Then, check Renderer.isVisible for each of them. Renderer is Visible

You could further optimize this by checking to see if the object is behind the camera or not, first, by its transform, before you check the renderer, since that's a more expensive operation.
Is that transform behind me?

And if those don't fix your problem, tell us more about what you ultimately hope to achieve.

Edit: based on your new edit, I'd say you need to use Raycast All instead,

RaycastAll

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!