0
\$\begingroup\$

I'm working on a script that uses raycasting from the camera's perspective to see what the player is looking at. Pretty standard stuff. The only question is, how to reliably find the camera?

Everything I've seen says you don't want to use Camera.main in Update() because performance, so instead you should call it once in Start() and cache it in a field. And that's great, as long as you can guarantee that the main camera will never change. But what if it does?

What I'd like is to have some sort of OnCameraUpdated event I can subscribe to that will let me know when the main camera has changed, but I don't see anything like that on the Camera class. Is there any good way to find this out without polling for it?

\$\endgroup\$
  • 1
    \$\begingroup\$ What in your game changes the camera? That's a great place to fire an OnCameraChanged event as you describe. \$\endgroup\$ – DMGregory Apr 20 at 23:12
  • \$\begingroup\$ @DMGregory That's the point. I'm not writing the game; I'm writing a script that doesn't have knowledge of the game. Something that's supposed to be an independent library. \$\endgroup\$ – Mason Wheeler Apr 21 at 11:00
1
\$\begingroup\$

If you can't rely on the code that's changing the camera to tell you, then about the best you can do is check to see if your cached camera has been disabled/destroyed, and trigger a new search only when that happens:

static Camera _cachedCurrentCamera;

void Update() {
    if(_cachedCamera == null || _cachedCamera.isActiveAndEnabled == false)
        _cachedCurrentCamera = Camera.main;
}

But you can expose a camera changed event handler of your own, for game code to call when they change the camera, if they want to avoid any searches at all. Then the ball is in their court to control their own performance, even if you can't force them to use it:

public static void OnCameraChanged(Camera newCamera) {
    _cachedCurrentCamera = newCamera;
}
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Well that's disappointing. The Scene Manager provides events to notify scripts when the scene has changed; I wonder why there's no similar thing for cameras. \$\endgroup\$ – Mason Wheeler Apr 21 at 14:10
  • \$\begingroup\$ You could try implementing the OnWillRenderObject message, with a dummy renderer set up so that it's always visible/never culled, but that seems even more hacky, and liable to break if there are other non-player cameras in the scene. \$\endgroup\$ – DMGregory Apr 21 at 14:14
  • \$\begingroup\$ You could also make it the convention of your library that this script sits on the camera it uses for its perspective, so then it enables/disables along with the camera. Your script can cache its local camera then never change that value. It becomes the user's responsibility to place a copy of this script on each camera they want to use, and coordinate swapping which instance to reference when they switch cameras. \$\endgroup\$ – DMGregory Apr 21 at 14:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.