Hello everyone! I've recently started making a 2D RPG Top Down game, a sort of Dungeon Crawler, following this YouTube guide: https://www.youtube.com/watch?v=b8YUfee_pzc&list=WL&index=5&ab_channel=Epitome
I'm currently at the Floating Text section (2:43:00) onwards, but I get this error everytime I collide with a chest. The sprite changes to the empty chest, but the floating text that should say “+5 Gold!” doesn't appear. I'll attach my scripts. From what I understood, I think that the FloatingText variable doesn't get created properly in the GetFloatingText function, which eturns a null value, and this leads to the NullReferenceException error when trying to assign values like “msg” to it. I want to clarify that I attached everything in the right GameObject slots in the Inspector. The error should be around GameManager.cs or FloatingTextManager.cs, the other scripts work fine in other scenarios.
NullReferenceException: Object reference not set to an instance of an object
FloatingTextManager.Show (System.String msg, System.Int32 fontSize, UnityEngine.Color color, UnityEngine.Vector3 position, UnityEngine.Vector3 motion, System.Single duration) (at Assets/Scripts/FloatingTextManager.cs:23)
GameManager.ShowText (System.String msg, System.Int32 fontSize, UnityEngine.Color color, UnityEngine.Vector3 position, UnityEngine.Vector3 motion, System.Single duration) (at Assets/Scripts/GameManager.cs:39)
Chest.OnCollect () (at Assets/Scripts/Chest.cs:16)
Collectable.OnCollide (UnityEngine.Collider2D coll) (at Assets/Scripts/Collectable.cs:12)
Collidable.Update () (at Assets/Scripts/Collidable.cs:25)
EDIT: I solved the problem by changing the FloatingText prefab to a Legacy Text instead of the default TextMeshPro.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Collidable : MonoBehaviour
{
public ContactFilter2D filter;
private BoxCollider2D boxCollider;
private Collider2D[] hits = new Collider2D[10];
protected virtual void Start()
{
boxCollider = GetComponent<BoxCollider2D>();
}
protected virtual void Update()
{
boxCollider.OverlapCollider(filter, hits);
for (int i = 0; i < hits.Length; i++)
{
if (hits[i] == null)
continue;
OnCollide(hits[i]);
hits[i] = null;
}
}
protected virtual void OnCollide(Collider2D coll)
{
Debug.Log(coll.name);
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Collectable : Collidable
{
protected bool collected;
protected override void OnCollide(Collider2D coll)
{
if (coll.name == "Player")
OnCollect();
}
protected virtual void OnCollect()
{
collected = true;
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Chest : Collectable
{
public Sprite emptyChest;
public int goldAmount = 5;
protected override void OnCollect()
{
if (!collected)
{
collected = true;
GetComponent<SpriteRenderer>().sprite = emptyChest;
GameManager.instance.ShowText("+" + goldAmount + " Gold!", 16, Color.yellow, transform.position, Vector3.up * 50, 1.5f);
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class GameManager : MonoBehaviour
{
public static GameManager instance;
private void Awake()
{
if (GameManager.instance != null)
{
Destroy(gameObject);
return;
}
instance = this;
SceneManager.sceneLoaded += LoadState;
DontDestroyOnLoad(gameObject);
}
// Resources
public List<Sprite> playerSprites;
public List<Sprite> weaponSprites;
public List<int> weaponPrices;
public List<int> xpTable;
// References
public Player player;
// public Weapon weapon; ...
public FloatingTextManager floatingTextManager;
public int gold;
public int experience;
public void ShowText(string msg, int fontSize, Color color, Vector3 position, Vector3 motion, float duration)
{
floatingTextManager.Show(msg, fontSize, color, position, motion, duration);
}
public void SaveState()
{
string s = "";
s += "0" + "|";
s += gold.ToString() + "|";
s += experience.ToString() + "|";
s += "0";
PlayerPrefs.SetString("SaveState", s);
}
public void LoadState(Scene s, LoadSceneMode mode)
{
if (!PlayerPrefs.HasKey("SaveState"))
return;
string[] data = PlayerPrefs.GetString("SaveState").Split('|');
// Change player skin
gold = int.Parse(data[1]);
experience = int.Parse(data[2]);
// Change weapon level
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class FloatingTextManager : MonoBehaviour
{
public GameObject textContainer;
public GameObject textPrefab;
private List<FloatingText> floatingTexts = new List<FloatingText>();
private void Update()
{
foreach (FloatingText txt in floatingTexts)
txt.UpdateFloatingText();
}
public void Show(string msg, int fontSize, Color color, Vector3 position, Vector3 motion, float duration)
{
FloatingText floatingText = GetFloatingText();
floatingText.txt.text = msg;
floatingText.txt.fontSize = fontSize;
floatingText.txt.color = color;
floatingText.go.transform.position = Camera.main.WorldToScreenPoint(position);
floatingText.motion = motion;
floatingText.duration = duration;
floatingText.Show();
}
private FloatingText GetFloatingText()
{
FloatingText txt = floatingTexts.Find(t => !t.active);
if (txt == null)
{
txt = new FloatingText();
txt.go = Instantiate(textPrefab);
txt.go.transform.SetParent(textContainer.transform);
txt.txt = txt.go.GetComponent<Text>();
floatingTexts.Add(txt);
}
return txt;
}
}