I do a 2d Tavère-defens, I decided to make a constructor for creating towers conveniently, but I encountered the error NullReferenceException: Object reference not set to an instance of an object assignment to the sprite tower and characteristics (in second class, line selftower = gl.AllTowers [(int)selftype]; just below.

The problem is gl or FindObjectOfType<GameLogic>(); since it is they who return null , but that’s why they don’t work, is not obvious to me. I also tried GetComponent<GameLogic>().AllTowers [(int)selftype] but it didn't help either. I am almost 100% sure that my problem is in some minor error, which I do not notice, please take a fresh look ...

There are two classes:

Constructor:

 using System.Collections; using System.Collections.Generic; using UnityEngine; public class Tower{ public float range,Cooldown; public Sprite Spr; public Tower(float range, float cd,string path){ this.range = range; Cooldown = cd; Spr = Resources.Load<Sprite> (path); } } public class Towerprojectile{ } public enum TypeTower{ First_tower,Second_tower } public class GameLogic : MonoBehaviour { public List<Tower> AllTowers = new List<Tower>(); public void Awake(){ AllTowers.Add (new Tower (40, 0.3f,"TowerSpr/First")); AllTowers.Add (new Tower (70, 0.9f,"TowerSpr/Second")); } } 

Tower logic class:

 using System.Collections; using System.Collections.Generic; using UnityEngine; public class Towersrc : MonoBehaviour { public GameObject Projectile; GameLogic gl; Tower selftower; public TypeTower selftype; private void Start(){ gl = FindObjectOfType<GameLogic>(); selftower = gl.AllTowers [(int)selftype]; GetComponent<SpriteRenderer> ().sprite = selftower.Spr; } 

How to implement Initialize (2nd method I tried):

 public void Initialize(){ AllTowers.Add (new Tower (40, 0.3f, "TowerSpr/First")); AllTowers.Add (new Tower (70, 0.9f, "TowerSpr/Second")); } 

In Tower:

 gl = FindObjectOfType<GameLogic>(); // GetComponent<GameLogic> ().Initialiaze (); gl.Initialize(); // selftower = GetComponent<GameLogic>().AllTowers [(int)selftype]; selftower = gl.AllTowers[(int)selftype]; 

Thank you for your attention, if necessary, I can give a link to the project githab.

  • The point is not the AllTowers empty list, but the zero reference gl . - Igor
  • @Igor hmm, but what is the error with gl ? I assumed that the problem was with gl and addressed through GetComponent<GameLogic>().AllTowers [(int)selftype] but that didn't help either. Or was there the same error? - Anton Kovalenko
  • GameLogic an object of this type created somewhere? - Igor
  • @Igor GameLogic gl; in the second class, GameLogic is the name of the class in which I have a constructor. - Anton Kovalenko
  • GameLogic gl; is a variable declaration. Is there an instance of the new GameLogic() class new GameLogic() ? - Igor

1 answer 1

Your GameLogic component must be added to the scene and present in it before creating the towers. It is initiated by you on Awake and in theory should work before it is called in Start at the tower. Your constructor as far as I understand it should be the only one in the scene, you can look towards the singleton and create a link to the constructor in the class (I mean to yourself) in order to get access to the constructor in any class without using Find .

 public class GameLogic : MonoBehaviour { public List<Tower> AllTowers = new List<Tower>(); public static GameLogic instance = null; public void Awake(){ if (instance) { Destroy(this); return; } instance = this; AllTowers.Add (new Tower (40, 0.3f,"TowerSpr/First")); AllTowers.Add (new Tower (70, 0.9f,"TowerSpr/Second")); } } 

This is faster and it is possible at the time of initialization to check that the second object with the constructor in the scene was not accidentally created. And in the towers we appeal to it like this GameLogic.instance.AllTowers [(int)selftype]