2
\$\begingroup\$

I wouldn't say i'm new to unity or programming in general.. but right now i feel so stupid.

I have a simple enemy script. I instantiate object with another script, calling SettingUpCreep and giving it a list of waypoints. Then happens update object should move from one waypoint to another. But look at information in Console.

enter image description here

What's wrong with waypoints.Count in Update? Why does it increased? And it works only if list and nextPos are public. If i set it to private then other methods can't access it. There's nothing in it. enter image description here

What's happening and why? I can't understand. Have i've done something wrong or just need more sleep?

List<Vector3> waypoints;
Vector3 nextPos;
int currentPoint = 1;

private void Update()
{
    moveToNextWaypoint();
}

void moveToNextWaypoint()
{
    Debug.Log("Update");
    Debug.Log("WP.count " + waypoints.Count + " NP" + nextPos);

    if (transform.position == nextPos)
    {
        if (currentPoint == waypoints.Count)
        {
            gameObject.SetActive(false);
        }
        else
        {
            currentPoint++;
            nextPos = waypoints[currentPoint];
        }
    }
    transform.position = Vector3.MoveTowards(transform.position, nextPos, 5 * Time.deltaTime);
}

public void SettingUpCreep(List<Vector3> list)
{
    Debug.Log("list.Count " + list.Count);
    List<Vector3> waypoints = new List<Vector3>(list.Count);

    for (int i = 0; i < list.Count; i++)
    {
        waypoints.Add(list[i]);
    }
    nextPos = waypoints[1];
    transform.position = waypoints[0];

    Debug.Log("WP.count " + waypoints.Count + " NP" + nextPos);
}
\$\endgroup\$
2
  • 1
    \$\begingroup\$ We can't see where SettingUpCreep is called or what's being passed to it, so we don't have enough information to diagnose this problem. Please ensure you're providing a minimal, complete, verifiable example - ie. you could show only the content of this question to a stranger, and without any follow-up questions/clarifications they'd be able to reproduce the problem you're seeing in a new empty project. \$\endgroup\$
    – DMGregory
    Feb 1, 2019 at 0:38
  • \$\begingroup\$ Possible duplicate of NullReferenceException in Unity \$\endgroup\$
    – Philipp
    Feb 1, 2019 at 12:16

1 Answer 1

7
\$\begingroup\$

This is a concept called Variable Shadowing and is a common problem with newer developers. Variables have a scope that represents where they exist and can be manipulated. A class-level variable (such as the three defined at the top of your file) can be used anywhere within the class, regardless of access level. In addition, we can tell the code to allow or disallow access to other parts of code with the public, private, internal, sealed, etc keywords.

However, there's also a scope beneath the class level: Method Level scope. There is not a rule that requires variables defined at the class level and the method level not to share a name (when they get translated into lower level code, that name disappears anyway, so the computer doesn't care). So your line of code that says

List<Vector3> waypoints = new List<Vector3>(list.Count);

is really defining a method-scoped variable call waypoints. This is not the same variable as your class-level variable also called waypoints. If you wanted to use the class-scp[ed variable instead, remove the variable definition of List from this line of code. That will tell the compiler to use the class-scoped variable instead. This may not fix all your issues, but it is definitely one problem.

The full stack trace of your error would be helpful to figure out any others.

EDIT: I was thinking about this a little further, and this example shows why having a coding standard for variable naming is valuable.

For example, in my team's coding standard, there is a visible difference between the names of variables.

Properties (aka public, class-scope variables) are capitalized (e.g. Waypoints)

private class-level variables are camel case with an underscore (e.g. _waypoints)

method-scoped variables are camel case. (e.g. waypoints).

If you followed a standard like this, it would be more obvious which of the variables you were assigning to. Naming things the exact same is still not a good thing to do, but sometimes we aren't paying attention and fail to realize we're doing it.

\$\endgroup\$
3
  • 1
    \$\begingroup\$ Ahhh, good catch! I totally missed the redefinition there! :) Here's another recent answer about similar variable shadowing issues \$\endgroup\$
    – DMGregory
    Feb 1, 2019 at 16:08
  • \$\begingroup\$ Most compilers that I've used will flag this as a warning (or error) when the compile-time flags are set. \$\endgroup\$ Feb 21, 2019 at 23:34
  • 1
    \$\begingroup\$ @PatrickHughes in my experience, the vast majority of developers ignore warnings :) \$\endgroup\$ Feb 22, 2019 at 14:39

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .