1

I'm trying to cycle through a 2D array of card objects and instantiate them in my Unity scene. However, I'm getting a Null reference exception when trying to instantiate them. Here is the code that instantiates the objects:

//Setting up initial board
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 4; j++){
            //Checked with debug.log, this should work Debug.Log (board[j, i].name);
            Debug.Log(board[j, i].name);
            temp = Instantiate(board[j,i]) as GameObject;
            CardScript cs = temp.GetComponent<CardScript>();
            objectBoard[j, i] = cs;
            //Setting locations of the cards
            objectBoard[j, i].transform.position = new Vector3(30 * j + 20, 50 * i +   70, 0);
        }
    }

The error occurs in the line 'CardScript cs = new.... I originally had the error in the temp = Instantiate... line, when the code was GameObject temp = Instantiate.... It fixed when I made temp a private GameObject variable in the code. I don't think I can do that with this one, because I need to have a reference to each individual object I'm instantiating.

Full Code:

public class MatchScript : MonoBehaviour {

public CardScript[] potentialCards;

private CardScript[,] board;
private CardScript[,] objectBoard;
private List<CardScript> entries;
private GameObject temp;


// Use this for initialization
void Start () {
    entries = new List<CardScript> ();
    objectBoard = new CardScript[4,3];
    board = new CardScript[4, 3];
    foreach (CardScript c in potentialCards)
        entries.Add (c);
    foreach (CardScript c in potentialCards)
        entries.Add (c);

    //Loading up the board
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 4; j++){
            int k = Random.Range(0, entries.Count);
            board[j, i] = entries[k];

            entries.RemoveAt(k);
        }
    }

    //Setting up initial board
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 4; j++){
            //Checked with debug.log, this should work Debug.Log (board[j, i].name);
            Debug.Log(board[j, i].name);
            temp = Instantiate(board[j,i]) as GameObject;
            CardScript cs = temp.GetComponent<CardScript>();
            objectBoard[j, i] = cs;
            //Setting locations of the cards
            objectBoard[j, i].transform.position = new Vector3(30 * j + 20, 50 * i + 70, 0);
        }
    }
}

// Update is called once per frame
void Update () {

}
Maxw3ll
  • 61
  • 1
  • 6
  • The C# `as` operator is a run time safe cast - if the type cannot be cast to the destination type, rather than throw an `InvalidCastException`, the operator returns `null`. You haven't shown the code for `Instantiate(board[j,i])`, which is the method's result that you're casting to `GameObject`. If the result of that method is not an instance of `GameObject`, `cs` will be set to `null`, and your next line will *always* throw a null reference exception when you attempt to invoke `GetComponent()` on a null reference. – Preston Guillot Oct 12 '14 at 00:33
  • Sorry, Unity has a built in function for Instantiate, I didn't write it. – Maxw3ll Oct 12 '14 at 01:29
  • possible duplicate of [What is a NullReferenceException and how do I fix it?](http://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-do-i-fix-it) – LearnCocos2D Feb 16 '15 at 10:49

2 Answers2

1

I'm not really sure why this happen. But you can fix this by change

temp = Instantiate(board[j,i]) as GameObject;

to

temp = Instantiate(board[j,i].gameObject) as GameObject;
apxcode
  • 7,367
  • 7
  • 25
  • 39
vsenik
  • 518
  • 5
  • 12
  • This is essentially what I ended up doing to make it work. You can't pass in a child of a Gameobject to Instantiate without it returning null. I just changed the unity variable that came in to a GameObject, passed in the same CardScript, and pulled out the CardScript piece after instantiating it. – Maxw3ll Oct 13 '14 at 04:57
1

"expression as Type" clause returns expression cast to Type if and only if actual type of expression is derived from Type, otherwise it returns null.

Instantiate makes an independent copy of an object passed, which, naturally, has type CardScript. Now, there is some possible misunderstanding: GameObject is a base class for all "entities in Unity scenes", but that doesn't include all classes you create on your own. If CardScript is a class you created and it doesn't inherit any class explicitly, then it inherits System.Object (which is base class for all C# classes).

If CardScript is derived from GameObject, then you should probably provide that class as well.

Abstraction
  • 1,059
  • 11
  • 22