Using Listeners for Sequences and Different Classes

I have three classes of C# things. One is a PuzzleController, another is a CameraGlide, and the last is a CameraRotate. Just a quick summary of what the 3 classes are. Controller has all the puzzle variables, trigger actions, stuff to send to UI, and controls what state the puzzle is in. CameraGlide moves the camera from one point to another while looking at a point. CameraRotate allows the player to mouse drag the mouse around a point and zoom in/out.


What I want to do is this:

-Player walks into trigger

-Camera disables 3rdPersonCamera

-Camera glides from behind player to predetermined puzzle location

-Tells the Controller when the camera has reached the puzzle position

-PuzzleController turns off the glide and turns on the Rotate


-Player out of trigger

-Turn off CameraRotate

-CameraGlides from where it is to the player

-Tells the controller when the camera has reached the player position

-Turn back on 3rdPersonCamera


The problem is the sequence of events. CameraGlide and CameraRotate should be PuzzleController agnostic (there different classes of controllers at different levels). So I don’t want to hard code anything into Glide Update() something like:

“if(at_loc) Puz_Con_A.glideDone()”.

Because now this Glide class only works with the one type of controller. Similarly I don’t want a constantly running update in the PuzzleController checking the status of the Glide like:

“if(glide.at_loc =true)”.

Since this would be constantly checking when it only needs to be when the player has triggered the puzzle.

Ideally I want to use some kind of Delegate/Listener that any PuzzleController can add to their own code so that when it triggers it tells the CameraGlide, and listens for CameraGlide to send back that it’s at the location. The problem is I’m terrible at Listeners and I’m not sure how to add it while keeping CameraGlide and CameraRotate agnostic.

You definitely might want to check out UnityEvents, as of right now you are going in a direction in which every class will have to know about each other just to subscribe to some events, and by using UnityEvents they won’t have to know about each other and your code can stay clean.
e.g. you said there is a trigger so let’s assume this class:

using UnityEngine;
using UnityEngine.Events;  // important to use UnityEvents

class Trigger : MonoBehaviour
{
       // ...
       [SerializeField] private UnityEvent _OnPlayerEnter = null;

       private void OnTriggerEnter( Collision col )  // or whatever you want
       {
              Player p;
              // ... your logic for player checking or whatever ...
              _OnPlayerEnter?.Invoke(); // call the event - the player entered
       }
}

Then you can subscribe various stuff to the event and have everything smoothly organised.
UnityEvents can handle:

  • No parameter public methods
  • Public methods with 1 parameter
  • Setting a public field to a given value

Using them is pretty intuitive, so I bet you’ll get the hang of it. Good luck!