Расширение
Исключение, которое вы получаете, говорит не об объекте MazeKey
, а о компоненте MazeDirectives
.
К сожалению, вы нажали самую важную информацию в комментариях:
private void Awake()
{
MazeGenerator.OnMazeReady += StartDirectives;
}
так что OnMazeReady
кажется static
и не является экземпляром, поэтому он не будет уничтожен при загрузке новой сцены, но останется нетронутым в новой сцене!
При вызове
MazeGenerator.OnMazeReady += StartDirectives;
вы добавляете вызов к методу StartDirectives
экземпляра MazeDirectives
в качестве слушателя этого события static
.
Теперь, когда вы перезагружаете Scene all GameObject
s и, следовательно, их экземпляры компонентов уничтожаются
=> как и экземпляр MazeGenerator
... НО событие static
OnMazeReady
равно не уничтожено!
, поэтому после следующего Awake
вызова у вас теперь есть два слушателя
- Один из "второй" / новой загруженной сцены
- Все еще«старый», который вы добавили в первый раз
Но с момента появления MazeDirectives
вы добавилиПервый слушатель для уничтожается, когда сцена перезагружается и генерируется новый экземпляр, вы получаете это исключение
MissingReferenceException: объект типа 'MazeDirectives' был уничтожен, но вы все еще пытаетесь получить к нему доступ.Ваш сценарий должен либо проверить, является ли он нулевым, либо вы не должны уничтожать объект.
, когда метод пытается получить доступ к значению transform
уничтоженного экземпляра.
Solution 1a
Таким образом, вы должны удалить прослушиватель при уничтожении экземпляра
private void OnDestroy()
{
MazeGenerator.OnMazeReady -= StartDirectives;
}
Solution 1b
или перезаписать его только одним слушателем наtime
private void Awake()
{
MazeGenerator.OnMazeReady = StartDirectives;
}
этот второй подход, очевидно, полезен только тогда, когда нет другого экземпляра или класса, слушающего это событие.Вопрос в том, какой смысл использовать событие, чем?И я бы в любом случае удалил его, если бы не нуждался, просто чтобы быть уверенным
private void OnDestroy()
{
MazeGenerator.OnMazeReady = null;
}
Решение 2
Я бы предпочел это решение.
Не делатьMazeGenerator.OnMazeReady
статический вообще.Так или иначе, я вижу, что вы используете шаблон Singleton, например, в
MazeGenerator.instance.mazeGoalPosition
, вместо этого вы можете просто сделать OnMazeReady
нестатичным и использовать его таким же образом:
private void Awake()
{
MazeGenerator.instance.OnMazeReady += startDirectives;
}
поэтому он будет уничтожен вместе с этим экземпляром MazeGenerator
.
Общее примечание
Я бы всегда удалил всех слушателей, которых когда-либо добавил, как можно скорее.чтобы избежать именно той проблемы, которая у вас есть.
Вы можете дополнительно удалить его, например, уже внутри StartDirectives
, чтобы убедиться, что метод выполняется только один раз, даже если одна и та же сцена "случайно" вызвала OnMazeReady
дважды.
Подсказка: я сказал дополнительно , поскольку всегда есть возможность сохранить / можно удалить слушателя, даже если он не был добавлен ранее, и вы должны всегда оставлять его в OnDestroy
в случае StartDirectives
никогда не вызывается до уничтожения объекта.