- Home /
Unity Events in Execute In Edit Mode
So I have a script that I want to execute in edit mode. The script works fine inside of play mode. I'm triggering a unity event in the update loop of execute in edit mode, but no event is being raised it seems. Is this expected behavior?
[ExecuteInEditMode]
public class CardManager : UIBehaviour
{
/// <summary>
/// Triggered when the loot item has changed.
/// </summary>
[SerializeField]
private LootItemDataEvent _onLootItemAssigned = null;
private void Update()
{
// If the previous item does not match the current then we've switch items and should trigger the event
if (_lootItem == _previousLootItem)
{
return;
}
Debug.Log("Switch!");
_previousLootItem = _lootItem;
_onLootItemAssigned.Invoke(_lootItem);
}
}
So there is clearly more to the code that I posted above, but this gives the quickest example of what I'm seeing. The "LootItemDataEvent" is just a custom unity event, I'll paste the code below in case there is an issue there.
namespace Meta.Event
{
using System;
using Loot;
using UnityEngine.Events;
/// <summary>
/// Allows a unity event to send loot item data with it.
/// </summary>
/// <seealso cref="UnityEngine.Events.UnityEvent{LootItemData}" />
[Serializable]
public class LootItemDataEvent : UnityEvent<LootItemData>
{ }
}
Thanks in advance!
Answer by JoshDangIt · Jul 14, 2016 at 05:37 PM
Are you editing the UnityEvent in the inspector? If so, all you have to do is change the "Runtime Only" parameter to "Editor And Runtime".
Well, don't I feel foolish. I will say that my method did work, but this is definitely the route to go. Thank you for posting and saving me from myself.
I was searching for a GetPersistentEventCount & Get$$anonymous$$ethod() (like @nerull22), but this method is... really obvious :D
Answer by Nerull22 · Jul 14, 2016 at 02:28 PM
So I left this up for anyone to answer instead of myself as I don't really like answering my own question on a forum. But since there was absolutely no replies or answers provided, I'll do it in case someone runs across this again. I don't know if this is by design on Unity's part or not, but I have a workaround. See the code below.
#if UNITY_EDITOR
/// <summary>
/// Called once per frame.
/// </summary>
private void Update()
{
// Do not run this while playing
if (Application.isPlaying)
{
return;
}
// If the previous item does not match the current then we've switch items and should trigger the event
if (_lootItem == _previousLootItem)
{
return;
}
_previousLootItem = _lootItem;
for (int i = 0; i < _onLootItemAssigned.GetPersistentEventCount(); i++)
{
_onLootItemAssigned.GetPersistentTarget(i)
.GetType()
.GetMethod(_onLootItemAssigned.GetPersistentMethodName(i))
.Invoke(_onLootItemAssigned.GetPersistentTarget(i), new object[] {_lootItem});
}
}
#endif
So this section is only for in the editor to use. I still call normal invokes on the object while the game is running in the editor or in deployment.
Basically it's just using a for loop to go through all the registered targets with the method on the event and is manually triggering them one by one using reflection. Not super ideal, but is functional.