Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

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

Discussion in 'Scripting' started by AussieSwissDave, May 8, 2016.

  1. AussieSwissDave

    AussieSwissDave

    Joined:
    Apr 20, 2013
    Posts:
    97
    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.
     
  2. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,514
    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.

    Code (csharp):
    1.  
    2. public class FixedIntervalUpdate
    3. {
    4.  
    5.     private int _ticksPerSecond;
    6.     private System.Action _callback;
    7.     private float _simulationInterval;
    8.     private float _t;
    9.  
    10.     public FixedIntervalUpdate(int ticksPerSecond, System.Action callback)
    11.     {
    12.         this.TicksPerSecond = ticksPerSecond;
    13.         _callback = callback;
    14.     }
    15.  
    16.     public int TicksPerSecond
    17.     {
    18.         get { return _ticksPerSecond; }
    19.         set {
    20.             _ticksPerSecond = value;
    21.             _simulationInterval = 1f / value;
    22.         }
    23.     }
    24.  
    25.     public void Update(float dt)
    26.     {
    27.         _t += dt;
    28.         if(_ticksPerSecond <= 0) return;
    29.      
    30.         while(_t > _simulationInterval)
    31.         {
    32.             _t -= _simulationInterval;
    33.             _callback();
    34.         }
    35.     }
    36.  
    37. }
    38.  
    And used:
    Code (csharp):
    1.  
    2. public class SomeScript : MonoBehaviour
    3. {
    4.  
    5.     private FixedIntervalUpdate _fixedInterval;
    6.  
    7.     void Start()
    8.     {
    9.         _fixedInterval = new FixedIntervalUpdate(20, this.OnTick);
    10.     }
    11.  
    12.     void Update()
    13.     {
    14.         _fixedInterval.Update(Time.deltaTime);
    15.     }
    16.  
    17.     void OnTick()
    18.     {
    19.         //do stuff
    20.     }
    21.  
    22. }
    23.  
    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.
     
    Kiwasi likes this.
  3. AussieSwissDave

    AussieSwissDave

    Joined:
    Apr 20, 2013
    Posts:
    97
    Hey mate, thanks for your help. And yes good idea, the link to the other thread is:

    http://forum.unity3d.com/threads/sp...logic-and-visuals-and-multi-threading.403066/

    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.
     
  4. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,514
    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:

    Code (csharp):
    1.  
    2. public class FixedIntervalUpdate
    3. {
    4.  
    5.     private int _ticksPerSecond;
    6.     private System.Action<float> _callback;
    7.     private float _simulationInterval;
    8.     private float _t;
    9.  
    10.     public FixedIntervalUpdate(int ticksPerSecond, System.Action<float> callback)
    11.     {
    12.         this.TicksPerSecond = ticksPerSecond;
    13.         _callback = callback;
    14.     }
    15.  
    16.     public int TicksPerSecond
    17.     {
    18.         get { return _ticksPerSecond; }
    19.         set {
    20.             _ticksPerSecond = value;
    21.             _simulationInterval = 1f / value;
    22.         }
    23.     }
    24.  
    25.     public void Update(float dt)
    26.     {
    27.         _t += dt;
    28.         if(_ticksPerSecond <= 0) return;
    29.      
    30.         while(_t > _simulationInterval)
    31.         {
    32.             _t -= _simulationInterval;
    33.             _callback(_simulationInterval);
    34.         }
    35.     }
    36.  
    37. }
    38.  
    Code (csharp):
    1.  
    2. public class SomeScript : MonoBehaviour
    3. {
    4.    
    5.     public float speed;
    6.    
    7.     private FixedIntervalUpdate _fixedInterval;
    8.  
    9.     void Start()
    10.     {
    11.         _fixedInterval = new FixedIntervalUpdate(20, this.OnTick);
    12.     }
    13.  
    14.     void Update()
    15.     {
    16.         _fixedInterval.Update(Time.deltaTime);
    17.     }
    18.  
    19.     void OnTick(float dt)
    20.     {
    21.         //do stuff, where dt is the change in time since last tick
    22.         transform.position += Vector3.forward * speed * dt;
    23.     }
    24.  
    25. }
    26.