Multiple simultaneous processes, all using FixedUpdate, wanting multiple Time.timeScale variables

This is related to my earlier thread but on a different, specific topic.

I have a process which does all its stuff in FixedUpdate(), and I change the time at which it simulates with Time.timeScale.

Now I have multiple of these processes running simultaneously and it works fine. However, there is only one Time.timeScale variable and this applies to all of them. What I would like to do is be able to have multiple Time.timeScale values such that the different simulations can proceed at different rates.

Can someone please let me know how to achieve this? Cheers.

If this is not related to physics, don’t use FixedUpdate.

Instead simulate the same functionality of FixedUpdate using Update. You can then create a class to manage this pretty simply.

public class FixedIntervalUpdate
{

    private int _ticksPerSecond;
    private System.Action _callback;
    private float _simulationInterval;
    private float _t;
  
    public FixedIntervalUpdate(int ticksPerSecond, System.Action callback)
    {
        this.TicksPerSecond = ticksPerSecond;
        _callback = callback;
    }

    public int TicksPerSecond
    {
        get { return _ticksPerSecond; }
        set {
            _ticksPerSecond = value;
            _simulationInterval = 1f / value;
        }
    }
  
    public void Update(float dt)
    {
        _t += dt;
        if(_ticksPerSecond <= 0) return;
      
        while(_t > _simulationInterval)
        {
            _t -= _simulationInterval;
            _callback();
        }
    }
  
}

And used:

public class SomeScript : MonoBehaviour
{

    private FixedIntervalUpdate _fixedInterval;
  
    void Start()
    {
        _fixedInterval = new FixedIntervalUpdate(20, this.OnTick);
    }
  
    void Update()
    {
        _fixedInterval.Update(Time.deltaTime);
    }
  
    void OnTick()
    {
        //do stuff
    }

}

And you can easily change the ‘TicksPerSecond’ to change the speed.

Also, you should link your previous topic if it’s related. If I wasn’t part of the thread I wouldn’t know what you’re referencing.

1 Like

Hey mate, thanks for your help. And yes good idea, the link to the other thread is:

I have implemented your code but I find that the Time.deltaTime is changing, such that as I increase ticksPerSecond the Time.deltaTime increases.

So when I move the ball for example with position += velocity*Time.deltaTime the movement is suddenly very jagged if the time steps are so large. I find that often the ball goes through the ground as the position step may so large that it can go on its arc from say 10 metres to -2 in one timestep.

Comparatively, when I was using FixedUpdate the game behaved the exact same if I had Time.TimeScale = 1 or 100 (although with 100 things would become pretty unresponsive as the game is working so hard to simulate in the background).

Is the problem perhaps that doing things like ball trajectories, whilst simple, actually do count as physics and hence I really should be using Fixed Update?

Thanks again for your help.

During the ‘OnTick’ if you use ‘Time.deltaTime’, it’s not going to reflect the time passed since the last tick. So don’t use it.

If you need that simulation time, try this:

public class FixedIntervalUpdate
{

    private int _ticksPerSecond;
    private System.Action<float> _callback;
    private float _simulationInterval;
    private float _t;

    public FixedIntervalUpdate(int ticksPerSecond, System.Action<float> callback)
    {
        this.TicksPerSecond = ticksPerSecond;
        _callback = callback;
    }

    public int TicksPerSecond
    {
        get { return _ticksPerSecond; }
        set {
            _ticksPerSecond = value;
            _simulationInterval = 1f / value;
        }
    }

    public void Update(float dt)
    {
        _t += dt;
        if(_ticksPerSecond <= 0) return;
     
        while(_t > _simulationInterval)
        {
            _t -= _simulationInterval;
            _callback(_simulationInterval);
        }
    }

}
public class SomeScript : MonoBehaviour
{
   
    public float speed;
   
    private FixedIntervalUpdate _fixedInterval;

    void Start()
    {
        _fixedInterval = new FixedIntervalUpdate(20, this.OnTick);
    }

    void Update()
    {
        _fixedInterval.Update(Time.deltaTime);
    }

    void OnTick(float dt)
    {
        //do stuff, where dt is the change in time since last tick
        transform.position += Vector3.forward * speed * dt;
    }

}