-
Notifications
You must be signed in to change notification settings - Fork 0
GlobalEvents
Global Events are functionalities which affect many objects and occur throughout the entirity of the game.
For example, take an alarm system. An alarm can be considered a global event - it can affect enemy AI, doors, a time constraint, etc. Instead of introducing the alarm system as a dependency for each object, we can decouple the alarm system and subscribe when an alarm activates to other components. This introduces a relationship between the alarm and the AI, doors, and a timer system without having a hard dependency.
Each system can define how they're affected in a generic manner and can be subscribed.
The Global Event System uses Delegates
for method subscription, unsubscription, and invocations. Delegates
in C# work like function pointers found commonly in C/C++. You can read more about Delegates on the MSDN
page.
The GlobalEventHandler
contains a global event table which allows any void
method with 0 to 4 arguments to
be subscribed.
Once subscribed, another instance can invoke the subscribed method. Take the alarm system as an example.
Note: All instances which subscribed to the GlobalEventHandler will get invoked. So, if you have a duplicated alarm system then every alarm system will be activated with no guarenteed order. This is a limitation of a global event system.
using GlobalEvents; // Use the GlobalEvents namespace
using UnityEngine;
using UnityEngine.AI;
public class EnemyAI : MonoBehaviour {
private NavMeshAgent agent;
private void OnEnable() {
// Subscribe the event
GlobalEventHandler.SubscribeEvent("MoveToAlarm", MoveTo);
}
private void OnDisable() {
// Unsubscribe the event
GlobalEventHandler.UnsubscribeEvent("MoveToAlarm", MoveTo);
}
private void Start() {
agent = GetComponent<NavMeshAgent>();
}
// Move the agent to a position and invoke this method.
private void MoveTo(Vector3 position) {
agent.SetDestination(position);
}
}
public class AlarmSystem: MonoBehaviour {
public Transform playerTransform;
private bool isActive;
private void Start() {
isActive = false;
playerTransform = GameObject.FindGameObjectWithTag("Player");
}
private void Update() {
// If the player is within 5 meters of the alarm
if (Vector3.Distance(playerTransform.position, transform.position) < 5f) {
if (!isActive) {
// Invoke the GlobalEventHandler and pass the position of the alarm as an argument
GlobalEventHandler.InvokeEvent("MoveToAlarm", transform.position);
}
}
}
}