-
Notifications
You must be signed in to change notification settings - Fork 0
RelativeEvents
Global events are useful when invoking system wide events or an event which must be applied to every entity (e.g. healing every agent in the game).
But, if you want to invoke an event relative to a particular object, you can subscribe an object
with its method signature and event name to the RelativeEventHandler
.
The .NET 3.5 runtime uses reflections to mimic what the GlobalEventHandler
does. The table
consists of an event name as the key series of smaller tables which includes object instances
as keys and a series of subscribed methods.
Subscribed methods are represented as strings. See the table below for an example of how different instances which are subscribed to the same event can register different methods.
Event Name | Object Instance | Method(s) |
---|---|---|
Stop | Alice | "StopAI", "StopAnimator" |
(Same Event) | Bob | "StopAI", "StopAnimator", "StopAudio" |
When an event is invoked given an object instance, only the methods subscribed to that object
will be invoked. For example, if the object Alice
has the subscribed methods, StopAI
, StopAnimator
then only those methods will be invoked.
Likewise, if the event Stop
was invoked on Bob, then StopAi
, StopAnimator
, and StopAudio
will
be invoked.
using GlobalEvents;
using UnityEngine;
using UnityEngine.AI;
// Alice example
public class Alice : MonoBehaviour {
private Animator anim;
private NavMeshAgent agent;
private void OnEnable() {
RelativeEventHandler.Subscribe("Stop", this, "StopAI");
RelativeEventHandler.Subscribe("Stop", this, "StopAnimator");
}
private void OnDisable() {
RelativeEventHandler.Subscribe("Stop", this, "StopAI");
RelativeEventHandler.Subscribe("Stop", this, "StopAnimator");
}
private void Start() {
anim = GetComponent<Animator>();
agent = GetComponent<NavMeshAgent>();
}
private void StopAI() {
agent.isStopped = true;
}
private void StopAnimator() {
anim.SetBool("Stop", true);
}
}
public class Bob: MonoBehaviour {
private Animator anim;
private NavMeshAgent agent;
private AudioSource source;
private void OnEnable() {
RelativeEventHandler.Subscribe("Stop", this, "StopAI");
RelativeEventHandler.Subscribe("Stop", this, "StopAnimator");
RelativeEventHandler.Subscribe("Stop", this, "StopAudio");
}
private void OnDisable() {
RelativeEventHandler.Unsubscribe("Stop", this, "StopAI");
RelativeEventHandler.Unsubscribe("Stop", this, "StopAnimator");
RelativeEventHandler.Unsubscribe("Stop", this, "StopAudio");
}
private void Start() {
anim = GetComponent<Animator>();
agent = GetComponent<NavMeshAgent>();
audio = GetComponent<AudioSource>();
}
private void StopAI() {
agent.isStopped = true;
}
private void StopAnimator() {
anim.SetBool("Stop", true);
}
private void StopAudio() {
source.mute = true;
}
}
To avoid using Reflection
, the RelativeEventHandler
, is a table of objects with their respective events and delegates.
This is only supported in a .NET 4x environment found in Unity 2018.1. It is essentially the same as the .NET 3.5
environment with the following differences:
- Subscribe methods as Delegate/Action<T1..T4>
- Alternatively, lambda expressions can be subscribed
- Overloaded methods must be explicitly subscribed
For a simple example of subscribing relative events, see below.
using GlobalEvents;
using UnityEngine;
using UnityEngine.AI;
public class Alice : MonoBehaviour {
private AudioSource source;
private NavMeshAgent agent;
private void OnEnable() {
// Subscribe the object, the event name, and the method
RelativeEventHandler.SubscribeEvent(this, "Stop", StopAI)
}
private void Start() {
agent = GetComponent<NavMeshAgent>();
source = GetComponent<AudioSource>();
// Or we can replace the explicit method with a lambda expresssion
RelativeEventHandler.SubscribeEvent(this, "Stop", () => {
source.mute = true;
};)
}
// We'll subscribe the method below.
private void StopAI() {
agent.isStopped = true;
}
}
// In another class
public class AlertSystem : MonoBehaviour {
// Assuming we have the instance of Alice stored in a field
public Alice alice;
private void Start() {
// We can invoke the relative methods bound to Alice with an event Stop
RelativeEventHandler.InvokeEvent(alice, "Stop");
}
}
See the scripting api (coming soon) for details on subscription. In the meantime, the branch feature/relative-event-4.5
can be viewed
for specific details of the RelativeEventHandler
.