Unity's documentation has this line:
By default, the Awake, OnEnable and Update functions of different scripts are called in the order the scripts are loaded (which is arbitrary).
So I have two questions here:
What does "Arbitrary" mean in this context? Is it random?
Does this also include Start() alongside Awake(), or does Start() have its own special behaviour that doesn't follow the script execution order, even if that order has been altered in the project settings?
I've wondered for a while how Unity "decides" how it behaves when it runs, especially since it seems like something will work some of the time but the rest of the time it causes a crash or something with little to no explanation, but the documentation doesn't really mention it much and I can't seem to find much info elsewhere.
That statement is somehow confusing.
Awake, OnEnable and Update will always be called in order.
1.What does "Arbitrary" mean in this context? Is it random?
Yes, its random. Although, it is not talking about the Awake, OnEnable and Update functions. It is talking about scripts. The scripts are randomly chosen to execute.
2.Does this also include Start() alongside Awake(), or does Start() have its own special behaviour that doesn't follow the script
execution order, even if that order has been altered in the project
settings?
Answer #1 should also answer question #2.
This does not affect the callback functions such as Start() Awake(), or OnEnable().
I've wondered for a while how Unity "decides" how it behaves when it
runs, especially since it seems like something will work some of the
time but the rest of the time it causes a crash or something with
little to no explanation
Yes, this is true. This has happened to me in the past too. This is more prone to happen when you have large project with many scripts. The scripts are called randomly. Sometimes, you can get null exception error because GetComponent failed to work. This is why the Script Execution Order Settings is made so that you can always set the order in which your scripts execute.
What I do to fix problems like this is to perform GetComponent in a coroutine function. After that, I check if it is null. If it is null, wait for one frame then try GetComponent again.
Again, this applies to the order in which your scripts are executed not order in which callback functions are invoked/called.
Question 1
According to https://docs.unity3d.com/Manual/class-ScriptExecution.html you can set the order the scripts load manually. If you don't set an order my guess is that Unity uses some predefined order (random, alphabetical or something)
Question 2
Awake() allways runs before Start() and is called when the script is loaded https://docs.unity3d.com/ScriptReference/MonoBehaviour.Awake.html.
To load the scripts in a specific order you need to use the script execution order. To make sure you run the Start() function of each object in a specific order you need to make a "Manager" object that instantiates the objects in the order you wish.
Related
Hey im trying to get an object which is referenced in another script (dictionary).
But when i try to get the object in the start method it seems like the dictionary isnt populated jet.
Error: NullReferenceException: Object reference not set to an instance of an object
If I run this line of code in the update method it works completely fine.
Is there an easy way to let this line run after the dictionary is populated?
Grid Manager Script
Camera Movement Script
Both your code snippets run in Start.
There is no way to predict in which order these two Start messages will be invoked (at least not from the user perspective).
To solve this kind of race conditions (see Order of execution for event functions).
The Awake function is called on all objects in the Scene before any object's Start function is called.
my general thumb-rule is:
Use Awake
to initialize the component itself where it doesn't depend on values
from other components.
E.g. initializing your fields, filling your collections, using GetComponent etc to initialize references (but stop there)
Use Start to then initialize things where you do depend on other components being already initialized.
Like in your case access the collections of the other component
This usually covers most of the cases.
In your case simply converting GridManager.Start to GridManager.Awake should already solve the issue.
Where this is not enough you either can start and tweak the Script Execution Order and basically enforce a certain order in which the event methods get invoked or implement a more complex event based initialization system
Populate the dictionary in Awake() method instead of Start(), then it would be ready by the time you need it in Start() of another script.
I would like to run the Start() from one script just before the Start() of another Script. Is it possible? Can you choose the order of the executions of the scripts?
I am not totally sure about Start() but you can configure the Script Execution Order of Awake, OnEnable and Update. Go to menu Edit / Project Settings and set your preferences like described in the manual section. So you might want to investigate further if Start is affected too - I believe it is as it is kind of related to Update
In general I would recommend to use this feature carefully. If you run nto the situation of having too many scripts in this list, this indicates some design issues.
If you have one script (A) meant to run after another (B), I guess it means A depends on B. In that case, you should get B to call for A passing the needed data.
public class A : MonoBehaviour
{
public void Init(State state){}
}
public class B : MonoBehaviour
{
private State state;
void Start()
{
this.state = SetState();
this.gameObject.GetComponent<A>().Init(this.state);
}
}
This might be the only way in the long run preventing long debugging hours. In fact, if you use the script execution order, it is fine until you have a lot of classes and you have been working on the project for 6 months or more. Worst, you give the project to another coder. Then you have "invisible" dependencies with new bugs you can hardly debug since they are not in the code.
What you may be able to do is normally do the script that you are wanting first however you would like it. However lets say your wanting to run the other script at the end of the first script, You may be able to reference a function by using this (Replacing SecondScriptName with the script you want to go after the first one then replacing FunctionFromSecondScript with the Function from that script)
<SecondScriptName>().FunctionFromSecondScript();
You can then call all of the functions in turn in whatever order you wish.
If i make a mistake, Please forgive me as this is my first comment to help another programmer and I am currently a budding one myself.
Hope this helps :)
I need to build a mini version of the programming blocks that are used in Scratch or later in snap! or openblocks.
The code in all of them is big and hard to follow, especially in Scratch which is written in some kind of subset of SmallTalk, which I don't know.
Where can I find the algorithm they all use to parse the blocks and transform it into a set of instructions that work on something, such as animations or games as in Scratch?
I am really interested in the algorithmic or architecture behind the concept of programming blocks.
This is going to be just a really general explanation, and it's up to you to work out specifics.
Defining a block
There is a Block class that all blocks inherit from. They get initialized with their label (name), shape, and a reference to the method. When they are run/called, the associated method is passed the current context (sprite) and the arguments.
Exact implementations differ among versions. For example, In Scratch 1.x, methods took arguments corresponding to the block's arguments, and the context (this or self) is the sprite. In 2.0, they are passed a single argument containing all of the block's arguments and context. Snap! seems to follow the 1.x method.
Stack (command) blocks do not return anything; reporter blocks do.
Interpreting
The interpreter works somewhat like this. Each block contains a reference to the next one, and any subroutines (reporter blocks in arguments; command blocks in a C-slot).
First, all arguments are resolved. Reporters are called, and their return value stored. This is done recursively for lots of Reporter blocks inside each other.
Then, the command itself is executed. Ideally this is a simple command (e.g. move). The method is called, the Stage is updated.
Continue with the next block.
C blocks
C blocks have a slightly different procedure. These are the if <> style, and the repeat <> ones. In addition to their ordinary arguments, they reference their "miniscript" subroutine.
For a simple if/else C block, just execute the subroutine normally if applicable.
When dealing with loops though, you have to make sure to thread properly, and wait for other scripts.
Events
Keypress/click events can be dealt with easily enough. Just execute them on keypress/click.
Something like broadcasts can be done by executing the hat when the broadcast stack is run.
Other events you'll have to work out on your own.
Wait blocks
This, along with threading, is the most confusing part of the interpretation to me. Basically, you need to figure out when to continue with the script. Perhaps set a timer to execute after the time, but you still need to thread properly.
I hope this helps!
What is the difference between those two methods? Why should i prefer one?
1)
GameObject.FindGameObjectWithTag("").GetComponent<Rocket>().active = true;
2)
GameObject.FindGameObjectWithTag("").GetComponent<Rocket>().SendMessage("setActive");
thanks!
Sending a message searches through all the components of the gameObject and invokes any function that has the same name as the message. Not a 100% sure but Im sure this uses reflection which is generally considered slow.
SetActive() or the active variable set the gameObject as active or not. If its not active it wont render in the scene and vice versa.
First of all it seems there are several inconsistencies with your code above:
1) Components (and MonoBehavior) don't have an active property (active belongs to GameObject), so the first line of code shouldn't compile. In addition the most recente version of unity don't have active anymore, it's substitued with activeSelf and activeInHierarchy.
And btw, both activeSelf and activeInHierarchy are read only, so you can't assing directly a value to them. For changing their value use SetActive method.
2)
The second line of code shouldn't work either (unless Unity does some magic behind the scenes) because SetActive methods belong to GameObject and not to your Rocket Component.
Now, I suppose your question was the difference between:
gameObject.SetActive(true);
and
gameObject.SendMessage("SetActive",true);
The result is the same, but in the second way Unity3D will use reflection to find the proper method to be called, if any. Reflection has an heavy impact on performance, so I suggest you to avoid it as much as possible.
I am trying to write unit tests for a bit of code involving Events. Since I need to raise an event at will, I've decided to rely upon RhinoMocks to do so for me, and then make sure that the results of the events being raised are as expected (when they click a button, values should change in a predictable manner, in this example, the height of the object should decrease)
So, I do a bit of research and realize I need an Event Raiser for the event in question. Then it's as simple as calling eventraiser.Raise(); and we're good.
The code for obtaining an event raiser I've written as is follows (written in C#) (more or less copied straight off the net)
using (mocks.Record())
{
MyControl testing = mocks.DynamicMock<MyControl>();
testing.Controls.Find("MainLabel",false)[0].Click += null;
LastCall.IgnoreArguments();
LastCall.Constraints(Rhino.Mocks.Constraints.Is.NotNull());
Raiser1 = LastCall.GetEventRaiser();
}
I then test it as In playback mode.
using (mocks.Playback())
{
MyControl thingy = new MyControl();
int temp=thingy.Size.Height;
Raiser1.Raise();
Assert.Greater(temp, thingy.Size.Height);
}
The problem is, when I run these tests through NUnit, it fails. It throws an exception at the line testing.Controls.Find("MainLabel",false)[0].Click += null; which complains about trying to add null to the event listener. Specifically, "System.NullReferenceException: Object Reference not set to an instance of the Object"
Now, I was under the understanding that any code under the Mocks.Record heading wouldn't actually be called, it would instead create expectations for code calls in the playback. However, this is the second instance where I've had a problem like this (the first problem involved classes/cases that where a lot more complicated) Where it appears in NUnit that the code is actually being called normally instead of creating expectations. I am curious if anyone can point out what I am doing wrong. Or an alternative way to solve the core issue.
I'm not sure, but you might get that behaviour if you haven't made the event virtual in MyControl. If methods, events, or properties aren't virtual, then I don't think DynamicMock can replace their behaviour with recording and playback versions.
Personally, I like to define interfaces for the classes I'm going to mock out and then mock the interface. That way, I'm sure to avoid this kind of problem.