I want to use the new UnityEvents to broadcast global game events, but examples of how to do this and my knowledge of the new system are very limited at the moment. I think the best way to do this is by re-creating the “Event Trigger” script, but with my own custom events. After looking at the UI source code I now know how to create my own version with custom events like so:
Custom Interface and Event:
using UnityEngine;
using UnityEngine.EventSystems;
// interface you implement in your MB to receive events
public interface IGameStartHandler : IEventSystemHandler
{
void OnGameStart (GameStartData eventData);
}
// Custom data we will send via the event system
public class GameStartData : BaseEventData
{
public string m_GameStartData;
public GameStartData(EventSystem eventSystem, string data)
: base(eventSystem)
{
m_GameStartData = data;
}
}
// container class that holds the execution logic
// called by the event system to delecate the call to
// the intercea
public static class GameStartEvents
{
// call that does the mapping
private static void Execute(IGameStartHandler handler, BaseEventData eventData)
{
// The ValidateEventData makes sure the passed event data is of the correct type
handler.OnGameStart (ExecuteEvents.ValidateEventData<GameStartData> (eventData));
}
// helper to return the functor that should be invoked
public static ExecuteEvents.EventFunction<IGameStartHandler> GameStartEventHandler
{
get { return Execute; }
}
}
Custom “Trigger Event” like script to setup listener object events
using System;
using System.Collections.Generic;
using UnityEngine.Events;
namespace UnityEngine.EventSystems
{
public class CustomTrigger :
MonoBehaviour,
IGameStartHandler
{
public enum EventType
{
GameStart = 0,
GameEnd = 1
}
[Serializable]
public class TriggerEvent : UnityEvent<BaseEventData>
{ }
[Serializable]
public class Entry
{
public EventType eventID = EventType.GameStart;
public TriggerEvent callback = new TriggerEvent();
}
public List<Entry> delegates;
protected CustomTrigger()
{ }
private void Execute(EventType id, BaseEventData eventData)
{
if (delegates != null)
{
for (int i = 0, imax = delegates.Count; i < imax; ++i)
{
var ent = delegates[i];
if (ent.eventID == id && ent.callback != null)
ent.callback.Invoke(eventData);
}
}
}
public virtual void OnGameStart(GameStartData eventData)
{
Execute(EventType.GameStart, eventData);
}
}
}
However, I’m stuck on how exactly I’m supposed to go about sending the event to each listener automatically through a method. The only example I’ve found is for a custom input module that sends the events to a list of objects:
//Custom input module that can send the events
public class MyInputModule : BaseInputModule
{
// list of objects to invoke on
public GameObject[] m_TargetObjects;
// called each tick on active input module
public override void Process()
{
// if we don't have targets return
if (m_TargetObjects == null || m_TargetObjects.Length == 0)
return;
// for each target invoke our custom event
foreach (var target in m_TargetObjects)
ExecuteEvents.Execute (target, new GameStartData (eventSystem, "Game Start Data"), GameStartEvents.GameStartEventHandler);
}
}
But I just want to call the event on all listeners form a method, like with a C# event:
if(OnGameStart != null)
OnGameStart();
I have to admit I’m in over my head here and having a hard time wrapping my brain around all this code. Am I going about this completely wrong? Any suggestions or advice would be greatly appreciated.