-2

No matter what i change the parameters to, Instantiate() throws a NullReferenceException, even after it successfully instantiates the GameObject.

I've used Debug.Log on all the parameters to check if any of them are null, they aren'tDebug.Log returns false Yet still, the Instantiate function throws a NullReferenceExceptionNullReferenceException All of this is based on the assumption that the reason its throwing a NullReferenceException is because one of the parameters is null, but clearly something else is wrong. How do I fix this? The full code looks like this:

public class BattleSystem : MonoBehaviour
{
    public static Unit selected;

    public BattleState battleState;
    public GameState gameState;
    public GameObject baseUnit;
    public Vector2 playerPos, enemyPos;
    public Vector2 posOffset;
    public List<Effect> statusEffects = new();
    
    //-----------This is placeholder code----------
    public List<Unit> allyTeamUnits, enemyTeamUnits = new(3);
    //----Remember to add a loading mechanic------
    List<GameObject> playerTeamUnitsGO, enemyTeamUnitsGO;

    public GameObject canvas;

    private void Awake()
    {
        gameState = GameState.starting;
        SetupBattle();
    }
    IEnumerator Start()
    {
        yield return new WaitForSeconds(2f);
        battleState = BattleState.playerPassive;
    }

    void SetupBattle() //should be called at the start of the battle
    {
        Debug.Log("setup battle is called");
        for (int i = 0; i < allyTeamUnits.Count; i++)
        {
            Debug.Log(baseUnit == null);
            Debug.Log(playerPos == null);
            Debug.Log(Quaternion.identity == null);
            Debug.Log(canvas.transform == null);
            playerTeamUnitsGO[i] = Instantiate(baseUnit, playerPos, Quaternion.identity, canvas.transform); //This line throws NullReferenceException
            playerTeamUnitsGO[i].SetActive(true);
            playerTeamUnitsGO[i].GetComponent<Unit>().Init(allyTeamUnits[i]);
        }
        Debug.Log("info initialized");

        for (int i = 0; i < enemyTeamUnits.Count || i < 3; i++)
        {
            enemyTeamUnitsGO[i] = Instantiate(baseUnit, enemyPos, Quaternion.identity, canvas.transform); //spawning an enemy
            enemyTeamUnitsGO[i].SetActive(true);
            enemyTeamUnitsGO[i].GetComponent<Unit>().Init(enemyTeamUnits[i]);
        }
    }
}

baseUnit has a GameObject attached to it. After the Instantiate(), nothing after the exception runs. I've also tried changing the GameObject to a dummy one, but that didn't work either, and it still throws the exception.

derHugo
  • 83,094
  • 9
  • 75
  • 115
kale
  • 36
  • 7
  • `All of this is based on the assumption that the reason its throwing a NullReferenceException is because one of the parameters is null` ... don't make assumptions, [debug](https://docs.unity3d.com/Manual/ManagedCodeDebugging.html)! It is not the `Instantiate` throwing the exception (it wouldn't btw it would rather throw its own `ArgumentException` telling you you can not instantiate `null`) ... it is rather the `playerTeamUnitsGO` list not being initialized and being `null` -> `private readonly List playerTeamUnitsGO = new List();` – derHugo Jul 18 '23 at 11:29
  • And then you will still get an index out of bouns exception because if your list is empty you can not simply write to ` playerTeamUnitsGO[i]` .. you should rather store the instance reference and then `.Add` it to the list – derHugo Jul 18 '23 at 11:33

1 Answers1

1
//-----------This is placeholder code----------
public List<Unit> allyTeamUnits, enemyTeamUnits = new(3);
//----Remember to add a loading mechanic------

List<GameObject> playerTeamUnitsGO, enemyTeamUnitsGO; 

as you can see List playerTeamUnitsGO, enemyTeamUnitsGO; don't exist at all therefore when unity tries to Instantiate an object at index there are no list to work with

if you want you can Instantiate your object then adding it to a list Like this

GameObject ob = Instantiate(baseUnit, playerPos, Quaternion.identity, canvas.transform);

playerTeamUnits.Add(ob);

playerTeamUnitsGO[i].SetActive(true);
DevAm00
  • 369
  • 2
  • 10
  • 1
    the lists do not contain `0` elements ... as you say they are not initialized => They don't exist at all and both fields are `null`! There is also no need to serialize the lists (should be `SerializeField` btw) .. you just need to make sure you initialize them (which the Inspector does for you, yes, but that shouldn't be the reason why you serialize them ;) ) – derHugo Jul 18 '23 at 11:34
  • 100% true the list is empty and the code is trying to grab the element at index 0 which doesn't exist ,i edited my answer thanks for noticing my mistake – DevAm00 Jul 18 '23 at 12:00
  • ignore all my previous responses, the error was thrown by the list, answer marked as accepted – kale Jul 18 '23 at 13:16