Switch ScriptingDefineSymbols from the editor menu

2 minute read

Scripting Define Symbols

The preprocessor is essential for ʻUnity, which tends to have build problems, What is Scripting Define Symbols` … A little more, I’m trying to do it …

[Unity] Editor extension that makes it easy to set Scripting Define Symbols
Editor extension that makes Scripting Define Symbols dramatically easier to use [Unity] [Editor extension]

I’d like to talk about something like that, but what is the predecessor already Scripting Define Symbols? From the explanation, it says that you can operate with the editor extension, so please read that!

That’s it.

DefineSwitcher.cs

The article ended when I wrote it without thinking about anything, but it is a story that I also tried to make something similar.

output.gif

Only one symbol can be turned ON / OFF, but the point is that it can be easily switched from the editor menu.
The Scripting Define Symbols is checked at the first startup of the editor and at the timing of Switch Platform to switch the editor menu ON / OFF.
The description on gist is for a specific platform [^ platform], so please rewrite Define and DefineMenuPath as described in the comment.

gist : DefineSwitcher.cs

DefineSwitcher.cs


using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEditor.Build;
using UnityEngine;

namespace Nekomimi.Daimao
{
    /// <summary>
    /// Switch #define.
    /// rewrite <see cref="Define"/> and <seealso cref="DefineMenuPath"/>
    /// </summary>
    public class DefineSwitcher : IActiveBuildTargetChanged
    {
        #region Define

        private const string Define = "UNITY_OVR";
        private const char Separator = ';';

        private static void SetDefine(bool on)
        {
            if (on == IsDefined())
            {
                return;
            }

            var current = new HashSet<string>(CurrentDefines());

            if (on)
            {
                current.Add(Define);
            }
            else
            {
                current.Remove(Define);
            }

            PlayerSettings.SetScriptingDefineSymbolsForGroup(
                EditorUserBuildSettings.selectedBuildTargetGroup, string.Join(Separator.ToString(), current)
            );
        }

        private static IEnumerable<string> CurrentDefines()
        {
            return PlayerSettings.GetScriptingDefineSymbolsForGroup(EditorUserBuildSettings.selectedBuildTargetGroup).Split(Separator);
        }

        private static bool IsDefined()
        {
            return CurrentDefines().Contains(Define);
        }

        #endregion


        #region EditorMenu

        private const string DefineMenuPath = "Oculus/" + Define;

        [MenuItem(DefineMenuPath, priority = -1)]
        private static void SwitchDefine()
        {
            var current = IsDefined();
            SetDefine(!current);
            SetCheckState(!current);
        }

        private static void SetCheckState(bool state)
        {
            var check = Menu.GetChecked(DefineMenuPath);
            if (state == check)
            {
                return;
            }

            Menu.SetChecked(DefineMenuPath, !check);
        }

        #endregion


        #region IActiveBuildTargetChanged

        public int callbackOrder { get; } = 0;

        public void OnActiveBuildTargetChanged(BuildTarget previousTarget, BuildTarget newTarget)
        {
            SetCheckState(IsDefined());
        }

        #endregion

        #region InitializeOnLoadMethod

        private class FirstLoad : ScriptableSingleton<FirstLoad>
        {
            [SerializeField]
            public bool AlreadyLoaded = false;
        }

        [InitializeOnLoadMethod]
        private static void CheckOnLaunch()
        {
            if (FirstLoad.instance.AlreadyLoaded)
            {
                return;
            }

            FirstLoad.instance.AlreadyLoaded = true;
            SetCheckState(IsDefined());
        }

        #endregion
    }
}

Summary

I don’t use preprocessors and macros like this so much, but this time I made it because it was a bit difficult.
The editor extension of ʻUnity has somehow ʻAPI, so if you want to make it, you can make anything.
Since the official manual says * …… fluffy …… *, it is difficult to find the article of the ancestor, but from now on, I will try to keep in mind whether there is a problem that can be solved by the editor extension. think.

That’s it.

reference

[Unity] Editor extension that makes it easy to set Scripting Define Symbols
Editor extension that makes Scripting Define Symbols dramatically easier to use [Unity] [Editor extension]
[Unity] Performs processing only when UnityEditor is started [^ wakeup]