阻止 Unity 编辑器应用程序进入播放模式



是否可以阻止 Unity 在用户按下按钮后更改播放模式?

假设我有一个自定义编辑器,它可能具有无法正确序列化的状态;如果用户此时更改 Unity 编辑器模式,他们的更改将丢失。

这是一个完全摆脱不可序列化状态的选项,但这是完全不同的复杂性的任务。想避免这种情况。

上级:

我已经用下面的脚本测试了derHugo的答案:

using UnityEditor;
using UnityEngine;
namespace Innoactive.Hub.Training.Editors
{
    [InitializeOnLoad]
    public class ProveThatDudeWrongWindow : EditorWindow
    {
        private static ProveThatDudeWrongWindow windowInstance;
        private string notSerializedString = "default";
        static ProveThatDudeWrongWindow()
        {
            EditorApplication.playModeStateChanged += OnPlayModeStateChanged;
        }
        [MenuItem("Test/I'm damn sure he's wrong")]
        private static void MenuItem()
        {
            if (windowInstance == null)
            {
                windowInstance = GetWindow<ProveThatDudeWrongWindow>();
            }
            windowInstance.notSerializedString = "some value";
        }
        [MenuItem("Test/Display current value")]
        private static void DisplayCurrentNonSerializedValue()
        {
            windowInstance = GetWindow<ProveThatDudeWrongWindow>();
            Debug.Log("string: " + windowInstance.notSerializedString);
        }
        private static void OnPlayModeStateChanged(PlayModeStateChange state)
        {
            if (state == PlayModeStateChange.ExitingEditMode)
            {
                EditorApplication.isPlaying = false;
            }
            Debug.Log("state: " + state);
        }
    }
}

然后我做了以下操作:

  1. Test/I'm damn sure he's wrong选项将非序列化值从default值设置为some value
  2. Test/Display current value 确保值已更改
  3. 按播放按钮
  4. Test/Display current value查看当前值。如果是default,德雨果的解就行不通,如果是some value,就行得通。

结果:德雨果很酷。

是的,我认为有

您可以注册EditorApplication.playModeStateChanged

看看我修改的文档中的示例:

using UnityEngine;
using UnityEditor;
public static class PlayModeStateChangedExample
{   
    private static void LogPlayModeState(PlayModeStateChange state)
    {
        Debug.Log(state);
    }
    public static void SetPlayModeEnabled(bool enabled)
    {
        //This is possible since you allways can remove
        //a listener even if there is none so far
        //This allways removes the listener making sure it is only added once  
          EditorApplication.playModeStateChanged -= LogPlayModeState;
        if(!enabled)
        {
            EditorApplication.playModeStateChanged += LogPlayModeState;
        }
    }
}

现在剩下的就是将EditorApplication.isPlaying重置回false例如通过替换

Debug.Log(state);

// This mode occures right before entering PlayMode
// and is the moment in which we want to intervene
if(state == PlayModeStateChange.ExitingEditMode)
{
    EditorApplication.isPlaying = false;
}

以杀死播放模式。

因此,您可以从任何地方拨打电话,例如

PlayModeStateChangedExample.SetPlayModeEnabled(false);

但是,我不确定这是否会完全阻止序列化部分,因为它也在文档中声明

设置 isPlaying 会将结果延迟到此帧的所有脚本代码完成之后。

最新更新