来回切换时场景未正确加载

时间:2019-02-19 21:13:45

标签: unity3d

问题
我构建的Unity项目面向iOS,Android和Windows X64。我有两个场景,A和B,而A是游戏的主菜单场景,场景B是一种关卡选择场景,用户可以在其中选择要玩的关卡。我可以从场景A导航到场景B,然后再次返回。在Unity编辑器中运行游戏时,所有行为均符合预期。当我在目标平台(真实设备)上运行游戏时,就会出现问题。然后,当像A-> B-> A那样导航时,我最终将场景A渲染为黑屏,除了FPSIndicator游戏对象仍在渲染并完成其工作。 FPSIndicator游戏对象是一小段代码,可以将自己引向OnGUI回调中的场景。没有其他显示。

场景A的设置
我在那里有一个Unity UI按钮(“拖放”),单击该按钮时,将使用以下代码加载场景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中,我在左下方有一个按钮,单击该按钮可使我回到场景A。这不是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

一般说明
两个对象使用DontDestroyOnLoadGameManagerMusicPlayer

我到目前为止检查的内容

  • 在“构建设置”中正确引用了场景
  • 在我使用Unity Cloud Build时,我已禁用库缓存功能以避免旧的构建工件出现问题(因此,每次构建时,我都会进行正确,干净的构建)
  • 我可以在本地构建所有三个平台(Unity称其为“构建成功”)。因此没有构建错误。
  • 我正在使用LoadSceneMode.Single(默认)
  • 我在本地和Unity Cloud Build:2018.3.0f2中使用相同的Unity版本

更新2019-02-19:
当我使用相同的机制(称为“协程”的精灵按钮)从第三个场景C导航回场景A时,我也最终会出现在完全相同的黑屏上。那么问题可能存在于场景A中吗?

2019年2月19日的更新2:
这是我的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 :(得分:0)

因此,我终于设法自己解决了这个问题。这是我为了消除问题而经历的步骤列表:

  1. 我在Visual Studio 2017中安装了“使用Unity开发游戏”工作负载,以便能够使用Visual Studio调试器。这使我可以正确调试脚本(设置断点,检查值等)并逐步进行调试。有关如何完成此操作的一些详细信息,请参见this link。不幸的是,这还不能解决我的问题,但是为解决我的问题提供了良好的基础。

  2. 由于上述问题也出现在Windows x64构建上,因此我决定对Windows构建上的问题进行故障排除。因此,我通过将Script Debugging设置为true,将Development build设置为true,将Copy PDB files设置为true,在Build Player设置中重新配置了Windows构建。然后我运行了另一个Windows版本。

如果您现在运行游戏,它将在左下方屏幕上显示一个开发控制台,其中提供了许多有用的信息(抛出异常等)。您也可以直接从游戏中打开日志文件,该日志文件提供了大量有用的信息来解决实际问题。

因此,我在日志中有一些PlatformNotSupportedExceptions可以解决,还有其他一些错误。现在可以了。

尽管我已经回答了我自己的问题,但我希望这对某些人有用。