- Home /
Run a complex script in the background without reducing the FPS
The Problem:
I am making a turn based game and at the end of a players turn a complex script is run before it is the players turn again.
The problem is that when this complex script is run the game freezes for about 5 to 8 frames, this is only going to get worse as I add more complexity to the game.
As it is a turn based game it will not technically be a problem for the game to freeze for a few seconds between turns but it does look bad, especially since all the characters idle animations freeze and the game looks crashed.
The Question:
How can I get this complex script to run in the background "over a few frames" once a players turn is over, while still maintaining a frame rate that allows animations to play?
I will obviously not permit inputs during this period and nothing will change "except whats happening in the complex script", other than the idle animations playing.
Bad Solutions:
I could display a "Loading" screen before running the script and then remove it when the script has completed but that will look just as bad and kill immersion.
Answer by Statement · Dec 16, 2012 at 11:58 PM
You could make use of coroutines. You would have to modify your code to allow the game to "catch up & do other stuff" while your operation is processing.
http://docs.unity3d.com/Documentation/ScriptReference/index.Coroutines_26_Yield.html http://docs.unity3d.com/Documentation/ScriptReference/MonoBehaviour.StartCoroutine.html http://docs.unity3d.com/Documentation/ScriptReference/Coroutine.html
You could make use of threads to run your code on a different core of your processor (or switch between tasks on single core architectures).
http://msdn.microsoft.com/en-us/library/a9fyxz7d(v=vs.90).aspx
Take care if you do threads as you can't access most Unity classes from a different thread than the main thread.
Also you could consider trying to optimize your code.
Thank you.
Coroutines sound like the thing I need to use, although it will require me write my code in small snipits that the CPU can handle.
I was wondering would it be possible to implement a system were a script would pause till the next update if a certain amount of time has passed "ie one 1/30 of a second"?
Using yield inside for- and while loops usually takes care of any hiccups. What heavy algorithm(s) are you running during the freeze?
I was wondering would it be possible to implement a system were a script would pause till the next update if a certain amount of time has passed "ie one 1/30 of a second"?
Yes, but you'd have to make sure that the code is testing for the elapsed time frequently so it can yield. Otherwise it sounds like you want to use threads. Depending on how much stuff your script does with "Unity objects", you might want to think about threading ins$$anonymous$$d. If you don't use Unity objects in those algorithms, then you should be pretty fine, and all you need to worry about is the synchronization to signal the main thread when the work is done.
The game is on a Hex grid with 10,000+ hex's that can move and have walls placed between them.
The Complex Script finds all Hex's adjacent to each Hex and then checks to see if there is a wall blocking movement to that Hex. Then a list of Connections is created for each Hex.
I have a $$anonymous$$i version that just updates the Connections list for Hex's that have changed "and it neighbors" for when a wall gets destroyed during a turn.
But I want to totally rebuild the Hex Grid each turn, for peace of $$anonymous$$d. :P
That does sound very intense, but also interesting! Re-assigning so many objects/components might be tricky to solve without some sort of pause in between. At the end you might want that $$anonymous$$i version for the sake of the end-user, but until then you might be able to loop through hex in blocks (batches) while giving the player a heads up to wait. Animations should be able to play whilst doing so.