- Home /
GameManager trying to access method from deleted GameManager via the InvokeRepeating() function
When GameManager tries to access my GenerateWave method, that is inside the GameManager itself, with the InvokeRepeating function, it gives the following error:
MissingReferenceException: The object of type 'GameManager' has been destroyed but you are still trying to access it.
Your script should either check if it is null or you should not destroy the object.
UnityEngine.MonoBehaviour.InvokeRepeating (System.String methodName, System.Single time, System.Single repeatRate) (at <a9810827dce3444a8e5c4e9f3f5e0828>:0)
GameManager.StartEnemyGeneration () (at Assets/Scripts/Game/GameManager.cs:66)
GameManager.HandleBossDeath () (at Assets/Scripts/Game/GameManager.cs:50)
Boss.Die () (at Assets/Scripts/Game/Boss.cs:41)
Enemy.TakeDamage (System.Int32 damage) (at Assets/Scripts/Game/Enemy.cs:32)
Enemy.OnTriggerEnter2D (UnityEngine.Collider2D other) (at Assets/Scripts/Game/Enemy.cs:45)
First I'm in my MainMenu scene, the I press play and load the GameScene. In the GameScene a boss spawns, and when I kill it, the game continues with waves of Monsters, but if instead I die, either by the the boss or the monsters, the MainMenu loads again, and the GameScene is deleted. If I once again press play, after have died once, and then kill the boss, then the error above comes, and the boss just stands still, instead of dying so the game can continue. I use Unity version 2020.1.6f1 on Windows 10, and I use the Universal Render Pipeline.
It's only the InvokeRepeating and Invoke functions that creates the errors, no other methods or functions inside the GameManager creates the error. The GameManager is loaded with the GameScene, and is not instantiated.
It's like the InvokeRepeating function tries to access the GameManager from the previous GameScene, but it shouldn't
My GameManager script:
using System;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
public class GameManager : MonoBehaviour
{
public static Vector2 bottomLeft;
public static Vector2 topRight;
[SerializeField]
Player player;
[SerializeField]
Monster monster;
[SerializeField]
GameObject wave;
[SerializeField]
Boss boss;
[SerializeField]
Text score;
int coins = 0;
int monsterWaveCount = 0;
int wavesLeft;
float monsterSpeed = 1f;
// Start is called before the first frame update
void Start()
{
bottomLeft = Camera.main.ScreenToWorldPoint(new Vector2(0, 0));
topRight = Camera.main.ScreenToWorldPoint(new Vector2(Screen.width, Screen.height));
Player p = Instantiate(player) as Player;
p.OnGainCoing += HandleGainCoin;
p.OnPlayerDied += HandlePlayerDeath;
Boss.OnBossDied += HandleBossDeath;
wavesLeft = monsterWaveCount;
StartEnemyGeneration();
}
private void HandleBossDeath()
{
monsterSpeed++;
monsterWaveCount++;
wavesLeft = monsterWaveCount;
StartEnemyGeneration();
}
private void HandlePlayerDeath()
{
SceneManager.LoadScene(0, LoadSceneMode.Single);
}
void HandleGainCoin()
{
coins++;
score.text = coins.ToString();
}
void StartEnemyGeneration()
{
InvokeRepeating("GenerateWave", 0f, 4f);
}
void GenerateBoss()
{
Vector2 bossPos = new Vector2(0, topRight.y + 2);
Quaternion bossRot = new Quaternion(0, 0, 0.258819103f, 0.965925813f);
Instantiate(boss, bossPos, bossRot, transform);
}
void GenerateWave()
{
if (wavesLeft == 0)
{
CancelInvoke();
Invoke("GenerateBoss", 2f);
return;
}
wavesLeft--;
GameObject monsterWave = Instantiate(wave, Vector2.zero, Quaternion.identity, transform);
for (int i = 0; i < 5; i++)
// i: 0.5, 1.5, 2.5, 3.5, 4.5
{
float x = (i + 0.5f) / 5;
Vector2 pos = Camera.main.ScreenToWorldPoint(new Vector2 (Screen.width * x, Screen.height));
pos += Vector2.up * monster.transform.localScale.y;
Monster monsterGO = Instantiate(monster, pos, Quaternion.identity, monsterWave.transform) as Monster;
monsterGO.SetSpeed(monsterSpeed);
}
}
}
I've searched the Internet for hours without any luck..:/