Instantiate returns Null when instantiating an gameObject from a list of GameObjects

Good Day everyone!

A Friend and I are building a card game and right now we’re working on a deck manager for the game. Our deck manager is made up of a list of card gameobjects from which our script will pick a random set of 4 cards which will go into the player’s hand. This first part of our code will check if player has any cards on hand:

void GenerateDeck()
    {    
        if (cardsOnHand.Count == 0)
        {
            for (int i = 0; i < cardLocation.Length; i++)
            {
                CardGenerator();
                placeCard = cardLocation[i];
                Debug.Log("added cards to hand");
            }
        }
    }

cardLocation is an array of transforms which serve as the cards’ location on screen. And this next one will pick a random card from the deck.

  void CardGenerator()
    {
        //cards takes a random card in the deck

        cards = UnityEngine.Random.Range(0, cardsOnDeck.Count - 1);

        //cards tells instantiate that the card to instantiate is the random card

        Debug.Log("Cards on deck: " + cardsOnDeck.Count);
        Debug.Log("Card number " + cards + " returned");

        cardsOnHand.Add(cardsOnDeck[cards]);

        Debug.Log("Cards on Hand: " + cardsOnHand.Count);
        Instantiate(cardsOnDeck[cards], placeCard.position, Quaternion.identity);
    }

The script is able to detect that there are card game objects in the deck and pick a random card and add it to the hand, but the Instantiate returns a NullReferenceException. I already loaded the card game objects to the list in the inspector when this happened.

You’re getting a NullReferenceException because you’re calling CardGenerator() before setting placeCard, so placeCard is null when you do the Instantiate (specifically the NRE is caused by trying to access placeCard.position).

Also if you’ll permit me to complain about just a couple tiny naming things: for cardLocation, since it’s an array/list, try to name it cardLocations for clarity… and for “cards”, name that something like “cardIndex”, because at first I thought it was an array due to its name.

1 Like

couldn’t decipher your code, I don’t know if this is only pseudo, but I have no clue what to expect from cardsOnDeck
I absolutely can’t tell whether it’s null at this index or not.

anyway your usage of UnityEngine.Random.Range is wrong, as you’re excluding the last card.
that method is inclusive exclusive and should be used without - 1.

Good catch by orionsyndrome, their advice is correct, but I think they just mixed up the words, because the max is exclusive not inclusive.

It’s also worth noting that Range() is only exclusive when dealing with integers, when dealing with floats, the max is inclusive, so it could be returned.

1 Like

true, I meant the opposite. I’ll have to edit that, it’s confusing already

As a matter of fact, both methods are exclusive. It’s just that in practical terms, float variant of Range() can return max * 0.99999999 which is effectively the same as max, but it’ll never actually produce a value of max * 1.0
It’s not that important really, but explains the weird difference between the two methods. There is none.

1 Like

This solved it. Thanks man!

Thank you as well for the feedback, I’ll keep all of these in mind.