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;
             }

         }
     }
 }
R.I
  • 9
  • 3
  • 2
    Did you use the debugger? Does it show a null reference? how do you initialize `transform` within `GameObject` and and `position` within that? – JHBonarius Nov 08 '19 at 19:55
  • 1
    @JHBonarius those are types of Unity: [`GameObject`](https://docs.unity3d.com/ScriptReference/GameObject.html) 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](https://stackoverflow.com/a/58773473/7111561) below) – derHugo Nov 08 '19 at 20:44

2 Answers2

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];
}
derHugo
  • 83,094
  • 9
  • 75
  • 115
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.

  • 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. – Dortimer Nov 08 '19 at 20:34
  • 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. –  Nov 08 '19 at 20:39
  • Ah, my mistake. I should have read the code more closely. – Dortimer Nov 08 '19 at 20:48