- Home /
How to run Update multiple times per frame for fast-forwarding purposes
I want functionality similar to games like The Sims where the game can run at 0, 1x, 3x, and ~20x speed.
The first few I can do by adjusting Unity's time scale. But very high speeds don't work this way. Everything breaks as accuracy goes down at high time steps.
I need a way to have Update() run multiple times per frame. So to run at 20x speed I could set the time scale to 2.0 and repeat Update 10 times each frame (or as many as the user's machine can handle).
Does anyone know a good way to set Update to repeat each frame? I know how I could do it by setting up my own version of Update and calling it myself, but I'm wondering if there's a more elegant solution.
Thanks, Tynan Sylvester tynansylvester.com
Answer by pudd1nG · Jun 05, 2012 at 03:36 AM
You want to use the timescale.
In script, you can simply do
Time.timeScale = 2.0f
for 2x speed.
In Unity if you goto edit>project settings>time you can set the timescale.
Otherwise just loop over it, you could either call your function twice or simply loop over it. Here's a loop example
void MyThing(int count){
for(i=0;i <= count;i++){
DoThing();
}
}
You can then InvokeRepeating on that function, adjust the repeat time and count to find a smooth set of numbers for your timescale & timestep.
Good luck
Well if you don't want the timescale, simply migrate all your Update code into another function and call it twice in update........Or 100 times in update.
Answer by Berenger · Jun 05, 2012 at 03:38 AM
I'm gonna take an example to make sure I understood your problem.
Let's say you have AI characters using pathfinding to travel into a house in a sims-like game. At timeScale = 1, the delta is of .02, all is fine. With timeScale = 100 however, the delta is 2 and that makes your character miss all the waypoints on your path, problematic with corners and such.
I've never dealt with that before, but try to loop several times inside your Update function, proportionnally to your timeScale. tS of 2, loop of 2, tS of 10, loop of 10 etc. If several scripts need that behaviour, I suggest you create a class between MonoBehaviour and your scripts to deal with that, so you don't have to write it multiple times.
Yeah I can think of ways to do it with my own custom method. I'm really trying to find the most elegant solution. Creating a subclass of $$anonymous$$onoBehaviour may be that, though I had hoped there was a better way. Thanks.
Hmm, the other issue here is that all the scripts have to run Update in the correct order.
If there are four objects, A, B, C, and D, they have to run ABCDABCDABCDABCD and so on. Not AAAABBBBCCCCDDDD, which I think is what you would get if you just did any variation on looping inside the Update function.
In that case, you might need a master taking care of the updates. it would be a script gathering all the updatable objects (probably any objects bu himself ?), storing them into a list / array. None of them must have an Update function, only the master.
Inside it would alternatively call a custom update function for each of them, once for a timeScale = 1, twice for 2 etc.
Answer by Tynan · Jun 06, 2012 at 08:15 PM
So here's what I did.
-Created a central time manager class.
-Created a subclass of MonoBehavior called MonoBehaviorGame. All my game actors derive from this.
-MonoBehaviorGame has a ZUpdate() and ZLateUpdate() function.
-In their Start() methods, all MonoBehaviorGames call a function which registers them with the central time manager.
-Every Update() on the time manager, I loop through the list of all registered MonoBehaviorGames and call their ZUpdates(), then their ZLateUpdates().
-Note that between the above loops I run an algorithm that consolidates out any null entries in the list of registered MonoBehaviorGames. This handles actors being destroyed.
Seems to work so far, except a few quicks I have to work out with how the interface such interact with it.
Your answer