quot;No Listeners Subscribed to {name} type"); } } public void Subscribe(Action<T> action) { eventAction += action; Debug.Log(quot;{name} listener Subscribed {action.Target}"); } public void Unsubscribe(Action<T> action) { eventAction -= action; Debug.Log(quot;{name} listener Unsubscribed {action.Target}"); } } ``` --- Using the *OnUpdateResourceUI* event as an example: ```csharp public static NarraEvent<int, int> OnUpdateResourceUI = new("OnUpdateResourceUI"); ``` Use in a class - Event Subscribe/Unsubscribe: ```csharp private void OnEnable() { UIEventBus.OnUpdateResourceUI.Subscribe(ResourceDisplay); } private void OnDisable() { UIEventBus.OnUpdateResourceUI.Unsubscribe(ResourceDisplay); } private void ResourceDisplay(int currentResource, int maxResource) { //do stuff } ``` Event Calling ```csharp UIEventBus.OnUpdateResourceUI.RaiseEvent(currentResource, resourcePerTurn); ``` # C# Reference Events I built a system we've dubbed "On" and "Do" events. - "On events" are when something happens and could trigger other events. - "On Take Damage" will be raised when the player takes any damage, but... - "Do events" are hooked into the player script as to bypass any other event calls. - "Do Damage", will not trigger the "On Take Damage event". - This avoids any crazy recursion we'd run into, and allows things like Ex: ```csharp [Serializable] public sealed class CritVampirism : EventHandlerTwoRef<SDamageStats>, IEventHandler { public override string Title => "Crit Vampirism"; public override string Description => "When you land a critical strike heal for 15% of the damage done"; public bool IsEnabled => true; public void Subscribe() { GameplayOnEventBus.OnEnemyTakeDamage.Subscribe(Handle); } public void Unsubscribe() { GameplayOnEventBus.OnEnemyTakeDamage.Unsubscribe(Handle); } protected override void Handle(ref SDamageStats originalData, ref SDamageStats modifiedData) { if (originalData.damageFlag == EDamageFlag.CRIT && originalData.attacker is PlayerBase) { Resolve(ref originalData, ref modifiedData); } } protected override void Resolve(ref SDamageStats originalData, ref SDamageStats modifiedData) { int value = (int)Math.Round(originalData.Damage * .15f); SDamageStats healing = new() { Damage = value, damageType = StaticReferenceManager.GetDamageType("healing"), damageFlag = EDamageFlag.NONE }; GameplayDoEventBus.DoPlayerHeal.RaiseEvent(healing); } } ```