the question basically explains itself.
Where declare a variable in the scope it’s needed.
If it’s a variable that is needed for the life of a script, you declare it at the class level.
If it’s a variable that is needed for only the life of a function call, it should be scoped to that function.
So if you have a variable that’s only needed DURING the start call, declare it in the Start function.
When you need a variable in Start
The question pretty much answers itself
ok so you are saying if i also need the variable throughout update() i should declare it at class level right?
Technically…
If the state of it is needed from update call to update call, yes.
For example:
public class Example : MonoBehaviour
{
public float Range = 1.0f;
private int _count;
void Start()
{
_count = (int)Random.Range(0,10);
}
void Update()
{
float value = 0f;
for(int i = 0; i < _count; i++)
{
value += Random.Range(0, Range);
}
value /= (float)_count;
Debug.Log(value.ToString());
}
}
In this example we have several variables.
Range - this is a value that can be set through the inspector (it’s public) it’s going to control the amount of range of the values we generate
_count - this is set to a random value in Start, and then used every frame of update to generate a random average
value - this is a value used in Update over and over, BUT it’s life really only lasts as long as Update runs once. The state of it does not need to be stored for the next Update call.
i - this is the iterator, it is only needed for the life of the for loop
Note how all these variables are scoped to that which the life of it is needed.
I’m trying to make as simplified an example as possible here…
You have to. Something you declare in start only exist within that scope.
I think you actually meant to ask when to assign a class level variable vs just grabbing the reference again when you need it?
I always see you initializing variables in the start is there ever a point where you dont initialize variables in the start()
cause my only guess is in situation like this where. also what is the default modifier for a variable with no access modifier.
int a;
int b;
start()
{
int c=a+b;
}
I didn’t initialize Range in Start
I did that purposely. I wanted to show a variable getting initialized in Start, and one not getting initialized in Start.
Note that the _count value I initialized in Start is private. I did this because it shouldn’t be in the inspector (it’s a value we generate on Start, not something configured in the inspector).
Unless you are using “c” in the Start() method for something then it is useless and will disappear when Start() is done.
You created a completely new variable in a method, when that method is done the variables created inside that scope are gone. You can’t access them from other methods.
You could however, initialize int c at the class level as a and b are, then say c=a+b in start and access it later, like in Update().
when i did this it worked like a charm:
public class test : MonoBehaviour {
public int a;
public int b;
public int total;
// Use this for initialization
void Start () {
a=5;
b=3;
}
// Update is called once per frame
void Update () {
if(Input.GetKeyDown(KeyCode.Space))
{
total=a*b;
Debug.Log(total);
}
}
}
but when i did this it showed up in console as 0 and i get 0 everytime i press space:
public class test : MonoBehaviour {
public int a=5;
public int b=3;
public int total;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
if(Input.GetKeyDown(KeyCode.Space))
{
total=a*b;
Debug.Log(total);
}
}
}
and a and b are set to 5 and 3 in the inspector?
This works fine. Are your variables defined properly in the Inspector?
If you change the class level values it wont update the inspector. Use Reset() or Start() to define variables.
I’m betting you moved the initial values to the fields and out of Start AFTER attaching the script to the GameObject.
Remember in the other thread where I told you about the order of steps that go on when initializing an object? Well in the steps unity does some special things that deal with serialization. Those steps are what allow saving the scene for reloading later.
The values in the serialized object were set to the values the FIRST time it was added to the GameObject. Which was when you were initializing it in Start. So the values were 0 (ints default to 0).
I bet if you add the script to a whole new GameObject it will work fine.
ok thx i had to reset the script in the gameObject i am such a newb but i understand what you are talking about laneFox
if i define and initialize the variable in start it only stores the memory temporarily therefore it will be 0 but if i make a class level variable then initialize it in start() it will save that memory and i can later use it in my script but i do not know if that memory gets deleted eventually or if it stays.
The code below uses some basic scope control. Maybe it’ll help everything click for you.
public string thisExistsInTheClass; // this string has no value yet
// Start runs one time, before Update
void Start()
{
thisExistsInTheClass = "Hello"; // now it as a value
}
void Update()
{
string onlyThisMethodSeesMe; // this variable has no value yet
onlyThisMethodSeesMe = thisExistsInTheClass; // make this local string the same as the other one
if (onlyThisMethodSeesMe == thisExistsInTheClass)
{
string Exists_For_This_If_Statement = "12345";
Debug.Log(Exists_For_This_If_Statement + " " + onlyThisMethodSeesMe); // we can use OnlyThisMethodSeesMe because its inside Update, which created it.
}
DoSomethingElse();
}
void DoSomethingElse()
{
thisExistsInTheClass = "LOLZWTF"; // update the class level variable which we defined in Start(), then observe the debug.
}
}
When you leave a method, its local variables are GC’d. For example, “Exists_For_This_If_Statement” is destroyed when the if statement is finished and “onlyThisMethodSeesMe” is destroyed when Update() is finished, then recreated when its run again. DoSomethingElse() could not reference either of them because they don’t exist in its context.
i thought that variable must be declared in Awake()
No. Awake() has other uses and it does run before Start().
when is thisExitsInTheClass destroyed?
When the component is destroyed.
component as in the script?