Важно отметить, что Renderer.isVisible может возвращать true по причинам, отличным от прямой видимости, ie. тень. Это прокомментировано в документах Unity3D: https://docs.unity3d.com/ScriptReference/Renderer-isVisible.html
Существующий код, который вы используете для хорошей первой проверки, чтобы отфильтровать объекты, которые могут быть быстро определены как невидимые (особенно проверка Frustum). Но когда эти проверки возвращаются видимыми, вам может потребоваться выполнить дополнительные проверки, чтобы убедиться, что объект действительно виден. Для этого вы, вероятно, захотите выполнить серию лучевых трансляций.
Однако вы не сможете просто сделать лучевую трансляцию прямо в центре каждого персонажа, потому что персонаж может быть частично закрыт. В зависимости от потребностей вашей программы, я бы порекомендовал лучевую передачу по центру и всем 8 углам ограничительной рамки объекта. (Если ваши персонажи были завернуты в коробочный коллайдер, вы можете использовать это для своих углов.) Возможно, вам придется сделать больше, если вам нужно обнаружить видимость с помощью маленьких windows или любых других.
RaycastHit hit;
//Do we hit any geometry?
Physics.Raycast(cameraOrigin, targetPoint, out hit, maxDistance, layermask);
Если у вас есть collider
, который полностью охватывает ваших персонажей, это будет легко проверить, используя hit.collider
.
https://docs.unity3d.com/ScriptReference/Physics.Raycast.html