For something completely different.

For a recent side project in Unity, I was trying to find out if certain game objects were seen by the main camera.

To sum up what I was trying to do, I wanted to have enemies able to be highlighted (using a basic outline shader) if they were on screen with the player.  This meant finding if they were on screen with the player, collecting their game objects into a list and cycling through that list to change which enemy is the current target for an attack.

My initial research led me to OnBecameVisible() and it’s opposite, OnBecameInvisible().  This is supposed to tell the renderer when the object comes on screen, or any part of it, including it’s shadow, and needs to be rendered.  What sounded good on paper failed to work in reality.  One drawback is that it is hard to test in the Unity editor because the editor camera also affects the outcome (allegedly).  I say allegedly because I could not get it to work regardless.

What I ended up relying on were two GeometryUnity functions.  CalculateFrustrumPlanes and TestPlanesAABB.

On the script for the object I wanted to test, I used these variables:

private Plane[] planes;
public Camera cam;
private Collider coll;

The main camera is dragged onto the Camera slot in the inspector, although, with a prefab, it might need to be coded directly into the Start() function, where I used this piece of code to access the collider.

coll = GetComponent<Collider>();

In Update(), because the camera is moving with the player, I needed to constantly tell the script what is planes[] were using:

planes = GeometryUtility.CalculateFrustumPlanes(cam);

The script would then announce that it was visible by referring to an external bool function:

if(IsVisible()) {..//insert mad code here//..}

This was a very simple function that returned true when the collider could be “seen” by the main camera and false when it couldn’t.

bool IsVisible()
return GeometryUtility.TestPlanesAABB(planes,coll.bounds);

This code was used for a prototype to prove that I could implement this mechanic, although after implementing it, I realised that it was rather boring for the purpose I had envisaged and will likely be scrapped.  One of the rules of Game Design is that you have to be prepared to “kill” your children.  As a father, I find this is a horrible metaphor, but true still the same.

My main concern with this current layout was if, in the long run, the amount of processing and garbage generated would have been worth knowing what was visible.  In my thinking, it couldn’t be worse than having a raycast every frame to tell if the player is grounded, or not.

I am posting this in case I have to revisit the concept in the future (3 strokes plays havoc with the short term memory) and if anyone else needs to know a working way to detect if something is currently on screen.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s