Need help understanding how to implement Delegate/Event

I have an object (let’s call it zone-object) that changes its boolean property to true if the player is within a certain distance and false when the player isn’t. This object is dotted around my environment. The idea with this is to let the player know what zone they’re in.

In this game object, I am doing this :

public float proximity; // Metres
public GameObject _player;
public bool user_detected = false;

public delegate void DetectionDelegate();
public event DetectionDelegate detectedEvent;

private void Update()
{
    if (Vector3.Distance(_player.transform.position, transform.position) < proximity)
    {
        StartCoroutine(SendAlert());
        Debug.DrawLine(transform.position, _player.transform.position, Color.green);
    }
    else if (Vector3.Distance(_player.transform.position, transform.position) > proximity)
    {
        StartCoroutine(StopAlert());
    }

}

private IEnumerator StopAlert()
{
    if (detectedEvent != null)
    {
        user_detected = false;
    }
    yield return null;
}

private IEnumerator SendAlert()
{
    if (detectedEvent != null)
    {
        user_detected = true;
    }

    yield return null;
}

Now attached to my player object is a script that tries informs the player what zone they’re in. So if one of these zone object detects the player, it should set its boolean to true, and the player should be able to pick up this event and display the area they’re in (currently using the zone object’s name for now).

I just learned about using delegate/events although I am finding it hard to understand how I should write the code. Because I have multiple of these zone objects around the map, how would the player script know which zone object event is active? Would I need to List of some kind and iterate through it?

I’m open for suggestions, even if there is a simpler way to achieve what I’m doing. Bonus points if someone could explain delegates/events in simple english, although I get a general idea what they’re about, I need a simple example of a use case to fully grasp the idea.

Thanks!

Even if events are a powerful in recent programming languages such as C#, you must understand that tools must be used in the situation where they are useful. Using a screwdriver is more efficient than a hammer when dealing with screws :wink:

Here, you don’t need delegates to warn your player he has entered into the zone. But it may be useful to warn other entities which have a direct reference to your zone.

 public float proximity; // Metres
 public PlayerScript player; // Here, drag & drop the script attached to your player

 public bool playerInside = false;

 public delegate void PlayerEnteredEventHandler(PlayerScript p);
 public event PlayerEnteredEventHandler PlayerEnteredEvent;
 public delegate void PlayerLeftEventHandler(PlayerScript p);
 public event PlayerLeftEventHandler PlayerLeftEvent;

 private void Update()
 {
     if (Vector3.Distance(_player.transform.position, transform.position) < proximity && !playerInside)
     {
         playerInside = true;
         player.OnZoneEntered( this ) ;  // Define this function inside the PlayerScript attached to the player : public void OnZoneEntered( Zone zone ) { ... }
         Debug.DrawLine(transform.position, _player.transform.position, Color.green);
         if( PlayerEnteredEvent != null )
             PlayerEnteredEvent.Invoke( player );
     }
     else if (Vector3.Distance(_player.transform.position, transform.position) > proximity && playerInside)
     {
         playerInside = false;
         player.OnZoneLeft( this ); // Define this function inside the PlayerScript attached to the player : public void OnZoneLeft( Zone zone ) { ... }
         if( PlayerLeftEvent != null )
             PlayerLeftEvent.Invoke( player );
     }
 }

Then, we could image you have an other script called Trap interested in the events defined in your Zone script :

public Zone zone ; // Drag & Drop the object holding the Zone script

private void OnEnable()
{
     zone.PlayerEnteredEvent += OnPlayerEnteredZone ;
}

private void OnDisable()
{
     zone.PlayerEnteredEvent -= OnPlayerEnteredZone ;
}

private void OnPlayerEnteredZone(PlayerScript p)
{
      // Trigger an animation for example
      Debug.Log("The player has been captured in my trap! Mouahaha!"); 
}