📗
【Unity】DefineSymbolをスクリプトから追加する方法
はじめに
初めての方も、そうでない方もこんにちは!
現役ゲームプログラマーのたむぼーです。
自己紹介を載せているので、気になる方は見ていただければ嬉しいです!
今回は
DefineSymbolをスクリプトから追加する方法
について紹介します
DefineSymbolとは
Define Symbol(定義シンボル)は、Unityにおいて条件付きコンパイルを行うために使われる仕組みです。
特定のコードブロックを、ある条件(シンボルが定義されているかどうか)によって有効・無効にできるため、プラットフォームごとの処理切り替えや、開発/本番の環境分岐などに活用されます。
#if DEBUG_MODE
Debug.Log("デバッグモードです");
#endif
上記のように DEBUG_MODE というシンボルが定義されている場合にだけ、Debug.Log のコードが有効になります。
主な用途
・開発中のみ表示したいログの制御
・有償版/無償版などのビルド差分の制御
・プラットフォーム別の機能制御(例:iOS専用コード)
・アセットやパッケージによる機能のON/OFF切り替え
設定方法
Unityの上部メニューから
Edetor > Project Settings > Player > Other Settings > Scripting Define Symbols
DefineSymbolをスクリプトから追加
使い方
Example.cs
public void Example()
{
// 全てのプラットフォームに【DEBUG_MODE】を追加
DefineSymbolsHelper.AddDefineSymbol(DefineSymbolsPlatform.All, "DEBUG_MODE");
// Androidの設定から【DEBUG_MODE】を削除
DefineSymbolsHelper.RemoveDefineSymbol(DefineSymbolsPlatform.Android, "DEBUG_MODE");
}
プラットフォームのEnumの定義
DefineSymbolsPlatform
DefineSymbolsPlatform.cs
#if UNITY_EDITOR
/// <summary>
/// プラットフォーム
/// </summary>
public enum DefineSymbolsPlatform
{
Android,
iOS,
PC,
All
}
#endif
ヘルパークラスの実装
DefineSymbolsHelper
DefineSymbolsHelper.cs
#if UNITY_EDITOR
using UnityEditor;
public static class DefineSymbolsHelper
{
/// <summary>
/// DefineSymbolを追加
/// </summary>
public static void AddDefineSymbol(DefineSymbolsPlatform platform, string symbol)
{
switch (platform)
{
case DefineSymbolsPlatform.Android:
AddDefineSymbolGroup(BuildTargetGroup.Android, symbol);
break;
case DefineSymbolsPlatform.iOS:
AddDefineSymbolGroup(BuildTargetGroup.iOS, symbol);
break;
case DefineSymbolsPlatform.PC:
AddDefineSymbolGroup(BuildTargetGroup.Standalone, symbol);
break;
case DefineSymbolsPlatform.All:
AddDefineSymbolGroup(BuildTargetGroup.Android, symbol);
AddDefineSymbolGroup(BuildTargetGroup.iOS, symbol);
AddDefineSymbolGroup(BuildTargetGroup.Standalone, symbol);
break;
}
}
/// <summary>
/// DefineSymbolを削除
/// </summary>
public static void RemoveDefineSymbol(DefineSymbolsPlatform platform, string symbol)
{
switch (platform)
{
case DefineSymbolsPlatform.Android:
RemoveDefineSymbolGroup(BuildTargetGroup.Android, symbol);
break;
case DefineSymbolsPlatform.iOS:
RemoveDefineSymbolGroup(BuildTargetGroup.iOS, symbol);
break;
case DefineSymbolsPlatform.PC:
RemoveDefineSymbolGroup(BuildTargetGroup.Standalone, symbol);
break;
case DefineSymbolsPlatform.All:
RemoveDefineSymbolGroup(BuildTargetGroup.Android, symbol);
RemoveDefineSymbolGroup(BuildTargetGroup.iOS, symbol);
RemoveDefineSymbolGroup(BuildTargetGroup.Standalone, symbol);
break;
}
}
/// <summary>
/// DefineSymbolが存在するか
/// </summary>
public static bool IsDefineSymbolPresent(DefineSymbolsPlatform platform, string symbol)
{
return platform switch
{
DefineSymbolsPlatform.Android => IsDefineSymbolPresent(BuildTargetGroup.Android, symbol),
DefineSymbolsPlatform.iOS => IsDefineSymbolPresent(BuildTargetGroup.iOS, symbol),
DefineSymbolsPlatform.PC => IsDefineSymbolPresent(BuildTargetGroup.Standalone, symbol),
DefineSymbolsPlatform.All => IsDefineSymbolPresent(BuildTargetGroup.Android, symbol)
&& IsDefineSymbolPresent(BuildTargetGroup.iOS, symbol)
&& IsDefineSymbolPresent(BuildTargetGroup.Standalone, symbol),
_ => false,
};
}
/// <summary>
/// DefineSymbolが既に存在するかを確認
/// </summary>
private static bool IsDefineSymbolPresent(BuildTargetGroup buildTargetGroup, string symbol)
{
string defines = PlayerSettings.GetScriptingDefineSymbolsForGroup(buildTargetGroup);
return IsDefineSymbolPresent(defines, symbol);
}
/// <summary>
/// DefineSymbolが既に存在するかを確認
/// </summary>
private static bool IsDefineSymbolPresent(string defines, string symbol)
{
return defines.Contains(symbol);
}
/// <summary>
/// DefineSymbolをグループ毎に追加
/// </summary>
private static void AddDefineSymbolGroup(BuildTargetGroup buildTargetGroup, string symbol)
{
string defines = PlayerSettings.GetScriptingDefineSymbolsForGroup(buildTargetGroup);
// DefineSymbolの存在チェック
if (!IsDefineSymbolPresent(defines, symbol))
{
if (!string.IsNullOrEmpty(defines))
{
defines += ";";
}
defines += symbol;
PlayerSettings.SetScriptingDefineSymbolsForGroup(buildTargetGroup, defines);
AssetDatabase.Refresh();
}
}
/// <summary>
/// DefineSymbolをグループ毎に削除
/// </summary>
private static void RemoveDefineSymbolGroup(BuildTargetGroup buildTargetGroup, string symbol)
{
string defines = PlayerSettings.GetScriptingDefineSymbolsForGroup(buildTargetGroup);
// DefineSymbolの存在チェック
if (IsDefineSymbolPresent(defines, symbol))
{
defines = defines.Replace(symbol, "").TrimEnd(';').TrimStart(';');
PlayerSettings.SetScriptingDefineSymbolsForGroup(buildTargetGroup, defines);
AssetDatabase.Refresh();
}
}
}
#endif
おまけ(拡張ウィンドウでの設定)
DefineSymbolsSetterWindow
DefineSymbolsSetterWindow.cs
#if UNITY_EDITOR
using UnityEditor;
using UnityEngine;
using System;
using System.Collections.Generic;
public class DefineSymbolsSetterWindow : EditorWindow
{
private DefineSymbolsPlatform _selectedPlatform = DefineSymbolsPlatform.All;
private string _defineSymbol = "";
private Vector2 _scrollPos;
/// <summary>
/// ウィンドウを作成
/// </summary>
[MenuItem("Tools/DefineSymbolsSetter")]
public static void ShowWindow()
{
var window = GetWindow<DefineSymbolsSetterWindow>("Define Symbols Setter");
window.minSize = new Vector2(500, 300);
}
/// <summary>
/// 更新
/// </summary>
private void OnGUI()
{
EditorGUILayout.LabelField("Define Symbol 設定", EditorStyles.boldLabel);
EditorGUILayout.Space();
_selectedPlatform = (DefineSymbolsPlatform)EditorGUILayout.EnumPopup("対象プラットフォーム", _selectedPlatform);
_defineSymbol = EditorGUILayout.TextField("Define Symbol", _defineSymbol);
EditorGUILayout.BeginHorizontal();
if (GUILayout.Button("Add"))
{
if (!string.IsNullOrEmpty(_defineSymbol))
{
DefineSymbolsHelper.AddDefineSymbol(_selectedPlatform, _defineSymbol);
CustomLogger.Info("Define Symbols Setter", ColorPallet.Aqua, $"Symbol '{_defineSymbol}' を {_selectedPlatform} に追加しました。");
ShowNotification(new GUIContent($"Symbol '{_defineSymbol}' を {_selectedPlatform} に追加しました。"));
}
else
{
EditorUtility.DisplayDialog("エラー", "Define Symbol を入力してください。", "OK");
}
}
if (GUILayout.Button("Remove"))
{
if (!string.IsNullOrEmpty(_defineSymbol))
{
DefineSymbolsHelper.RemoveDefineSymbol(_selectedPlatform, _defineSymbol);
CustomLogger.Info("Define Symbols Setter", ColorPallet.Aqua, $"Symbol '{_defineSymbol}' を {_selectedPlatform} から削除しました");
ShowNotification(new GUIContent($"Symbol '{_defineSymbol}' を {_selectedPlatform} から削除しました。"));
}
else
{
EditorUtility.DisplayDialog("エラー", "Define Symbol を入力してください。", "OK");
}
}
EditorGUILayout.EndHorizontal();
EditorGUILayout.Space(15);
EditorGUILayout.LabelField("現在の Define Symbols", EditorStyles.boldLabel);
_scrollPos = EditorGUILayout.BeginScrollView(_scrollPos);
if (_selectedPlatform == DefineSymbolsPlatform.All)
{
DrawSymbolsForAllPlatforms();
}
else
{
var group = PlatformToBuildTargetGroup(_selectedPlatform);
DrawSymbolsForPlatform(group, _selectedPlatform.ToString());
}
EditorGUILayout.EndScrollView();
}
/// <summary>
/// 指定プラットフォームのDefineSymbolsを表示
/// </summary>
private void DrawSymbolsForPlatform(BuildTargetGroup group, string label)
{
string symbols = PlayerSettings.GetScriptingDefineSymbolsForGroup(group);
string[] defines = symbols.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
EditorGUILayout.LabelField($"--- {label} ---", EditorStyles.boldLabel);
if (defines.Length == 0)
{
EditorGUILayout.LabelField("(シンボルなし)");
}
else
{
foreach (var symbol in defines)
{
DrawSymbolRow(symbol);
}
}
EditorGUILayout.Space(10);
}
/// <summary>
/// 全プラットフォームのDefineSymbolsを表示
/// </summary>
private void DrawSymbolsForAllPlatforms()
{
var android = new HashSet<string>(PlayerSettings.GetScriptingDefineSymbolsForGroup(BuildTargetGroup.Android).Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries));
var ios = new HashSet<string>(PlayerSettings.GetScriptingDefineSymbolsForGroup(BuildTargetGroup.iOS).Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries));
var pc = new HashSet<string>(PlayerSettings.GetScriptingDefineSymbolsForGroup(BuildTargetGroup.Standalone).Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries));
var common = new HashSet<string>(android);
common.IntersectWith(ios);
common.IntersectWith(pc);
var androidOnly = new HashSet<string>(android);
androidOnly.ExceptWith(common);
var iosOnly = new HashSet<string>(ios);
iosOnly.ExceptWith(common);
var pcOnly = new HashSet<string>(pc);
pcOnly.ExceptWith(common);
// 共通シンボル
EditorGUILayout.LabelField("=== 共通シンボル(全プラットフォーム) ===", EditorStyles.boldLabel);
if (common.Count == 0)
{
EditorGUILayout.LabelField("(共通シンボルなし)");
}
else
{
foreach (var symbol in common)
{
DrawSymbolRow(symbol);
}
}
// 各プラットフォーム専用シンボル
DrawPlatformSymbols("Android 専用", androidOnly);
DrawPlatformSymbols("iOS 専用", iosOnly);
DrawPlatformSymbols("PC 専用", pcOnly);
}
/// <summary>
/// 指定プラットフォームのDefineSymbolsを表示
/// </summary>
private void DrawPlatformSymbols(string label, HashSet<string> symbols)
{
EditorGUILayout.Space();
EditorGUILayout.LabelField($"=== {label} ===", EditorStyles.boldLabel);
if (symbols.Count == 0)
{
EditorGUILayout.LabelField("(シンボルなし)");
}
else
{
foreach (var symbol in symbols)
{
DrawSymbolRow(symbol);
}
}
}
/// <summary>
/// 1つのDefineSymbolを行として表示
/// </summary>
private void DrawSymbolRow(string symbol)
{
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField($"- {symbol}", GUILayout.MaxWidth(position.width - 60));
if (GUILayout.Button("Copy", GUILayout.Width(40)))
{
EditorGUIUtility.systemCopyBuffer = symbol;
CustomLogger.Info("Define Symbols Setter", ColorPallet.Aqua, $"Symbol '{symbol}' をコピーしました");
ShowNotification(new GUIContent($"'{symbol}' をコピーしました"));
}
EditorGUILayout.EndHorizontal();
}
/// <summary>
/// DefineSymbolsPlatformをBuildTargetGroupに変換
/// </summary>
private BuildTargetGroup PlatformToBuildTargetGroup(DefineSymbolsPlatform platform)
{
return platform switch
{
DefineSymbolsPlatform.Android => BuildTargetGroup.Android,
DefineSymbolsPlatform.iOS => BuildTargetGroup.iOS,
DefineSymbolsPlatform.PC => BuildTargetGroup.Standalone,
_ => BuildTargetGroup.Standalone
};
}
}
#endif
Discussion