Сцена не загружена должным образом при переключении вперед и назад - PullRequest
0 голосов
/ 20 февраля 2019

Проблема
Проект Unity, который я создаю, нацелен на iOS, Android и Windows X64.У меня есть две сцены, A и B, тогда как A - это сцена главного меню в моей игре, а сцена B - это сцена выбора уровня, в которой пользователь может выбрать уровень для игры.Из сцены AI можно перейти к сцене B и обратно.При запуске игры в редакторе Unity все ведет себя как положено.Проблема возникает, когда я запускаю игру на целевых платформах (реальных устройствах).Затем, при навигации как A -> B -> A, я в конечном итоге оказываюсь в сцене A, отображаемой как черный экран, за исключением игрового объекта FPSIndicator, который все еще отображается и выполняет свою работу.Игровой объект FPSIndicator представляет собой небольшой фрагмент кода, который обращается к сцене в обратном вызове OnGUI.Больше ничего не отображается.

Настройка сцены A
У меня есть кнопка пользовательского интерфейса Unity («Перетаскивание»), которая при нажатии загружает сцену B, используя этот код:

using System.Collections;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.EventSystems;

public class GameTypeButtonController : MonoBehaviour, IPointerClickHandler
{
    public ButtonSounds ButtonSounds;
    public string SceneNameToLoad;
    public GameType GameType;

    public void OnPointerClick(PointerEventData eventData)
    {
        StartCoroutine(Do());
    }

    private IEnumerator Do()
    {
        var animator = gameObject.GetComponent<Animator>();

        if (animator != null)
        {
            animator.SetTrigger("Clicked");
        }

        var audioSource = gameObject.GetComponent<AudioSource>();

        if (audioSource != null)
        {
            var clip = GetRandomAudioClip(ButtonSounds);
            audioSource.clip = clip;
            audioSource.Play();
            yield return new WaitWhile(() => audioSource.isPlaying);
        }

        Logger.LogInfo("[GameTypeButtonController.Do] Setting game type " + GameType);
        GameManager.Instance.CurrentGameType = GameType;
        SceneManager.LoadScene(SceneNameToLoad);
    }

    private AudioClip GetRandomAudioClip(ButtonSounds buttonSounds)
    {
        var numberOfAudioClips = buttonSounds.AudioClips.Length;
        var randomIndex = Random.Range(0, numberOfAudioClips);
        return buttonSounds.AudioClips[randomIndex];
    }
}

Сцена выглядит следующим образом:

enter image description here

Настройка сцены B
В сцене B, Iесть кнопка в левом нижнем углу, которая возвращает меня к сцене А при нажатии.Это не кнопка Unity UI, а обычный спрайт с прикрепленным CircleCollider2D.Сценарий для этой кнопки выглядит следующим образом:

using System.Collections;
using UnityEngine;
using UnityEngine.SceneManagement;

public class HomeButtonController : MonoBehaviour
{
    public ButtonSounds ButtonSounds;
    public string SceneNameToLoad;

    void OnMouseDown()
    {
        StartCoroutine(Do());
    }

    private IEnumerator Do()
    {
        var animator = gameObject.GetComponent<Animator>();

        if (animator != null)
        {
            animator.SetTrigger("Clicked");
        }

        var audioSource = gameObject.GetComponent<AudioSource>();

        if (audioSource != null)
        {
            var clip = GetRandomAudioClip(ButtonSounds);
            audioSource.clip = clip;
            audioSource.Play();
            yield return new WaitWhile(() => audioSource.isPlaying);
        }

        SceneManager.LoadScene(SceneNameToLoad);
    }

    private AudioClip GetRandomAudioClip(ButtonSounds buttonSounds)
    {
        var numberOfAudioClips = buttonSounds.AudioClips.Length;
        var randomIndex = UnityEngine.Random.Range(0, numberOfAudioClips);
        return buttonSounds.AudioClips[randomIndex];
    }
}

Сцена выглядит следующим образом:

enter image description here

Общие примечания
Два объекта используют DontDestroyOnLoad: GameManager и MusicPlayer.

Что я проверял до сих пор

  • Сценыссылка правильно указана в настройках сборки
  • Поскольку я использую Unity Cloud Build, я отключил функцию кэширования библиотеки, чтобы избежать проблем со старыми артефактами сборки (поэтому каждый раз, когда я строю, я делаю правильную, чистую сборку)
  • Я могу собрать все три платформы локально (Unity сообщает об этом как "Сборка выполнена успешно").Так что никаких ошибок сборки.
  • Я использую LoadSceneMode.Single (по умолчанию)
  • Я использую ту же версию Unity локально и в Unity Cloud Build: 2018.3.0f2

Обновление 2019-02-19:
Когда я перемещаюсь из третьей сцены C обратно в сцену A, используя тот же механизм (кнопка спрайта, вызывающая сопрограмму), я также оказываюсь втакой же черный экран.Таким образом, проблема, вероятно, существует в сцене A?

Обновление 2 от 2019-02-19:
Вот мой код GameManager:

using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using UnityEngine;

public class GameManager : MonoBehaviour
{
    public EventHandler<LevelStartedEventArgs> LevelStarted;
    public EventHandler<LevelFinishedEventArgs> LevelFinished;

    // General 
    public GameType CurrentGameType;
    public GameScene CurrentScene;
    public int CurrentLevel;
    public static GameManager Instance;
    public GameLanguage Language;
    public bool IsMusicEnabled;
    private string gameStateFile;

    void Start()
    {
        if (Instance == null)
        {
            gameStateFile = Application.persistentDataPath + "/gamestate.dat";
            Load(gameStateFile);
            DontDestroyOnLoad(gameObject);
            Instance = this;
        }
        else if (Instance != this)
        {
            Destroy(gameObject);
        }
    }

    public void Save()
    {
        Logger.LogInfo("[GameManager.Save] Saving game state to " + gameStateFile);
        var bf = new BinaryFormatter();
        var file = File.Create(gameStateFile);

        var gameState = new GameState();
        gameState.Language = Language;
        gameState.IsMusicEnabled = IsMusicEnabled;

        bf.Serialize(file, gameState);
        file.Close();
        Logger.LogInfo("[GameManager.Save] Successfully saved game state");
    }

    public void Load(string gameStateFile)
    {
        Logger.LogInfo("[GameManager.Load] Loading game state from " + gameStateFile);
        if (File.Exists(gameStateFile))
        {
            var bf = new BinaryFormatter();
            var file = File.Open(gameStateFile, FileMode.Open);
            var gameState = (GameState)bf.Deserialize(file);
            file.Close();
            Language = gameState.Language;
            IsMusicEnabled = gameState.IsMusicEnabled;
        }
        Logger.LogInfo("[GameManager.Load] Successfully loaded game state");
    }

    [Serializable]
    class GameState {
        public GameLanguage Language;
        public bool IsMusicEnabled;
    }
}

Спасибо за любыенамеки!

1 Ответ

0 голосов
/ 01 марта 2019

Итак, мне наконец-то удалось решить проблему самостоятельно.Вот список шагов, которые я прошел, чтобы устранить мою проблему:

  1. Я установил рабочую нагрузку «Разработка игр с Unity» в Visual Studio 2017, чтобы иметь возможность использовать VisualСтудийный отладчик.Это дало мне возможность правильно отлаживать мои сценарии (устанавливать точки останова, проверять значения, ...) и проходить их шаг за шагом.См. эту ссылку , чтобы узнать, как этого добиться.К сожалению, это еще не решило мою проблему, но дало хорошую основу для устранения моей проблемы.

  2. Поскольку проблема, описанная выше, также возникала в сборках Windows x64, я решилустранить мою проблему на сборке Windows.Поэтому я перенастроил свою сборку Windows в настройках Build Player, установив Script Debugging на true, Development build на true, Copy PDB files на true.Затем я запустил еще одну сборку Windows.

Если вы сейчас запустите свою игру, в левом нижнем углу экрана отобразится консоль разработки, на которой будет много полезной информации (сгенерированные исключения,так далее...).Также вы можете открыть файл журнала непосредственно из игры, который предоставляет МНОГО полезной информации для решения реальной проблемы.

Итак, у меня было несколько PlatformNotSupportedExceptions в журналах, которые я смогисправить и некоторые другие ошибки.Теперь он работает.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...