UnityEvent invocation cancelled when re-invoked within callback

I’ve got a bunch of objects which use a UnityEvent to signal when their state has changed. In some cases, a change in one such object can trigger a change in another such object, causing it to invoke the same UnityEvent.

I have found that when this happens, the first invocation does not reliably complete. Specifically, any callbacks which should be called after the one which causes the UnityEvent to be re-invoked do not get called.

I at first assumed that I had an issue in my code and simply wasn’t handling the callbacks properly. After investigating this for a while I swapped the UnityEvent for a standard C# delegate, though, and the code worked exactly as intended - the state changes propagated as desired and other objects were also able to hook into the callbacks.

Is this a limitation in UnityEvent? A bug?

Specifically what I’m seeing is this:
I have objects A and B and C which are all listening for UnityEvent E. A invokes E (lets call this ‘E(A)’), which calls a function in B. In executing that function, B also invokes E (lets call this ‘E(B)’). E(B) calls functions in both A and C as expected. However, E(A) never calls C as expected.

In the above case A and B are of the same type, C is a different type, and E is a UnityEvent that belongs to a different class.

Sounds like a limitation to me, like the events track the objects that haven’t been called yet, so they end up refreshing and wiping the records when called again. So no recursion for you.

1 Like

Yes, that’s my impression, too.

Events hooked up in code are different from events hooked up in the inspector. Does this issue you’re describing apply to both, or just one (and if so, which)?

That use case is stuff dynamically hooked up in code.

I would call it a bug.

If it was a deliberate safety net to prevent a UnityEvent calling itself in an infinite loop then it should throw an error rather then simply do nothing.

1 Like

Presumably it’s the unintended consequence of state. If you wanted to preserve the call stack, you would have to create a new instance of the UnityEvent for each call, so then each level of the stack tracks each call’s state independently. But since a UnityEvent is one object, it only has one state that all levels of the stack are acting from.

At the very least, it’s safe to say recursion wasn’t an expected use case for UEs.

1 Like

Propagating changes in this manner is not an uncommon use for events, though.