Simple "events"?

Hey everyone.

I’m trying to implement a way to change the simulation speed of my game. For this, I need to be able to “broadcast” to every game object when a simulation step occurs.

In other words: When a certain method is called in my simulation handling object, every object “subscribed” to this “event” needs to know, and be able to, in turn, call their own methods.

Looking at delegates, I only got confused, and the UnityEvent system proved much the same.

Therefore, I was wondering if there’s some simple system I could use to achieve this, without having a reference to every “subscribed” object in my simulation handler?

Thanks in advance :slight_smile:

-FP

They objects wishing to subscribe need a reference to the script that will invoke the event (not the other way around, in case that’s what you thought).

Do you have any code sample/attempts to post?

Ah, what a shame. I suppose that’ll be the way forward then.

I’d love a code example if you don’t mind :slight_smile:

public class Test1 : MonoBehaviour {

    public event System.Action onStepChanged;

    // for your code, this would be probably your own method, not Start().
    // I used start for a simple example so it can run on its own ;)
    IEnumerator Start()
    {
        yield return new WaitForSeconds(1.5f);
        if (onStepChanged != null) onStepChanged();
    }
}

So, the code above is for 1 game object that is going to signal other objects when the step changes. Be sure to note my comment, as you probably don’t want Start(). =)

public class Test2 : MonoBehaviour
{
    [SerializeField]
    Test1 test1Broadcaster;

    void Start()
    {
        test1Broadcaster.onStepChanged += SimulationStepNext;
    }

    private void SimulationStepNext()
    {
        print("Got event notification: " + gameObject.name);
    }
}

That’s the simplest idea I could come up with to show you it working. If you put that on 1+ game objects, they will receive the notification when the event is invoked.
Note: if the objects receiving events should not receive them while disabled, you should unsubscribe them at that time. Also, if they can be destroyed, but the broadcaster is still active, you should unsubscribe from the event at that time, too.
I left that out of the example, but didn’t want to leave it out entirely. :slight_smile:

You could also pass arguments from the event, too. That’s what things like onValueChanged do, if you modify a slider’s value and have an event listening, for example - it sends the new value…

Ah, fantastic! This is exactly the simplicity I was looking for.
Thanks a lot @methos5k !

Do you need to broadcast the event or is just having the current simulation step available to other scripts an option? IE do the scripts need to execute every time or is having the correct information when they do execute enough?

If they just need the correct simulation step, then maybe storing that in a scriptable object would work. That way the scripts don’t need to be aware of each others events, they just reference the same scriptable object to update / read the step as appropriate.

You’re welcome. :slight_smile:

Somewhat unfortunately, it does need to trigger a method or action on the receiving object.

Using Time.timeScale caused some problems, so I’m basically making my own simulation speed system. I have one class which handles the steps based on the current simulation speed (player inputted), and the difference in time between the last step and the next step time (if that makes sense). When that difference is triggered, I want all receiving objects to do something (in this case, I want a planet to move a certain amount of degrees in its orbit).

Ok. My suggestion was more suitable if each planet had a UpdateOrbit(simulationTime) sort of function.