После перехода в сцену меню и обратно в сцену игры возникает ошибка Coroutine
У меня проблема с повторным входом в игровую сцену после сцены меню.
При первом запуске все работает нормально, но стоит вернуться в сцену с меню, и обратно в игровую, появляется ошибка:
MissingReferenceException: The object of type 'GameControl' 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.
Я понимаю, о чем идет речь в ошибке, но понятия не имею, почему возникает эта ошибка, ведь объект существует на сцене с самого начала сцены.
public class GameControl : MonoBehaviour{
private static GameControl _gameControlInstance;
[SerializeField] private GameObject _playerForwardPref;
[SerializeField] private GameObject _playerForward;
[SerializeField] private GameObject _playerGoalkeeperPref;
private GameObject _playerGoalkeeper;
private GameObject _targetPoint;
private GameObject _savePoint;
private Text _resulKick;
[SerializeField] private AudioClip _voicesFans;
private AudioSource _whistle;
private AudioSource _audioSource;
private Animator _animResultKick;
private bool _isKickForward = true;
private bool _endGame = false;
[SerializeField] private List<int> Player1 = new List<int>();
[SerializeField] private List<int> Player2 = new List<int>();
private void Awake()
{
if (SceneManager.GetActiveScene().name == "GameScene")
{
Application.targetFrameRate = 60;
DontDestroyOnLoad(gameObject);
if (_gameControlInstance == null)
{
_gameControlInstance = this;
}
else
{
Destroy(gameObject);
}
}
}
void OnEnable()
{
StopAllCoroutines();
SceneManager.sceneLoaded += OnSceneLoaded;
}
void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
if (scene.name == "GameScene")
{
_targetPoint = GameObject.FindGameObjectWithTag("TargetPoint");
_savePoint = GameObject.FindGameObjectWithTag("DirectionPoint");
_resulKick = GameObject.FindGameObjectWithTag("ResultKickText").GetComponent<Text>();
_animResultKick = _resulKick.GetComponent<Animator>();
_whistle = GameObject.FindGameObjectWithTag("whistle").GetComponent<AudioSource>();
if (!_isKickForward)
{
_targetPoint.SetActive(false);
}
else
{
_savePoint.SetActive(false);
}
SpawnPlayers();
StartCoroutine(StartGameDelay()); // Здесь возникает ошибка
}
}
private void Start()
{
_audioSource = gameObject.GetComponent<AudioSource>();
_audioSource.clip = _voicesFans;
_audioSource.Play();
}
/* Go to the main menu scene */
private IEnumerator EndGame(float delay)
{
yield return new WaitForSeconds(delay);
SceneManager.MoveGameObjectToScene(gameObject, SceneManager.GetActiveScene());
_gameControlInstance = null;
SceneManager.LoadSceneAsync(1, LoadSceneMode.Single);
}
private IEnumerator StartGameDelay()
{
yield return new WaitForSeconds(3.0f);
_whistle.Play();
_playerForward.SendMessage("StartGame", true);
}
Ответы (1 шт):
Спустя 2 дня, я наконец нашел свою ошибку (довольно глупую). Решение моей проблемы заключалось в том, что я добавлял в методе OnEnable делегат SceneManager.sceneLoaded и цеплял к нему метод OnSceneLoaded, однако я забыл создать метод OnDisable и отцепить метод OnSceneLoaded. Все оказалось очень просто, и было написано в официально документации Unity. Вот код решения:
void OnDisable()
{
SceneManager.sceneLoaded -= OnSceneLoaded;
}
Надеюсь эта тема поможет кому то, кто столкнулся с такой же проблемой.