Greetings,
I have a script which assists mice in looking for applicable mates. It checks their gender then creates a list of mice ‘mates’ of the opposite gender using an else if statement.
The list was building fine before I created the else if, now I get the error:
The name ‘mates’ does not exist in the current context.
void FindMate() //need to look at all mice, find a mice of the other gender, if the mouse is not pregnant and older than 1, then make the mouse pregnant
{
if (gender == 0) { GameObject[] mates = GameObject.FindGameObjectsWithTag(femaleMouse); }
else if (gender == 1) { GameObject[] mates = GameObject.FindGameObjectsWithTag(maleMouse); } //make a list of mates from all creatures with the mouseTag
float shortestDistance = Mathf.Infinity; //we haven't found any mate we have a infinite distance to that mate
GameObject nearestMate = null; //we need to store a nearest mate variable, this will start as nothing
foreach (GameObject mate in mates) //lets look at every object with the mouseTag
{
float distanceToMate = Vector2.Distance(transform.position, mate.transform.position); //measure the distance from this object with all other mouseTag objects
if (distanceToMate < shortestDistance) //is there a new mate that is closer than the shortest distance other mate object?
{
shortestDistance = distanceToMate; //the closest mouse object becomes the shortest distance mouse object
nearestMate = mate; //the nearest mate is equal to the mate object found in the foreach function
}
}
A variable only ever exists in the surrounding context (and any nested ones below its declaration). What that means in your case is that the array (actually not a list but an array) mates only exists within the body of the if clause (line 3) and another array by the same name exists in the else if body in line 4. Only code within the same curly braces could access these two arrays. In order to be able to use the (one and only) array after the if and if else clauses, you need to put the declaration of the variable outside of these “contexts”, i.e. before line 3 or as an instance variable outside the method within the class body. To avoid a null check (when neither the if nor the if else case apply and the array thus isn’t ever initialized), I would suggest declaring the array right at the beginning of the method and initializing it to be an empty array (then the for loop simply doesn’t run) like so:
void FindMate() //need to look at all mice, find a mice of the other gender, if the mouse is not pregnant and older than 1, then make the mouse pregnant
{
GameObject[] mates = new GameObject[0];
if (gender == 0) { mates = GameObject.FindGameObjectsWithTag(femaleMouse); }
else if (gender == 1) { mates = GameObject.FindGameObjectsWithTag(maleMouse); } //make a list of mates from all creatures with the mouseTag
// omitted for brevity
foreach (GameObject mate in mates) //lets look at every object with the mouseTag
{
// omitted for brevity
}
}
This is the reason standards exist. In C#, scopes (anything between { } ) should be in new lines, to make things more readable and allow the IDE to format your code.
Compare this:
if (gender == 0) { GameObject[] mates = GameObject.FindGameObjectsWithTag(femaleMouse); }
foreach (GameObject mate in mates) //lets look at every object with the mouseTag
{
// omitted for brevity
}
With this:
if (gender == 0)
{
GameObject[] mates = GameObject.FindGameObjectsWithTag(femaleMouse);
}
foreach (GameObject mate in mates) //lets look at every object with the mouseTag
{
// omitted for brevity
}
You can quickly and clearly see in the 2nd code that “mates” is local to the “if” block, and can’t be used in the “foreach” block since they are not at the same indentation (alignment), which makes it easy to find and fix the problem.
Use new lines, they’re free and it’ll make your code a lot more readable. Your future self will thank you trust me.