0

I am constantly getting a Null Reference error when I try to change the positions of the game objects stored in an array. I have attached this script to a GameObject. This is my current code:

public class transaction : MonoBehaviour
 {
     private GameObject[] traders = new GameObject[9];
     private Vector3[] positions = new Vector3[9];
     void Start()
     {
         for (int i = 1; i < 9; i++)
         {
             GameObject pos = GameObject.Find("Wall"+i);
             GameObject trader = GameObject.Find("Trader" + i);
             this.positions[i] = pos.transform.position;
             this.traders[i] = trader;

         }
     }

     // Update is called once per frame
     void Update()
     {
         SetPositions();
     }

     private void SetPositions()
     {
         int randPos;
         bool[] assigned = new bool[8];
         int count = 0;

         while (count < 8)
         {
             randPos = Random.Range(0, 8);
             if (!assigned[randPos])
             {

                //error occurs here
                 this.traders[count].transform.position += this.positions[randPos] - new Vector3(0f, 0f, 1f);
                 assigned[randPos] = true;
                 count++;
             }
             else
             {
                 continue;
             }

         }
     }
 }
2
  • 2
    Did you use the debugger? Does it show a null reference? how do you initialize transform within GameObject and and position within that? Commented Nov 8, 2019 at 19:55
  • 1
    @JHBonarius those are types of Unity: GameObject has a property transform which is always initialized with the associated Transform reference. Which again has a property Vector3 position. Vector3 is a struct and never null ;) The isssue is rather the never initialized index 0 (see my answer below) Commented Nov 8, 2019 at 20:44

2 Answers 2

1

You initialize the array indexes 1-9 with values via Find. Arrays in C# have a 0-based index.

From your description it sounds like these Find calls succeed since you say the exception is thrown when you assign a new position.


The problem is: you never initialize traders[0] since you started at index 1.

So if the random index hits 0 you get a NullReferenceException since traders[0] will always be null.

Also, your random range returns one index too few, since the second parameter is exclusive.

You should change it to

private GameObject[] traders = new GameObject[8];
 private Vector3[] positions = new Vector3[8];
 void Start()
 {
     for (var i = 0; i < 8; i++)
     {
         var pos = GameObject.Find("Wall"+ (i+1).ToString());
         var trader = GameObject.Find("Trader" + (i+1).ToString());
         positions[i] = pos.transform.position;
         traders[i] = trader;
     }
 }

or, if you want the naming clearer:

     for (var i = 1; i < 9; i++)
     {
         var pos = GameObject.Find("Wall"+ i);
         var trader = GameObject.Find("Trader" + i);
         positions[i-1] = pos.transform.position;
         traders[i-1] = trader;
     }

However, a while loop is not the best solution here. You should rather iterate once over the shuffled positions like e.g.

Random rnd=new Random();
var randomPositions = positions.OrderBy(x => rnd.Next()).ToArray();

for(var i = 0; i < 8; i++)
{
    traders[i].transform.position = randomPositions[i];
}
Sign up to request clarification or add additional context in comments.

Comments

0
  • Arrays start from [0]...(in your case to [8]). So in loop start from i = 0 and i<traders.Length. You should learn about arrays, lists and Collections from youtube it's very important and basic.

  • I propose to create that from beginning. I would create class that handle movement for this objects and if you spawn/instantiate objects like a bullets you can attach the script as a component to them ( AddComponent() ). If you have them on a scene then you can just create that script and attach manually the script into this objects in the inspector. It's easier faster and fail less.

3 Comments

They'll be skipping over the first item in those arrays, but otherwise that's not the issue. I think they'd probably get an IndexOutOfBounds exception if that were the case.
In Start you get a reference to wall + i (but not [0]). In Update you try to move the object [0] from the array. Here is the problem I think.
Ah, my mistake. I should have read the code more closely.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.