I understand from Unity’s order of execution document that it runs Awake then OnEnable then Start and so on for all scripts, but what is the order of execution of the scripts. Does it execute the scripts in a random order. I know that the script execution order can also be set from the project settings or the alternate way is to use LateUpdate fix as Rick did in the video. But how do we decide which scripts should get priority? Is there a general rule like the scripts related to character movement should get the priority over other stuff like camera?
The order of scripts can really only be controlled to some extent using the Script Execution Order settings. By default, I am pretty sure that the scripts are executed primarily in the order that they are loaded, which can potentially lead to unpredictable results.
Here is how you can set the Script Execution Order:
"Edit" → “Project Settings” → “Script Execution Order” in the Unity editor. In the Script Execution Order window, you can add scripts and assign them a priority value. Scripts that have lower priority values are executed before the scripts with higher priority values. If multiple scripts have the same priority, their execution order is determined by the order in which they are listed.
I would recommend ordering the scripts based off of core game mechanics such as:
Core Gameplay: Character movement and Collision detection
Camera Related
AI
Logic
Effects: Particles and Audio just to name a few
A general thought is to make the core related stuff with the most priority because its usually hand and hand with player experience and should be processed before all other tasks. I would say the rest is highly based off of the direction of your game. If you have a game that relies heavily on physics(RigidBody, OnCollisionEnter), processing this earlier can ensure accurate physics behavior.
Let me know if you have further questions! Hope this helps!
I’m not sure if this helps or not but I’ll put it here in case it helps others as well.
As you already know, under your Project Settings → Script Execution Order you can see the list of your Project’s Script Execution Order. Minus will execute before ‘Default Time’, positive numbers after ‘Default Time’. The more negative, the higher priority on the list. Sometimes you might run into a bug where one script executes in an unexpected timing. That’s when I would recommend looking at the script order if required based on your project/game.
Unity executes any scripts not in the list during the Default Time slot, which occurs after any scripts with negative order numbers and before any scripts with positive order numbers.
Here is a link for the full details on Unity’s Order of Execution
I hope this helps!
Good idea to put something from Unity’s Documentation, really useful source.
I ran into this problem in a project about a month ago and that particular page helped me out as well. The unusual bug that I experienced didn’t always happen. This leads me to believe that if two functions are called in the same ‘order’ automatically it may conflict with one or both of said scripts. In this instance, it is worth using the Script Execution Order settings. There is a bit of a grey area, which we may never know as it is part of the closed source within the UnityEngine itself
I’ll caution that I’m a beginner so take whatever I saw with a grain of salt. But it’s possible my perspective as a beginner may be helpful. I try to design my code to tolerate almost any script execution order. Here are a few things that I have found that give me that flexibility.
- First off within Awake() only put stuff in here that has no dependency on any other script
- Within OnEnable() register all your event listeners with +=
- I try to have one and only one Singleton class. This is for my GameManager which contains an overall state machine for the whole game. If you have execution order issues, sometimes, you can use the states in your game manager to sequence your initialization and create deterministic execution.
- For my game manager I add something like [DefaultExecutionOrder(-1000)] in the class definition so that it executes early. I personally prefer this over the UI for script execution order. If I have to play around with the UI for script execution order, I’ve already lost. I’m not good at thinking through those kinds of problems.
- Within Start() you can start referencing other scripts but with some exceptions… see below:
- Within any singleton class, I avoid referencing any other script in Start(). If I need to initialize something, I rely on the game manager’s state machine to help sequence it.
- Look through your Start() code for anything that Invokes an event. If you can try to defer it to Update(). Again I rely on the Game Manager’s state machine to defer to running that code until the right time.
Example: I once had a circular dependency driven by a Singleton class which needed to be loaded early. This singleton class had a start method which fired off an event which required other classes be fully initialized. Because all my event registration happened in OnEnable() that meant every event and event listener was fully set up. But because the Singleton needed to be loaded early, none of the other classes were sufficiently initialized. I solved this problem by moving the code from the Singleton’s Start method to the Update method. I had to add a little tiny bit of state checking logic within Update but that was sufficient and made my code very robust against being broken by future addition of logic.
I was about to post my general rules for race condition avoidance, but it looks like @Cat_Hill actually wrote a more comprehensive version. Well done.
While messing with the Script Execution Order is technically ok, it’s extremely *really really really important not to change the order of any of the built in scripts in the SEO.
Outside of the SEO, it’s safest to assume that you have no idea in which order the scripts will be executed in, and set your Unity callbacks (Awake, Start, onEnable, etc) up accordingly. To be absolutely safe, Singletons shouldn’t be referred to until OnEnable(), and even then I prefer Start() as I’ve run into occassion where OnEnable() doesn’t have the Singleton yet.
Personally, unless I’m working on following a course, I generally don’t use Singletons at all. That’s not my declaring them evil and off limits, it’s just my preference not to use them.
This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.