I just want to share some of the fun that can be had with the extremely powerful EventDelegate system in NGUI and propose a few tweaks to help it along.
The power of EventDelegate events in NGUI comes from the ease created by simply wiring events in the editor versus having to handle them via code. I heartily recommend using the various events exposed on the NGUI stock controls.
I find that I create many simple
public void MethodName() {...} methods that can be the target of these events. Simple additions, like
SetUnchecked() and
SetChecked() can then be easy to wire up to events. What would make this more powerful would be a way to put static parameter values in the editor (see the EventDelegate Wireup.png attached image). PlayMaker does something similar with the ability to add references and static values.
The next level was reached when I started creating my own
List<EventDelegate> events from my own classes. This then opens up a very easy method to add my own events to my game and even extend NGUI's base classes.
EDIT: The below already exists as EventDelegate.Execute(List<EventDelegate>).
My first recommendation is to add to EventDelegate.cs a static Process() function. I created my own pseudo-extension method for the same and it means not writing the processing code for events ever again.
EventDelegateProcessor.cs
using System.Collections.Generic;
public static class EventDelegateProcessor
{
public static void Process(List<EventDelegate> eventDelegate)
{
List<EventDelegate> mTemp = null;
if (eventDelegate != null)
{
mTemp = eventDelegate;
eventDelegate = new List<EventDelegate>();
// Notify the listener delegates
EventDelegate.Execute(mTemp);
// Re-add the previous persistent delegates
for (int i = 0; i < mTemp.Count; ++i)
{
EventDelegate ed = mTemp;
if (ed != null && !ed.oneShot) EventDelegate.Add(eventDelegate, ed, ed.oneShot);
}
mTemp = null;
}
}
}
As an example that illustrates the above, here are some simple classes of mine that decorate
UIToggle with both types of extra functionality: granular void event target methods and custom events. (Freyja is the dev name for my project.)
FreyjaToggle.csusing UnityEngine;
using System.Collections.Generic;
public class FreyjaToggle : MonoBehaviour
{
private UIToggle _uiToggle;
[HideInInspector]
public List
<EventDelegate
> onToggleTrue
= new List
<EventDelegate
>();
[HideInInspector]
public List
<EventDelegate
> onToggleFalse
= new List
<EventDelegate
>();
public void Start()
{
_uiToggle = gameObject.GetComponent<UIToggle>();
EventDelegate.Add(_uiToggle.onChange, OnToggleChanged, false);
}
private void OnToggleChanged()
{
if (_uiToggle.value)
EventDelegateProcessor.Process(onToggleTrue);
else
EventDelegateProcessor.Process(onToggleFalse);
}
public void SetValue(bool isChecked)
{ _uiToggle.value = isChecked; }
public void SetChecked()
{ SetValue(true); }
public void SetUnchecked()
{ SetValue(false); }
public void ToggleState()
{ _uiToggle.value = !_uiToggle.value; }
}
FreyjaToggleEditor.cs:
located in an \Editor folderusing UnityEngine;
using UnityEditor;
[CustomEditor
(typeof(FreyjaToggle
))] public class FreyjaToggleEditor : Editor
{
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
FreyjaToggle ft = target as FreyjaToggle;
NGUIEditorTools.DrawEvents("On Toggle True", ft, ft.onToggleTrue);
NGUIEditorTools.DrawEvents("On Toggle False", ft, ft.onToggleFalse);
}
}
I hope this helps somebody!!