I am working on a project in Unity 2018.4 that has to be exported as an Asset Bundle so I’m fairly restricted in what can be done. I need to add a whole lot of function callback to a whole lot of UnityEvents, and I’d rather not do it by hand, so I’m wondering if it can be done using code.
I want events to set the text property of a Text UI component, so the result should be like this after running the script in Edit Mode:
Using another function as the callback function that sets the property is not an option due to the restrictions.
So far I have come up with the following code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;
using UnityEngine;
using Klak.Wiring;
using UnityEditor.Events;
using UnityEngine.Events;
using UnityEditor.Profiling;
using System;
using System.Reflection;
public class PrintAdder : MonoBehaviour
{
public GameObject[] NotePatches = new GameObject[18];
public GameObject[] Modes = new GameObject[4];
public bool execute = false;
static string[] modeStepsArr = { "I (1)", "II (1)", "III (1)", "IV (1)", "V (1)", "VI (1)", "VII (1)"};
static string[] stepsArr = { "I", "II", "III", "IV", "V", "VI", "VII"};
[ExecuteInEditMode]
public void AddListeners()
{
if (execute)
{
foreach (var note in NotePatches)
{
int stepCount = 0;
foreach (var step in stepsArr)
{
GameObject stepNode = note.transform.FindChild(step).gameObject;
EventOut eventOut = stepNode.GetComponent<EventOut>();
foreach (var mode in Modes)
{
GameObject modeStep = mode.transform.FindChild(modeStepsArr[stepCount]).gameObject;
EventOut stepNodeEventOut = stepNode.GetComponent<EventOut>();
Text modeStepText = modeStep.GetComponent<Text>();
eventOut._event.AddListener(() => modeStepText.text = note.name);
// DOES NOT WORK
//UnityEventTools.AddVoidPersistentListener(eventOut._event, () => modeStepText.text = note.name);
}
stepCount++;
}
}
execute = false;
}
}
}
This has the desired result in terms of functionality after running it during runtime, but I need the listeners to be persistent. I tried the commented out line but unfortunatly that doesn’t work.
To add the PersistentListener I assume I need to create a UnityAction, but I have no idea how to pass a value to the text property’s setter nor how to link it to a VoidEvent.
Any help is greatly appreciated.
For completeness, this is the EventOut component.
namespace Klak.Wiring
{
[AddComponentMenu("Klak/Wiring/Output/Generic/Event Out")]
public class EventOut : NodeBase
{
#region Editable properties
[SerializeField]
public VoidEvent _event;
#endregion
#region Node I/O
[Inlet]
public void Bang()
{
_event.Invoke();
}
#endregion
}
}
And this is the VoidEvent:
[Serializable]
public class VoidEvent : UnityEvent {}