Home > Software engineering >  Difference between assigning a variable a value before or inside Start() method. C#
Difference between assigning a variable a value before or inside Start() method. C#

Time:11-27

Is there any fundamental difference between assigning a value to a variable before or inside the Start() method?

For clarity, I'm not talking about declaring variables but really just giving them values like, in this simple example:

public class test : MonoBehaviour
{
    private float exampleFloat = 12.34f;

    private void Start()
    {
        // do stuff with exampleFloat
    }
}

versus this :

public class test : MonoBehaviour
{
    private float exampleFloat;

    private void Start()
    {
       exampleFloat = 12.34f;
       // do stuff with exampleFloat
    }
}

CodePudding user response:

I don't know if Unity changes this at all, but at least in the pure C# world, the only difference can be shown with the question:

Do you intend to read from exampleFloat before calling Start()?

In the second example, where you just declare the variable, the variable will get assigned a value of 0 by default. If you try to read the variable before calling Start(), you won't see the value as 12.34.


There is a similar problem of "do I initialize variables inside or outside constructors?", but at least with using a constructor, you know the variable will have the target value before the object (class) is initialized.

CodePudding user response:

private float exampleFloat;

...declares the variable, and as it's a primitive type, sets it to its default value, in this case 0.

Therefore, if you access the variable before the Start method has run, it will be 0. If you access it inside Start, or after that has run, it will have the value 12.34.

By the way, this is a C# question, nothing to do with Unity.

CodePudding user response:

Just to add, because we ARE talking about Unity, let's discuss your question with some examples.

Object Lifecycle

Let's consider the object lifecycle and when Unity events are called:

public class test : MonoBehaviour
{
    private float exampleFloat = 12.34f;

    private void Awake ()
    {
        Debug.Log($"Example 1: exampleFloat = {exampleFloat}");
    }

    private void Start()
    {
        //do stuff with exampleFloat
    }
}

and:

public class test : MonoBehaviour
{
    private float exampleFloat;

    private void Awake ()
    {
        Debug.Log($"Example 2: exampleFloat = {exampleFloat}");
    }

    private void Start()
    {
       exampleFloat = 12.34f;
       //do stuff with exampleFloat
    }
}

In the above examples, the results would be:

Example 1: exampleFloat = 12.34
Example 2: exampleFloat = 0

Serialisation

Now, let's throw serialisation into the mix!

public class test : MonoBehaviour
{
    [SerializeField] private float exampleFloat = 12.34f;

    private void Start()
    {
        //do stuff with exampleFloat
        Debug.Log($"Example 3: exampleFloat = {exampleFloat}");
    }
}

and:

public class test : MonoBehaviour
{
    [SerializeField] private float exampleFloat;

    private void Start()
    {
       exampleFloat = 12.34f;
       Debug.Log($"Example 4: exampleFloat = {exampleFloat}");
       //do stuff with exampleFloat
    }
}

In the above examples, the results would be:

Example 3: exampleFloat = 12.34 // OR whatever is serialised in the Inspector!
Example 4: exampleFloat = 12.34 // always 12.34.

So, it turns out that it does matter where you apply your values, as Unity is very much dependent on the component lifecycle. Awake will always be called before Start. Serialisation occurs after the object is created, but before Awake. And you're not supposed to call a Component constructor, so declaring values in there isn't an option.

  • Related