Reputation: 11
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;
}
Upvotes: 0
Views: 2554
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
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