阻止Unity Editor应用程序进入播放模式

时间:2018-12-25 10:35:16

标签: unity3d

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

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

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

UPD:

我已经使用以下脚本测试了derHugo's answer

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,则derHugo的解决方案不起作用;如果为some value,则其解决方案。

结果:derHugo很酷。

1 个答案:

答案 0 :(得分:2)

是的,我想

您可以注册到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;
}

杀死PlayMode。

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

PlayModeStateChangedExample.SetPlayModeEnabled(false);

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

  

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