エディタ拡張でDefineSymbolsのプリセットを作成する

#環境
Unity5.6.2f1

#概要
同じビルドターゲットでDefine定義でのモード切り替えを行いたい為に、DefineSymbolsのプリセットを作成してみました
ビルドターゲットはチェックボックスで複数指定できるので一括で変更できます

#プログラム
Assets/Editor/DefineSymbolsWindow.cs

~~~c#
using System.IO;
using UnityEditor;
using UnityEngine;

public class DefineSymbolsWindow : EditorWindow
{
	[MenuItem( "Tools/DefineSymbols" )]
	public static void Create()
	{
		var window = GetWindow<DefineSymbolsWindow>( "DefineSymbolsWindow" );
		window.Show();
	}

	private DefineSymbols _obj = null;

	private void OnEnable()
	{
		var ms = MonoScript.FromScriptableObject( this );
		var path = AssetDatabase.GetAssetPath( ms );
		path = path.Replace( Path.GetFileName( path ), "" );
	//	Debug.Log( "path:" + path );
		path = path + "DefineSymbols.asset";
		_obj = AssetDatabase.LoadAssetAtPath<DefineSymbols>( path );
		if( _obj == null )
		{
			_obj = ScriptableObject.CreateInstance<DefineSymbols>();
			AssetDatabase.CreateAsset( _obj, path );
			AssetDatabase.ImportAsset( path, ImportAssetOptions.ForceUpdate | ImportAssetOptions.ImportRecursive );
		}
 	}

	private void OnDisable()
	{
		if( _obj == null )
			return;
		EditorUtility.SetDirty( _obj );
		AssetDatabase.ImportAsset( AssetDatabase.GetAssetPath( _obj ), ImportAssetOptions.ForceUpdate | ImportAssetOptions.ImportRecursive );
	}

	private void OnGUI()
	{
		_obj.OnGUI();
		Repaint();
	}
}
~~~
Assets/Editor/DefineSymbols.cs

~~~c#
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;

public class DefineSymbols : ScriptableObject
{
	[Serializable]
	private class SymbolParam
	{
		public string name;
		public string symbols;
		public List<string> targets = new List<string>();
	}
	[SerializeField] private List<SymbolParam> _symbolParams = new List<SymbolParam>();
	[SerializeField] private int _selectedDropdownList = 0;
	private string _newParamName = "";
	private string _defineSymbols = null;

	private void OnEnable()
	{
	}

	private void OnDisable()
	{
	}

	public void OnGUI()
	{
		GUILayout.Label( "New Preset" );
		using ( var horizontalScope = new GUILayout.HorizontalScope() )
		{
			_newParamName = EditorGUILayout.TextField("", _newParamName );
			if( GUILayout.Button( "Add" ) == true )
			{
				if( _newParamName.Length > 0 && _symbolParams.Count( x => x.name == _newParamName ) == 0 )
				{
					_selectedDropdownList = _symbolParams.Count;
					var newParam = new SymbolParam();
					newParam.name = _newParamName;
					_symbolParams.Add( newParam );
					_newParamName = null;
				}
			}
		}

		GUILayout.Label( "Presets" );

		var names = new string[ _symbolParams.Count ];
		for( int i = 0; i < _symbolParams.Count; i++ )
			names[ i ] = _symbolParams[ i ].name;
		var prevSelectedDropdownList = _selectedDropdownList;
		_selectedDropdownList = EditorGUILayout.Popup( "", _selectedDropdownList, names );
		SymbolParam param = null;
		if( _selectedDropdownList >= 0 &&  _selectedDropdownList < _symbolParams.Count )
			param = _symbolParams[ _selectedDropdownList ];

		if ( _selectedDropdownList != prevSelectedDropdownList )
		{
		//	if( param != null )
		//		FlushSymbolsByTargets( param );
		}


		using ( var horizontalScope = new GUILayout.HorizontalScope() )
		{
			EditorGUILayout.Space();
			EditorGUILayout.Space();
			EditorGUILayout.Space();
			if( GUILayout.Button( "Remove" ) == true )
			{
				if( param != null )
				{
					_symbolParams.RemoveAt( _selectedDropdownList );
					_selectedDropdownList = Mathf.Clamp( _selectedDropdownList, -1, _symbolParams.Count - 1 );
					return;	//消したのでここで打ち切る
				}
			}
		}

		GUILayout.Label( "Define Symboles" );

		if( param != null )
		{
			param.symbols = EditorGUILayout.TextField( "", param.symbols );
			var rect = GUILayoutUtility.GetLastRect();
			if( Event.current.type == EventType.Repaint && rect.Contains( Event.current.mousePosition ) == false )
			{
				if( _defineSymbols != param.symbols )
				{
					//Debug.Log( "ChangeDefineSymbol:" + param.symbols );
					_defineSymbols = param.symbols;
					FlushSymbolsByTargets( param );
				}
			}
		}
		else
			EditorGUILayout.TextField( "", "" );

		GUILayout.Label( "Targets" );

		var targetNames = Enum.GetNames( typeof( BuildTargetGroup ) ).ToList();
		targetNames.Remove( "Unknown" );
		int cx = 3;
		int cy = targetNames.Count / cx + ( ( ( targetNames.Count % cx ) > 0 ) ? 1 : 0 );
		using ( var verticalScope = new GUILayout.VerticalScope() )
		{
			for( int y = 0; y < cy; y++ )
			{
				using ( var horizontalScope = new GUILayout.HorizontalScope() )
				{
					for( int x = 0; x < cx; x++ )
					{
						var i = ( y * cx ) + x;
						if( i >= targetNames.Count )
						{
							EditorGUILayout.LabelField( "" );
							continue;
						}

						if( param != null )
						{
							var toggle = false;
							if( param.targets.FirstOrDefault( name => name == targetNames[ i ] ) != null )
								toggle = true;

							var newToggle = EditorGUILayout.ToggleLeft( targetNames[ i ], toggle );
							if( toggle == false && newToggle == true )
							{
								param.targets.Add( targetNames[ i ] );
								FlushSymbols( targetNames[ i ], param.symbols );
							}
							else if( toggle == true && newToggle == false )
							{
								param.targets.Remove( targetNames[ i ] );
								FlushSymbols( targetNames[ i ], "" );
							}
						}
						else
							EditorGUILayout.ToggleLeft( targetNames[ i ], false );
					}
				}
			}
		}
	}

	private void FlushSymbols( string targetName, string defineSymbols )
	{
		var names = Enum.GetNames( typeof( BuildTargetGroup ) );
		var values = Enum.GetValues( typeof( BuildTargetGroup ) );
		var indices = names.Select( ( n, i ) => new { name = n, index = i } ).Where( x => x.name == targetName ).Select( x => x.index );
		if( indices.Count() == 0 )
			return;
		var index = indices.ElementAt( 0 );
		var target = (BuildTargetGroup)values.GetValue( index );
		PlayerSettings.SetScriptingDefineSymbolsForGroup( target, defineSymbols );
	}

	private void FlushSymbolsByTargets( SymbolParam param )
	{
		for( int i = 0; i < param.targets.Count; i++ )
			FlushSymbols( param.targets[ i ], param.symbols );
	}
}
~~~