【问题标题】:SceneManager LoadScene not working in editor playmodeSceneManager LoadScene 在编辑器播放模式下不起作用
【发布时间】:2020-04-09 16:59:12
【问题描述】:

正如标题所说,我在编辑器中处于播放模式时加载场景时遇到问题。

我的游戏的工作流程如下:

  1. 正在初始化(工作正常) 有一个空场景创建了一些全局游戏对象,这些对象将在整个运行时都存在。
  2. MainMenu(工作正常) 初始化完成后,它会加载 MainMenu 场景。我可以与场景互动,一切都很好。
  3. 连接到游戏服务器(工作正常) 在主菜单中,我可以选择连接到游戏服务器(我自己创建的专用服务器应用程序) 建立连接并发送登录信息效果很好。
  4. 字符选择(不工作) 在服务器上登录后,我得到了选择一个角色的共鸣。 (这按预期工作。) 然后我将通过打开角色选择场景来处理这个响应。 在这里我有问题。在编辑器内的 Playmode 中,处理程序方法被执行(由调试日志验证),但实际上并未加载场景。 当我构建游戏并运行创建的 .exe 并按照完全相同的步骤加载角色选择场景并按预期显示时。

我搜索了文档和网络,但没有发现任何类似的问题(也许我仍然遗漏了一些东西)

所以我的问题如下: 如何让场景也加载到编辑器播放模式中?我的方法似乎并没有完全错误,因为它在构建后起作用。

这是应该加载场景的代码sn-p:

private void MessageRecived(object sender, GNL.ResponseMessageEventArgs e)
    {
        GameEventMessage message = this.eventManager.MessageHandler.ParseMessage(e.Message);

        Debug.Log($"Recived message with type {message.Type}");

        switch (message.Type)
        {
            case GameEvent.CharacterSelectionRequired:
                Debug.Log($"Handle character creation 01");
                this.HandleCharacterSelectionRequried(message);
                break;
            default:
                break;
        }
    }

    private void HandleCharacterSelectionRequried(GameEventMessage eventMessage)
    {
        Debug.Log($"Handle character creation 02");
        SceneManager.LoadScene("CharacterCreation");
    }

所有三个 Debug.Log 语句都被执行。只有 LoadScene 在编辑器播放模式下不起作用。

重要补充 经过进一步的测试,我不得不提到网络通信是在一个单独的线程中完成的。当有新消息到达时,从该线程调用 eventHandler。

这是将方法添加到事件处理程序的位置:

this.client = new GNL.GameClient(System.Net.IPAddress.Parse(host), port);

        this.client.AnnounceRecivedMessage += this.MessageRecived;

        this.clientNetwork = new Thread(this.client.Start);
        clientNetwork.Start();

这就是eventHandler的定义:

public event EventHandler<ResponseMessageEventArgs> AnnounceRecivedMessage;

重要补充 - 第 2 部分 我刚刚发现,它适用于正常构建,但在构建设置中选择“开发构建”时不起作用。

这真的很烦人,因为我每次更改测试时都必须构建游戏。

感谢您的任何帮助和建议。

【问题讨论】:

  • 您的问题可能与线程有关! Unity的大部分API只能在Unity主线程中使用……难道MessageRecived是从后台线程调用的?
  • 是的,正如我在问题中所写的,MessageRecived 被分配给 EventHandler AnnounceRecivedMessage,这是从用于网络通信的单独线程调用的。但是,如果它确实是线程问题,那么它也不应该与正常构建一起使用。我记得之前尝试过多线程,然后 unity 抛出一个错误,但没有错误。
  • 这取决于那里如何处理线程......

标签: unity3d


【解决方案1】:

经过更多的调试和测试,我发现这个问题确实是一个线程问题。 在调试器的深处,我发现了线程问题的异常。所以我必须在这里改变我的实现。

但是,在启用调试工具(编辑器和开发构建中的播放模式)和禁用调试工具(正常构建)运行游戏时,Unity 中线程的处理方式仍然不一致。

【讨论】:

    【解决方案2】:

    AFAIK,您无法在编辑器中的场景之间切换。 Unity Editor 仅用于编辑和播放打开的场景。

    如果您想测试工作流程的某些部分,请创建专用于编辑器的函数(您可以使用#if UNITY_EDITOR)来测试您的场景,而无需之前的角色选择。

    【讨论】:

    • 实际上 SceneManager.LoadScene("") 方法在编辑器中工作。例如,从初始化场景 (Step1) 切换到 MainMenu (Step2) 时。而且,当我在 MainMenu 场景中创建一个仅调用 SceneManager.LoadScene("CharacterCreation") 的按钮时,场景也会被加载。这就是为什么我认为它与单独的线程有关。但它仍然让我感到困惑,为什么它在构建后工作但不在编辑器中工作。
    • 我编辑了我的答案。我每天都在使用它,我不知道为什么我确信它不起作用......这很奇怪,我不明白为什么它在编辑器中不起作用......但我认为你可以制作一些编辑器功能能够处理您的最终场景,而无需每次都测试整个工作流程。
    • 现在我必须进行角色选择和创建,这两者都很大程度上依赖于来自游戏服务器的数据。所以这将是只为编辑器创建的一大堆代码。总的来说,我不太喜欢绕过预期的工作流程。我会看看是否还有其他想法。如果没有,我会尝试你的方法。但无论如何,感谢您为此付出的努力。
    • 如果是线程问题,也许最好使用一个简单的调度对象来为您将其加载到主线程上?不会对您的工作流程产生太大影响。我实际上希望从不同的线程加载场景可能会在以后导致更多问题。
    • 我不确定这是否是线程问题,因为如果是一个问题,我会期待两件事。首先,它在正常构建后也无法正常工作,其次是错误输出,说明无法从不同的线程执行此操作。两者都不是这样,所以我个人认为这是统一开发环境的一些问题。 (另请参阅关于开发版本的更新第 2 部分)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多