【问题标题】:Prevent Unity Editor application from entering play mode阻止 Unity Editor 应用程序进入播放模式
【发布时间】:2018-12-27 18:26:27
【问题描述】:

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

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

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

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 很酷。

【问题讨论】:

    标签: unity3d


    【解决方案1】:

    是的,我认为

    您可以注册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 会延迟结果,直到完成此帧的所有脚本代码。

    【讨论】:

    • (我原以为它会进入播放模式并立即离开,但实际上它首先阻止了它)。
    • 很高兴为您提供帮助!老实说,我也分享了你的疑问^^
    猜你喜欢
    • 2018-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多