I’ve been on Unity for a very long time, yet I’ve come across the most common error.
I made a script to create a ship components store from a list of ScriptableObjects.
Here’s the ScriptableObjects:
<code>public class ShipComponent : ScriptableObject
[TextArea] public string shipDescription;
public ShipComponentType ComponentType;
public float Friction2AngularFrictionCoef;
public float Thrust2AngularThrustCoef;
public Sprite previewSprite;
<code>public class ShipComponent : ScriptableObject
{
public int shipID;
public string shipName;
[TextArea] public string shipDescription;
public ShipComponentType ComponentType;
public float Mass;
public float Friction;
public float Thrust;
public float Friction2AngularFrictionCoef;
public float Thrust2AngularThrustCoef;
public bool IsQuantum;
public Sprite previewSprite;
}
</code>
public class ShipComponent : ScriptableObject
{
public int shipID;
public string shipName;
[TextArea] public string shipDescription;
public ShipComponentType ComponentType;
public float Mass;
public float Friction;
public float Thrust;
public float Friction2AngularFrictionCoef;
public float Thrust2AngularThrustCoef;
public bool IsQuantum;
public Sprite previewSprite;
}
<code>public class DatabaseComponents : ScriptableObject
public string databaseName;
public List<Guild> databaseGuilds;
<code>public class DatabaseComponents : ScriptableObject
{
public int databaseID;
public string databaseName;
public List<Guild> databaseGuilds;
}
</code>
public class DatabaseComponents : ScriptableObject
{
public int databaseID;
public string databaseName;
public List<Guild> databaseGuilds;
}
<code>public class Guild : ScriptableObject
public List<GameObject> guildComponents;
<code>public class Guild : ScriptableObject
{
public int guildID;
public string guildName;
public List<GameObject> guildComponents;
}
</code>
public class Guild : ScriptableObject
{
public int guildID;
public string guildName;
public List<GameObject> guildComponents;
}
Here is the entire code where my problem is :
<code>using System.Collections.Generic;
public class ShipCreatorDEBUG : MonoBehaviour
[Header("Component Shop")]
[SerializeField] private Transform shopPanel;
[SerializeField] private GameObject guildNamePrefab;
[SerializeField] private GameObject rowPrefab;
private DatabaseComponents database;
private Dictionary<Guild, List<ShipComponent>> guildToListComponents;
guildToListComponents = GenerateShipComponentDictionary(database);
foreach (Transform trans in shopPanel)
Destroy(trans.gameObject);
foreach (var entry in guildToListComponents)
List<ShipComponent> shipComponents = entry.Value;
if (shipComponents == null || shipComponents.Count == 0) continue;
GameObject rowName = Instantiate(guildNamePrefab, shopPanel);
TMP_Text tmp = rowName.GetComponentInChildren<TMP_Text>();
tmp.text = guild.guildName;
int count = shipComponents.Count;
int rowAmount = Mathf.CeilToInt(count / 3f);
for (int i = 0; i < rowAmount; i++)
GameObject rowComponents = Instantiate(guildNamePrefab, shopPanel);
for (int j = 0; j < 3; j++)
int currentIndex = i * 3 + j;
if (currentIndex >= count) break;
Transform buttonTransform = rowComponents.transform.GetChild(j);
Button btn = buttonTransform.GetComponent<Button>();
ShipComponent sc = shipComponents[currentIndex]; // NullReferenceException here
btn.onClick.AddListener(() => SelectComponentInfo(sc));
Image image = buttonTransform.GetChild(0).GetComponent<Image>();
image.sprite = sc.previewSprite;
public void SelectComponentInfo(ShipComponent shipComponent)
public Dictionary<Guild, List<ShipComponent>> GenerateShipComponentDictionary(DatabaseComponents database)
Dictionary<Guild, List<ShipComponent>> guildComponentsDictionary = new Dictionary<Guild, List<ShipComponent>>();
foreach (Guild guild in database.databaseGuilds)
List<ShipComponent> shipComponentsList = new List<ShipComponent>();
foreach (GameObject componentPrefab in guild.guildComponents)
ShipComponentObject shipComponentObject = componentPrefab.GetComponent<ShipComponentObject>();
if (shipComponentObject != null)
shipComponentsList.Add(shipComponentObject.shipComponent);
guildComponentsDictionary[guild] = shipComponentsList;
return guildComponentsDictionary;
<code>using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class ShipCreatorDEBUG : MonoBehaviour
{
[Header("Component Shop")]
[SerializeField] private Transform shopPanel;
[SerializeField] private GameObject guildNamePrefab;
[SerializeField] private GameObject rowPrefab;
[SerializeField]
private DatabaseComponents database;
private Dictionary<Guild, List<ShipComponent>> guildToListComponents;
private void Start()
{
guildToListComponents = GenerateShipComponentDictionary(database);
GenerateShop();
}
// Shop
void GenerateShop()
{
foreach (Transform trans in shopPanel)
{
Destroy(trans.gameObject);
}
foreach (var entry in guildToListComponents)
{
Guild guild = entry.Key;
List<ShipComponent> shipComponents = entry.Value;
if (shipComponents == null || shipComponents.Count == 0) continue;
GameObject rowName = Instantiate(guildNamePrefab, shopPanel);
TMP_Text tmp = rowName.GetComponentInChildren<TMP_Text>();
tmp.text = guild.guildName;
int count = shipComponents.Count;
int rowAmount = Mathf.CeilToInt(count / 3f);
for (int i = 0; i < rowAmount; i++)
{
GameObject rowComponents = Instantiate(guildNamePrefab, shopPanel);
for (int j = 0; j < 3; j++)
{
int currentIndex = i * 3 + j;
if (currentIndex >= count) break;
Transform buttonTransform = rowComponents.transform.GetChild(j);
Button btn = buttonTransform.GetComponent<Button>();
ShipComponent sc = shipComponents[currentIndex]; // NullReferenceException here
btn.onClick.AddListener(() => SelectComponentInfo(sc));
Image image = buttonTransform.GetChild(0).GetComponent<Image>();
image.sprite = sc.previewSprite;
}
}
}
}
public void SelectComponentInfo(ShipComponent shipComponent)
{
// TODO
}
public Dictionary<Guild, List<ShipComponent>> GenerateShipComponentDictionary(DatabaseComponents database)
{
Dictionary<Guild, List<ShipComponent>> guildComponentsDictionary = new Dictionary<Guild, List<ShipComponent>>();
foreach (Guild guild in database.databaseGuilds)
{
List<ShipComponent> shipComponentsList = new List<ShipComponent>();
foreach (GameObject componentPrefab in guild.guildComponents)
{
ShipComponentObject shipComponentObject = componentPrefab.GetComponent<ShipComponentObject>();
if (shipComponentObject != null)
{
shipComponentsList.Add(shipComponentObject.shipComponent);
}
}
guildComponentsDictionary[guild] = shipComponentsList;
}
return guildComponentsDictionary;
}
}
</code>
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class ShipCreatorDEBUG : MonoBehaviour
{
[Header("Component Shop")]
[SerializeField] private Transform shopPanel;
[SerializeField] private GameObject guildNamePrefab;
[SerializeField] private GameObject rowPrefab;
[SerializeField]
private DatabaseComponents database;
private Dictionary<Guild, List<ShipComponent>> guildToListComponents;
private void Start()
{
guildToListComponents = GenerateShipComponentDictionary(database);
GenerateShop();
}
// Shop
void GenerateShop()
{
foreach (Transform trans in shopPanel)
{
Destroy(trans.gameObject);
}
foreach (var entry in guildToListComponents)
{
Guild guild = entry.Key;
List<ShipComponent> shipComponents = entry.Value;
if (shipComponents == null || shipComponents.Count == 0) continue;
GameObject rowName = Instantiate(guildNamePrefab, shopPanel);
TMP_Text tmp = rowName.GetComponentInChildren<TMP_Text>();
tmp.text = guild.guildName;
int count = shipComponents.Count;
int rowAmount = Mathf.CeilToInt(count / 3f);
for (int i = 0; i < rowAmount; i++)
{
GameObject rowComponents = Instantiate(guildNamePrefab, shopPanel);
for (int j = 0; j < 3; j++)
{
int currentIndex = i * 3 + j;
if (currentIndex >= count) break;
Transform buttonTransform = rowComponents.transform.GetChild(j);
Button btn = buttonTransform.GetComponent<Button>();
ShipComponent sc = shipComponents[currentIndex]; // NullReferenceException here
btn.onClick.AddListener(() => SelectComponentInfo(sc));
Image image = buttonTransform.GetChild(0).GetComponent<Image>();
image.sprite = sc.previewSprite;
}
}
}
}
public void SelectComponentInfo(ShipComponent shipComponent)
{
// TODO
}
public Dictionary<Guild, List<ShipComponent>> GenerateShipComponentDictionary(DatabaseComponents database)
{
Dictionary<Guild, List<ShipComponent>> guildComponentsDictionary = new Dictionary<Guild, List<ShipComponent>>();
foreach (Guild guild in database.databaseGuilds)
{
List<ShipComponent> shipComponentsList = new List<ShipComponent>();
foreach (GameObject componentPrefab in guild.guildComponents)
{
ShipComponentObject shipComponentObject = componentPrefab.GetComponent<ShipComponentObject>();
if (shipComponentObject != null)
{
shipComponentsList.Add(shipComponentObject.shipComponent);
}
}
guildComponentsDictionary[guild] = shipComponentsList;
}
return guildComponentsDictionary;
}
}
Here are the log results :
<code>NullReferenceException: Object reference not set to an instance of an object
ShipCreatorDEBUG.GenerateShop () (at Assets/Assets/Scripts/TestS/ShipCreatorDEBUG.cs:57)
ShipCreatorDEBUG.Start () (at Assets/Assets/Scripts/TestS/ShipCreatorDEBUG.cs:20)
<code>NullReferenceException: Object reference not set to an instance of an object
ShipCreatorDEBUG.GenerateShop () (at Assets/Assets/Scripts/TestS/ShipCreatorDEBUG.cs:57)
ShipCreatorDEBUG.Start () (at Assets/Assets/Scripts/TestS/ShipCreatorDEBUG.cs:20)
</code>
NullReferenceException: Object reference not set to an instance of an object
ShipCreatorDEBUG.GenerateShop () (at Assets/Assets/Scripts/TestS/ShipCreatorDEBUG.cs:57)
ShipCreatorDEBUG.Start () (at Assets/Assets/Scripts/TestS/ShipCreatorDEBUG.cs:20)
The only thing can be null is the shipComponents list, but it has 2 elements on it. It might be useless to send it because of this line :
<code>if (shipComponents == null || shipComponents.Count == 0) continue;
<code>if (shipComponents == null || shipComponents.Count == 0) continue;
</code>
if (shipComponents == null || shipComponents.Count == 0) continue;
Unless the problem is present but I don’t see it, as you can see, the values are non-null but I still get a NullReferenceException error.
Any idea where this problem might be coming from? The function is executed in runtime.
(reasking the question because it seems they don’t understand this is NOT a duplicate of the common NullReferenceException question)