C# Events Not Executing Some Code

Greetings,

In my app, I was trying to get an object to be active within the function that is attached to a c# event (e.g. via +=). However, the code would not execute when the event was fired. I checked and the function was being called in response to the event, but the set active code was either not executing, or the function did not proceed beyond the set active line. (The actual object is assigned in the editor and actually works when being referenced outside of the event.) Then I decided to set a flag for it in the function that responds to the C# event, and have another function (via Update) evaluate the flag and set the object active. That worked.

My question is why is that the case? Should some types of code not be called in C# Events in unity?

Thanks

What was causing the event to fire? Most of the stuff in the UnityEngine namespace is only safe to call from the main Unity thread, so if the event was triggering on some other thread, that would cause problems. (It doesn’t matter whether or not the function is being called through an event, only what thread its running on. It’s totally fine to use events as long as those events are only triggered by the main thread.)

Also, you can get issues if you SetActive(true) and SetActive(false) on the same object in the same frame. Intuitively, you’d expect whichever one you did last to “win”, but this isn’t necessarily the case, because SetActive actually defers some of its effects until later in the frame.

1 Like

Thanks so much. This clears up a lot of information and makes sense.

I thought C# events automatically fire on the main thread. So, that is not the case?

Thanks again.

They fire from whatever thread they are fired from ¯_(ツ)_/¯

I see. However, when I created the event, I did not fire it from a different thread. I don’t specify any thread. Perhaps it was being set twice in the same frame.

Thanks.

It doesn’t matter what thread it is created from, it matters what thread it is invoked from.

If your event is named MyEvent, then somewhere you have some code that says MyEvent() or MyEvent.Invoke(), which is what causes the event to run. Whatever thread is executing that line of code also executes the event. (Same rules as any other function or delegate–it inherits the same thread as the caller unless you do something special to ensure otherwise.)

Normally a Unity game won’t involve more than one thread unless you explicitly create a new thread, so unless you are intentionally being multi-threaded I’d be kinda surprised if this is your problem.

I see. So it must be the conflicting calls since I am not intentionally mulit-threading anything - primarily because I don’t even know how to do such. When I use the method of setting a flag that is checked in update, it seems to work. It’s likely, give what you said, my design probably is attempting to set the objects as active more than once in a frame. It’s not readily apparent where, because I checked.

Also, this is my first time using an event-driven approach as opposed to grabbing references to objects via GetComponent. So, I will clean those up as I continue.

Thanks for your insight.

If there’s no multithreading involved I’m at a loss to add anything to this conversation without seeing some of the code in question, ideally marking which code you believe should be executing but is not.

  • Where do you add the callback to the event?
  • Where do you invoke the event?
  • Which code in the callback is not being executed?

Unity’s concept of active/deactivated objects shouldn’t have any bearing on the way C# events execute except that if the event is fired within some function that Unity doesn’t invoke due to the object not being active, obviously the event won’t be fired.

Thanks. I think it is likely due to conflicting calls. Thankfully, I do think I have enough information based on what was shared in this thread to proceed and resolve the issue. If not, I will post some additional information.

Thanks again.

Necro with the solution that fixed this problem for me. I was trying to have my interaction system script subscribe to an event that my dialogue system would fire when the dialogue box was closed. The problem was a classic issue I’ve run into with grabbing other scripts’ components on awake - the script execution order. I had the dialogue system script in the manual execution order, but not the interaction system script. So, when the interaction system tried to subscribe to the dialogue system’s event OnEnable, it couldn’t, because the dialogue system script wasn’t awake yet. I manually told the interaction system script to wake up after the dialogue system script, and boom. Now the event is running perfectly!

I wish Unity would return an error when it doesn’t successfully subscribe to an event OnEnable, it would’ve saved me a day of headaches. But, I’m aware that’s easier said than done because of the nature of how events work. I’m on 2019.4.17f1, not sure if it’s been fixed in newer editor versions. Hope that helps someone!

Thanks. Indeed I do think it was a matter of execution order. As fast as computers are, they must still do tasks one at a time and in order.

1 Like