Also a noob here but have an opinion, maybe it will help.
I use GetComponent<>() methods in awake, also in the scene i put GameObjects to the slots if I used any public GameObject field.
In the start function, If I need, I reference to other scripts variables. This way I don’t get nullreferenceexception when i reference to other fields and use them
Well, you kinda answered your own question, didn’t you?. In the documentary it also says:
And while it is true that in some very rate cases an reference gets assigned too late due to delegate trickery or stuff like that you usually don’t have to worry about that.
[EDIT] Little side note: Setting references is actually pretty much exactly what Awake is for since it’s as close to a Monobehaviour construcor as you get.
You can use Awake for this, but it’s better to do it in Reset. Add it to an interface, and do what you like with it. I call all of them with my menu item Assets/Initialize Scene.
namespace UnityEngine {
public interface ISceneInitializable {void Reset();}
}
Awake is primarily useful for subscribing to events, in my experience.
Don’t use public fields for anything serialized. It was a bad decision on Unity’s part to make public and [SerializeField] be tied together.
Each GameObject and all of its component exist before awake is called. This means you can call GetComponent to your hearts content.
What you shouldn’t do is use any variables on any components. You have no guarantee that these variables are ready, as you can’t tell if Awake has been called. Some examples may help.
MyComponent myComponent;
Float someValue;
void Awake () {
// This line is okay
myComponent = GetComponent<MyComponent>();
// This is not okay
myFloat = GetComponent<MyComponent>().someValue;
}
Using SerializeField is good advice. In C# you don’t have to write private, so its not that many extra key strokes.
public allows any script to access a variable. It can lead to unexpected bugs and dependency issues for variables that are designed to be initialised in the inspector, but not changed during game play. In general you should have as few public variables as possible. Each public variable should have a defined purpose for other classes to interact with your class.
My recommendation isn’t really about the scope; I’m just saying that it was not good to make any access modifier (public, private, etc.) automatically invoke [SerializeField]. It leads to less experienced people (like the people who first made Unity, and the decision itself) using that access level, just to get things into the Inspector.
If the Inspector updated properties (not just fields), I’d have to reevaluate this, but because it doesn’t, here’s what my team does: If you know that you need a serialized field, treat it as a backing field for a property. In addition to accessing it via the property blocks, permit yourself to set the field’s value in the Inspector, if it makes sense to do so. Otherwise, use [HideInInspector].
Never serialize a field by making it public. Use [SerializeField], and only on private or protected fields.
If the backing field is visible in the Inspector, and you want to change the name of the property, you should employ FormerlySerializedAsAttribute.
Example of how what’s serialized, and what you want, aren’t always the same thing.
NullableBool is implicitly convertible to bool?. NullableBool only exists because Unity doesn’t serialize nullable types.
A lot of what I serialize doesn’t even need to be set from code, so only having a getter is very common for me. Setting the value is what you do in the Inspector.
When you are using Awake() and object is not an anctive at the game start the Awake of this object will not be called untill you set object active but if you use public variables objects will be referenced. That the problem of using Awake() for initialization I had found.
The note about Awake/Start in the docs isn’t new information. All you need to know is all Awakes run, then all Starts run. The note is explaining how you can use Start() to make sure one thing runs after another, in different scripts. The “random order” part is also old. You can set the Script Execution Order now. If you don’t, the order might seem random.
The thing about public/private is it has no effect on how the program runs. If you never want to use a variable from outside, but it’s public, it clutters up the dropdown a little. But making it private and adding getters/setters, which is what most people do, isn’t any better.