Help sending variables between scripts

Hey everybody, first post on the forums. I’m sorry, this is way longer than I hoped but I’ve been beating my head on this problem for a while.

I have a LookableObject script that causes the Sphere game object it’s on to turn green when the player’s first person camera is looking at it, and blue when you look away from it. Here’s the beginning of the important function, with some stuff summarized for you:

void CheckIfLooking()
{
sightPlanes = GeometryUtility.CalculateFrustumPlanes(cam);

if (GeometryUtility.TestPlanesAABB(sightPlanes, lookableCollider.bounds))
{
RaycastHit hit;
Physics.Linecast(cam.transform.position, transform.position, out hit);

// Decide whether the spheres are seen by the camera based on
// TestPlanesAABB and the raycast hit info, set them to green when
// they're in view and blue when they're not.
}

This is called in Update(). For the most part the script works pretty great. You look at the spheres, you see green spheres - the change is really quick and it is impossible to “catch” a sphere before it turns green and see its blue color, no matter how quickly you whip the mouse around. You have to look at them in the editor to see them at all in their unseen, blue state.

Since this script is on each instance of the color-changing object, every frame, each one of those Spheres is calculating the camera frustum every frame. I thought this seemed redundant and I wanted more flexibility in my code anyway so I started breaking the script down to be more modular. Now I have a PlayerSight script on the camera’s game object to do the frustum stuff, so that only has to calculated once per frame:

public class PlayerSight : MonoBehaviour
{
public static Plane[] sightPlanes;

private Camera cam;


void Awake()
{
cam = GetComponent<Camera>();
sightPlanes = GeometryUtility.CalculateFrustumPlanes(cam);
}

void Update()
{
CalculatePlayerSight();
}


void CalculatePlayerSight()
{
sightPlanes = GeometryUtility.CalculateFrustumPlanes(cam);
}
}

And the new LookableObject script skips calculating the frustum, and instead grabs sightPlanes from PlayerSight like this:

if (GeometryUtility.TestPlanesAABB(PlayerSight.sightPlanes, lookableCollider.bounds))

This also sorta works, but instead of being faster it seems to be slower. When looking around you see glimpses of the blue spheres for a couple frames before they turn green. It can’t keep up and it breaks the illusion.

My suspicion is that pulling the static variable sightPlanes from another script on another game object is slowing this down. But I do want to make the scripts more modular so it’s easier to do interesting things with them later. How can I get around this? What are best practices for communication between different objects?

Thanks to anybody who read this! :hushed:

Simply getting variables from other scripts does not slow down your game. Since you can see the blue spheres for a moment, could it be your PlayerSight.Update is called before the CheckIfLooking, causing it to get the correct value only on the next frame?

Try changing your PlayerSight script to use LateUpdate instead of Update.

Thanks! You definitely got my thinking on the right track. I eventually got it to work but I don’t really know how.

I’m now calling CalculatePlayerSight() in Update(), which calculates the frustum planes, then calling CheckIfLooking() in LateUpdate(), which checks whether the object is inside the planes and sets the “looking” variable, and then I call the color changing function inside CheckIfLooking() instead of alongside it in LateUpdate().

It didn’t work right away though, it seemed to work for no reason after I restarted my computer so I don’t know exactly why it started working. But I guess I’ll take it :wink:

Why are calculating the frustum of the camera? You can just call IsVisible and you are done (I think it was in the renderer). Then set the color.

IsVisible triggers when the object is rendered for any reason, so for example if it’s casting a shadow into the camera’s view it needs to be rendered for that. So I’d end up triggering it even when I don’t want to.