Scripting Define Symbols
プリプロセッサはビルドに問題を抱えがちなUnityには欠かせないものですが、Scripting Define Symbolsはなんというか……もうちょっと、こう、やりようというものが……。
【Unity】Scripting Define Symbolsを簡単に設定できるようにするエディタ拡張
Scripting Define Symbolsを劇的に使いやすくするエディタ拡張【Unity】【エディタ拡張】
みたいな話をしたいのですが、既に先人がScripting Define Symbolsとはなんぞや? という説明からなにからエディタ拡張で操作するとことまで書いてくれてるからそっち読んどいてくれよな!
おしまい。
DefineSwitcher.cs
なんか何も考えないで書いてたら記事が終わったんですが、そういうことではなくてわたしも同じようなものを作ってみましたという話です。
1シンボルしかON/OFFできませんが、その分簡単にエディタメニューからポチポチ切り替えられるのがポイントです。
エディタの初回起動時とSwitch PlatformのタイミングでScripting Define Symbolsをチェックして、エディタメニューのON/OFFを切り替えています。gistに載せたものは特定のプラットフォーム1に向けた記述になっているので、コメントに書いたとおりDefineとDefineMenuPathを書き換えて使ってください。
usingSystem.Collections.Generic;usingSystem.Linq;usingUnityEditor;usingUnityEditor.Build;usingUnityEngine;namespaceNekomimi.Daimao{/// <summary>/// Switch #define./// rewrite <see cref="Define"/> and <seealso cref="DefineMenuPath"/>/// </summary>publicclassDefineSwitcher:IActiveBuildTargetChanged{#regionDefineprivateconststringDefine="UNITY_OVR";privateconstcharSeparator=';';privatestaticvoidSetDefine(boolon){if(on==IsDefined()){return;}varcurrent=newHashSet<string>(CurrentDefines());if(on){current.Add(Define);}else{current.Remove(Define);}PlayerSettings.SetScriptingDefineSymbolsForGroup(EditorUserBuildSettings.selectedBuildTargetGroup,string.Join(Separator.ToString(),current));}privatestaticIEnumerable<string>CurrentDefines(){returnPlayerSettings.GetScriptingDefineSymbolsForGroup(EditorUserBuildSettings.selectedBuildTargetGroup).Split(Separator);}privatestaticboolIsDefined(){returnCurrentDefines().Contains(Define);}#endregion#regionEditorMenuprivateconststringDefineMenuPath="Oculus/"+Define;[MenuItem(DefineMenuPath,priority=-1)]privatestaticvoidSwitchDefine(){varcurrent=IsDefined();SetDefine(!current);SetCheckState(!current);}privatestaticvoidSetCheckState(boolstate){varcheck=Menu.GetChecked(DefineMenuPath);if(state==check){return;}Menu.SetChecked(DefineMenuPath,!check);}#endregion#regionIActiveBuildTargetChangedpublicintcallbackOrder{get;}=0;publicvoidOnActiveBuildTargetChanged(BuildTargetpreviousTarget,BuildTargetnewTarget){SetCheckState(IsDefined());}#endregion#regionInitializeOnLoadMethodprivateclassFirstLoad:ScriptableSingleton<FirstLoad>{[SerializeField]publicboolAlreadyLoaded=false;}[InitializeOnLoadMethod]privatestaticvoidCheckOnLaunch(){if(FirstLoad.instance.AlreadyLoaded){return;}FirstLoad.instance.AlreadyLoaded=true;SetCheckState(IsDefined());}#endregion}}まとめ
こういうプリプロセッサとかマクロとかってあんまり使わない派なのですが、今回はそこそこつらいことがあったので作りました。Unityのエディタ拡張ってなんだかんだAPIが用意されているので、作ろうと思えばなんでも作れますね。
公式のマニュアルが……ふわっ……としているので先人の記事を探し出さなければならないのが苦しいところですが、これからはエディタ拡張で解決できる問題がないか、気に留めてみようと思います。
おしまい。
参考
【Unity】Scripting Define Symbolsを簡単に設定できるようにするエディタ拡張
Scripting Define Symbolsを劇的に使いやすくするエディタ拡張【Unity】【エディタ拡張】
【Unity】UnityEditor の起動時にのみ処理を行う2
