【Unity】一键切换是否允许#if UNITY_EDITOR条件编译生效

在项目中经常会条件编译的方式来让编译器环境和非编译器环境跑不同的代码,但这种方式会让非编译器环境的代码测试变得十分不方便。UNITY_EDITOR也是Unity预定义的宏,不能直接在PlayerSettings里面增加或删除。

#if UNITY_EDITOR
    //编译器环境下的代码逻辑
#else
    //非编译器环境下的代码逻辑
#endif

实现思路:

用#undef UNITY_EDITOR可以取消unity预定义的UNITY_EDITOR宏,这样就可以让代码在编译器环境下直接进入非编译器环境的代码块。

#undef UNITY_EDITOR

#undef可以用来取消宏的定义,但#undef的作用范围只有当前文件,当多个文件都有用到#if UNITY_EDITOR的时候,当想调试非编译器环境的代码时,这些文件都需要加上#undef,调试编译器环境的代码时,又要一个个都删掉#undef...

这种情况下可以用一个自定义宏去控制#undef UNITY_EDITOR是否执行,我们只需要在每个脚本里面加上以下代码,然后在PlayerSettings里面控制是否定义ENABLE_EDITOR_MODE就可以控制多个脚本(注意以下语句必须放在using上面)。

#if ENABLE_EDITOR_MODE
#undef UNITY_EDITOR
#endif

具体做法:

Step1:在所有用到#if UNITY_EDITOR的脚本最上面加上代码块:

#if ENABLE_EDITOR_MODE
#undef UNITY_EDITOR
#endif

//using UnityEngine;之类
//...

#if UNITY_EDITOR
    //编译器环境下的代码逻辑
#else
    //非编译器环境下的代码逻辑
#endif

//...

Step2:用一个脚本来增加/移除自定义宏,并放到菜单栏

using System.Collections.Generic;
using UnityEditor;

public class EditorTools
{
    /// <summary>
    /// 当设置这个之后,#if UNITY_EDITOR不生效,移除后,#if UNITY_EDITOR生效
    /// </summary>
    private static string ENABLE_EDITOR_MODE
    {
        get
        {
            return "ENABLE_EDITOR_MODE";
        }
    }


    [MenuItem("MyTools/Symbols Setting/Enable Editor Mode")]
    static void EnableEditorMode()
    {
        RemoveDefineSymbols(ENABLE_EDITOR_MODE);
    }

    [MenuItem("MyTools/Symbols Setting/Disable Editor Mode")]
    static void DisableEditorMode()
    {
        AddDefineSymbols(ENABLE_EDITOR_MODE);
    }

    /// <summary>
    /// 添加宏
    /// </summary>
    /// <param name="symbol"></param>
    private static void AddDefineSymbols(string symbol)
    {
        string currentDefines = PlayerSettings.GetScriptingDefineSymbolsForGroup(EditorUserBuildSettings.selectedBuildTargetGroup);
        HashSet<string> defines = new HashSet<string>(currentDefines.Split(';')) {
            symbol
        };

        string newDefines = string.Join(";", defines);
        if (newDefines != currentDefines)
        {
            PlayerSettings.SetScriptingDefineSymbolsForGroup(EditorUserBuildSettings.selectedBuildTargetGroup, newDefines);
        }
    }


    /// <summary>
    /// 删除宏
    /// </summary>
    /// <param name="symbol"></param>
    private static void RemoveDefineSymbols(string symbol)
    {
        string currentDefines = PlayerSettings.GetScriptingDefineSymbolsForGroup(EditorUserBuildSettings.selectedBuildTargetGroup);
        HashSet<string> defines = new HashSet<string>(currentDefines.Split(';'));
        defines.Remove(symbol);

        string newDefines = string.Join(";", defines);
        if (newDefines != currentDefines)
        {
            PlayerSettings.SetScriptingDefineSymbolsForGroup(EditorUserBuildSettings.selectedBuildTargetGroup, newDefines);
        }
    }
}

Step3:在菜单栏控制是否允许#if UNITY_EDITOR条件编译生效

 当按了Disable Editor Mode后,在编译器下,会跳过#if UNITY_EDITOR语句进入#else的逻辑

我不是很确定实际项目里面是怎么做的,如果还有其他更好的办法欢迎告诉我~~

猜你喜欢

转载自blog.csdn.net/weixin_61427881/article/details/129846597
今日推荐