Event System, Component order and execution

Hi all,

I am trying to do a couple of Components on my GameObjects to communicate using the UI Event System (ExecuteEvents.Execute(…)).

Now I’m having trouble understanding when the events are actually firing.
I was hoping that the order of the Components in the Inspector was the actual order of execution, but it ain’t so.

If I have a Component A that fires an IMyNiceEventHandler : IEventSystemHandler interface event, and there is a Component B and a Component C that implement it, how can I make sure that Component B is executed before Component C, or (if I want it) Component C before Component B, just on that specific GameObject?

Basically I want to have a pool of Behaviours that can be applied AFTER a certain event happened. For example, if the event handler was

public interface IWaterEnteredHandler : IEventSystemHandler
{
       void OnWaterEntered();
}

Then my main component would be

public class MyClass: MonoBehaviour
{
       public void Update()
       {
               if(Input.GetMouseDown(0))
               {
                       EventSystems.Execute<IWaterEnteredHandler>(gameObject, null,  (x, y) => x.OnWaterEntered());
               }
       }
}

I want the following components

public class Drown : MonoBehaviour, IEnteredWaterEventHandler { ... }

public class Swim : MonoBehaviour, IEnteredWaterEventHandler { ... }
public class Walk: MonoBehaviour, IEnteredWaterEventHandler { ... }
public class GetsWet: MonoBehaviour, IEnteredWaterEventHandler { ... }

But if I have, for some reason, both Components on the same GameObject, I want to be able to say that Swim overrides Drown, or Walk overrides Swim or Drown. AND I want that GetsWet coexists with all three other components. So basically, if the character can swim, he doesn’t drown, and if he can walk, he doesn’t swim. But if he hits the water, he gets wet regardless.

If the component order was clear, it would be easy. Then GetsWet would come first. Then Walk, which would set all other IEnteredWaterEventHandlers to enabled = false. Then the rest wouldn’t even receive the event.

Thanks for your patience,

Wavy

Using separate components for states isn’t going to be a good idea. Making each state a separate component is saying an object can drown, swim, and walk at the same time. Consolidate them into a single class that controls what one state it’s supposed to be in.

3 Likes

If you want a specific order, create several events that fire one after the other.

Script Execution order last time I checked only applies to when the Unity Method’s (Update, FixedUpdate, etc.) fire. So if you set the order such that A was first, B second, C third, etc. then that only applies to the Unity methods. If you’re reaching into the other objects say A fired an event to C that would occur before B and C’s normal logic for that callback (Update(), etc.).

If it’s only a few things you can manage this by using lateUpdate for some things, but it’s probably better to specifically manage state yourself if you have a lot of this stuff that is timing dependent.

1 Like

I might have solved it by adding an overrideable Priority int property and an Applied bool property. If one post effect has a higher priority than the other, AND has been applied, other post effects with a lower priority will not fire. If it has not been applied, the other post effects do their thing, and so on.