Nero8Eye
Nero8Eye

Reputation: 11

Unity C# Check if GameObject is not visible for cam PROBLEM

I have a AimBot script that check how many enemy on the level, if they in a specifity Range and now if they are visible from cam. I have found this two codes but both say that the enemy behind a wall is visible. Sorry for bad english ^^

Code1

    //https://answers.unity.com/questions/8003/how-can-i-know-if-a-gameobject-is-seen-by-a-partic.html
    bool IsTargetVisibleV1(Camera c, GameObject go)
    {
        var planes = GeometryUtility.CalculateFrustumPlanes(c);
        var point = go.transform.position;
        foreach (var plane in planes)
        {
            if (plane.GetDistanceToPoint(point) < 0)
                return false;
        }
        return true;
    }

Code 2

    bool IsTargetVisibleV2(Camera cam,Renderer[] ren)
    {
        foreach (Renderer renderer in ren)
        {
            if (renderer.isVisible)
            {
                return true;
            }
        }
        return false;
    }

Player_Cam Minimap_Cam

Upvotes: 0

Views: 2554

Answers (2)

avariant
avariant

Reputation: 2300

It's important to note that Renderer.isVisible may return true for reasons other than direct visibility, ie. shadows. That is commented on in the Unity3D docs: https://docs.unity3d.com/ScriptReference/Renderer-isVisible.html

The existing code that you have makes for a good first check, to filter out the objects that can be quickly determined as not visible (the frustum check especially). But when those checks return visible, you may need to perform additional checks to ensure the object is truly visible. For that, you probably want to perform a series of raycasts.

However, you won't just be able to do a raycast straight at the center of each character because a character might be partially occluded. Depending on the needs of your program, I would recommend raycasting against the center and all 8 corners of the object's bounding box. (If you characters were wrapped in a box collider, you could make use of that for your corners.) You may need to do more than that if you need to detect visibility through small windows or whatever.

RaycastHit hit;
//Do we hit any geometry?
Physics.Raycast(cameraOrigin, targetPoint, out hit, maxDistance, layermask);

If you have a collider that fully encompasses your characters, that would be an easy check using hit.collider.

https://docs.unity3d.com/ScriptReference/Physics.Raycast.html

Upvotes: 1

LLSv2.0
LLSv2.0

Reputation: 543

In the first code example, you are checking if the game object is less than 0 units away from either view plane. This only checks if an object is "behind" a plane.

renderer.isVisible will return true if the MeshRender needs to be rendered. In your example, the enemies are not entirely covered up by the wall, so they do need to be rendered. This approach should work in the case that they are entirely obscured however.

I think you should check isVisible to find if the object is in a camera view at all. then if you are counting partial cover as cover, perform ray casts to check for objects that are rendered but are partially covered.

Upvotes: 0

Related Questions