Unity3D get an Object in start Method - unity3d

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.

Related

How can I pass custom data into a MTAudioProcessingTapProcessCallback?

I am successfully using an MTAudioProcessingTap in Swift on MacOS to manipulate my audio routing for both live playback and export. However, the specific routing that should occur at runtime depends on the user's choices. What I would like to be able to do is pass in a pair of Ints to the MTAudioProcessingTapProcessCallback when I create the tap so that I can use a single callback definition that can use those Ints to determine how to do the routing. The problem is that the callback is a C function pointer that can't capture context.
I thought maybe I could use the clientInfo parameter of the MTAudioProcessingTapCallbacks to hold the values I need, but I can't find any documentation on how I can access this parameter from within the MTAudioProcessingTapProcessCallback.
I have 32 possible routing combinations, and unfortunately the only other option I see at this point is declaring 32 separate MTAudioProcessingTapProcessCallbacks, and then selecting which to use when I create the tap. But it would be so much easier for me if I could just have a single MTAudioProcessingTapProcessCallback that makes a simple decision based on passed-in data.
I figured out how it works. In order to access the data inside the clientInfo from within the Process callback:
Inside the MTAudioProcessingTapInitCallback you have to initialize the tapStorageOut with the clientInfo pointer
Inside the Process callback use MTAudioProcessingTapGetStorage(tap) to get that pointer and access the data.

Unity script execution order and Start()

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.

runBlock not working in sequence?

I am trying to create a basic spawn sequence- the block must be created, moveDownLeft, and then removeLeft. moveDownLeft and removeLeft work fine on their own when the block is added using self.addChild(block1) previously, however I need to have self.addchild within the sequence.
The only way that I can see to do this is use runBlock, and I looked at this question when I got an error using that: Swift: SKAction.runBlock -> Missing argument for parameter 'completion' in call BUT WHY?
So now I am left with this:
block1.runAction(SKAction.sequence([SKAction.runBlock({ self.addChild(self.block1) }), moveDownLeft, removeLeft]))
And nothing in the sequence works because the block is not created in the first place. Why is this happening?
Your code fragment is too short but it looks like a typical chicken and egg problem.
node can only run actions once it has been added as child and thus becomes part of the scene graph
your node is supposed to run an action that will eventually add itself to the scene graph but it's not in the scene graph yet so it won't run that action
Add the node as child first, then run the action. If you need the node to be inactive for some time, simply set it's visible property to NO for the duration. You kay also ned to change other properties, ie postpone creation of the physics body.

Difference btw. sendmessage and setting Value

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.

Rhino Mocks Calling instead of Recording in NUnit

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.