Unity, перезагрузи сцену полностью - PullRequest
0 голосов
/ 06 декабря 2018

У меня есть две сцены: Меню и Игра, где лабиринт генерируется случайным образом при каждом запуске.

После того, как Игрок умирает в лабиринте, я загружаю Меню сцены, где Игрок может нажать кнопку Старт, которая должна создать новый лабиринт, но вместо этого он просто загружает старую сцену с лабиринтом, где Игрок умер раньше.

Я хочу генерировать новый лабиринт каждый раз после нажатия кнопки «Пуск».
Также, когда я играю сцену с лабиринтом отдельно, все работает правильно. Для загрузки сцены я использую:

SceneManager.LoadScene(sceneIndex);

с индексами, определенными в настройках сборки.

Если потребуется какой-либо дополнительный код, просто спросите меня, и я добавлю его.

ОБНОВЛЕНИЕ
У меня есть класс MazeGenerator, в котором у меня есть делегат и событие:

public delegate void MazeReadyAction();
public static event MazeReadyAction OnMazeReady;

Событие запускается, когда лабиринт генерируется и используется в классе MazeDirecives для установки врагов и монет, когда лабиринт готов.
Так что у меня в MazeDirectives есть строки:

void Awake()
{
    MazeGenerator.OnMazeReady += StartDirectives;    
}

void StartDirectives()
{
   for (int i = 0; i < mazeCoinPositions.Count; i++)
    {
        MazeCoin mazeCoin = Instantiate(mazeCoinPrefab, mazeCoinPositions[i], 
            Quaternion.identity) as MazeCoin;
            mazeCoin.transform.SetParent(transform);
    }
}

Ошибка:
MissingReferenceException: The object of type 'MazeDirectives' has been destroyed but you are still trying to access it щенки:

mazeCoin.transform.SetParent(transform);

Есть предложения?

Ответы [ 2 ]

0 голосов
/ 07 декабря 2018

Поскольку

public static event MazeReadyAction OnMazeReady;

равно static, оно продолжает существовать, даже если будет существовать экземпляр этого класса, который будет уничтожен.

Так что после

MazeGenerator.OnMazeReady += StartDirectives;

этот слушатель продолжает вызываться, хотя объект MazeDirectives, который вы зарегистрировали в качестве слушателя, разрушается из-за SceneManager.Load.Так что в следующий раз, когда будет вызван OnMazeReady, у вас на самом деле будет зарегистрировано два слушателя: один из первой сцены, которая сейчас уничтожена, и один из «новой» сцены.

Вы должны либо удалить старыйслушатель

private void OnDestroy()
{
    MazeGenerator.OnMazeReady -= StartDirectives;
}

или даже не «складывает» их, а назначает только одного слушателя

private void Awake()
{
    MazeGenerator.OnMazeReady = StartDirectives;
}

это, конечно, применимо, только если в вашей сцене нет другого слушателя.

В любом случае вы должны сбросить его, чтобы быть уверенным

private void OnDestroy()
{
    MazeGenerator.OnMazeReady = null;
}

Общее примечание: всегда можно позвонить на

MazeGenerator.OnMazeReady -= StartDirectives;

, даже если слушатель не был добавлендо.Таким образом,

private void Awake()
{
    MazeGenerator.OnMazeReady -= StartDirectives;
    MazeGenerator.OnMazeReady += StartDirectives;
}

также гарантирует, что слушатель всегда может быть добавлен только один раз.

0 голосов
/ 06 декабря 2018

Это грубая сила, но она должна сработать.Эта процедура вызывается из сцены главного меню перед загрузкой сцены лабиринта.

int scenes = SceneManager.sceneCount;
if (scenes > 1)
{
    for (int i = 0; i < scenes; i++)
    {
        if (SceneManager.GetSceneAt(i).name == "Name of Maze Scene")
        {
            SceneManager.UnloadSceneAsync(SceneManager.GetSceneAt(i).name);
        }
    }
}
...