- Home /
Optimizing script to improve lag
Currently, my game will spawn in a few enemies into the scene when a "wave" starts. This does not cause any lag, however, on each of the enemy, I have a script that tracks every single structures that belongs to the player (These structures are stored in an empty object so I used a foreach loop to get each structure's position). After getting each of the position, the enemy will find the nearest structure to go to. This itself is obvious that it will cause some lag, so I added a small timer to control the interval between finding a new nearest target (1 - 2 seconds). This helps with the frame drop issue as it is not tracking on every single frame. However, taking a look at my profiler, at each tracking moments, it has a huge lag spike. When playing the game, you can feel that the enemies are all trying to track and find the nearest object to go to (As the game stops for a brief moment, normally around 0.1 seconds). Is there a way I can optimize this? I have some solution in mind though, as I am using a for loop to instantiate all of the enemies in the scene at once, I'm pretty sure this will cause that future tracking "moments" will happen for all of the enemies since they are spawned in at the same time. So would spawning them in at different times help. Are there any other better way to improve the code?
private void track_items()
{
small_timer -= Time.deltaTime;
if (small_timer <= 0)
{
foreach (Transform structure in mc_structures.transform)
{
tracked_items.Add(structure);
}
foreach (Transform o in tracked_items)
{
float dist = Vector2.Distance(o.position, transform.position);
if (o.name.Equals("main_character"))
{
dist /= 2;
}
if (dist < distance)
{
distance = dist;
target = o.gameObject;
}
}
small_timer = small_time;
}
}
small_time is set to 2 seconds. Also, I added a if statement to make the enemies more "interested" in the player. mc_structure is the empty game objects that all of the structures will be stored in. Thanks for the help.
Answer by CodesCove · Mar 15, 2021 at 08:11 PM
Some ideas for optimization:
I usually add a small random time to timers when doing some mass operations that should be distributed in temporal axis evenly. This at least prevents certain spikes.
I also cache all the needed object references (so that you need to only find them once or if any changes are made) and preferably have a static List where each object registers it own reference on a Awake and remove it's own reference in OnDestroy. Then you have always up-to-date list of references that you can iterate in a quite fast way and access it anywhere in you code.
When calculating distances it's good to assess why it's done. If the distance is only needed for comparison the you don't need to call the quite expensive Distance method. You can use Vector3.sqrMagnitude value to do a fast comparison between two squared vector length. https://docs.unity3d.com/ScriptReference/Vector3-sqrMagnitude.html
If you have really larger amount of calculations to be done and your target platform is suitable then consider to move the calculations from CPU to GPU via ComputeShader.. This is not so trivial and lot's of considerations need to be done, but might be interesting option, at lease to get to know this option, if you have not programmed shaders before. https://docs.unity3d.com/Manual/class-ComputeShader.html
Thank you for your responses, I did try to cache all of the positions of my structures into one place and only update the list whenever a new structure is instantiated into the scene, so all of the enemies would reference to that script. I can't really say for sure what helped, I also added a small random time roughly from 1 to 3 seconds for the enemy to check nearest object again. This way not all the enemies are checking the distance at the same time, so the task is spread out.
Your answer
Follow this Question
Related Questions
How to reduce Draw-Calls? 1 Answer
Extreme lag in game 1 Answer
Editor incredibly slow, weird profiler output. 1 Answer
What is a dirty scene objects? 2 Answers
good guidelines for iOS Profiler 1 Answer