Skip to content

Instantly share code, notes, and snippets.

@lordlycastle
Last active January 9, 2020 17:40
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Embed
What would you like to do?
Allows us to copy over persistent actions in UnityEvent from script which show up in inspector.
/// <summary>
/// Allows us to copy over persistent actions in UnityEvent from script which show up in inspector.
/// <remarks>Currently only works for void methods.</remarks>
/// </summary>
/// <example>
/// Copy over event in editor script when button is pressed and save changes.
/// <code>
/// CopyUnityEvent(airTapButton.OnTapDown, interactableScriptEvents.OnPress, false);
/// EditorUtility.SetDirty(interactableScriptEvents);
/// </code>
/// </example>
/// <param name="oldEvent">Old event to copy from</param>
/// <param name="newEvent">New event to copy over to</param>
/// <param name="overwrite">Overwrite the existing listeners</param>
// todo: Add support for figuring out argument types for the methods so we can add non-void listeners. EventTool does have support to add it. Issues: 1. Find correct target MonoBehaviour. 2. Find argument type. 3. Find argument value set in inspector.
private void CopyUnityEvent(UnityEngine.Events.UnityEvent oldEvent, UnityEngine.Events.UnityEvent newEvent, bool overwrite = false)
{
for (int i = 0; i < oldEvent.GetPersistentEventCount(); i++)
{
var methodTarget = oldEvent.GetPersistentTarget(i);
var methodName = oldEvent.GetPersistentMethodName(i);
try
{
var execute =
Delegate.CreateDelegate(typeof(UnityAction), methodTarget, methodName) as
UnityAction;
if (overwrite == false)
{
UnityEditor.Events.UnityEventTools.AddVoidPersistentListener(newEvent, execute);
}
else
{
if (i >= newEvent.GetPersistentEventCount())
{
UnityEditor.Events.UnityEventTools.AddVoidPersistentListener(newEvent, execute);
}
else
{
UnityEditor.Events.UnityEventTools.RegisterVoidPersistentListener(newEvent, i, execute);
}
}
UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty(
((InteractableScriptEvents)target).gameObject.scene);
}
catch (Exception exp)
{
Debug.LogError(
$"Could not bind method: {methodName}, target: {target.name}. Probably because it isn't a void method. Exceptions: {exp}");
continue;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment