(:3[kanのメモ帳]

個人ゲーム開発者kan.kikuchiのメモ的技術ブログ。月木更新でUnity関連がメイン。

オブジェクトの検索、選択、アクティブ切替を楽にする【Unity】【エディタ拡張】


このエントリーをはてなブックマークに追加

この記事でのバージョン
Unity 5.6.1f1


はじめに

今回はオブジェクトの検索、選択、アクティブ切替を楽にするエディタ拡張のご紹介!

イメージとしては以下のような感じで、


f:id:kan_kikuchi:20170530055428g:plain


よく使うオブジェクト名を登録しておくと、それをいつでも検索&選択でき、

アクティブ切替もできちゃうと言った具合です。


SelectionWindow

それでは早速、オブジェクトの検索、選択、アクティブ切替を楽にするウィンドウ、

SelectionWindowのプログラムです。


オブジェクトの検索、選択、アクティブ切替を楽にする【Unity】【エディタ拡張】 · GitHub


上記のSelectionWindow.csSelectionWindowObjectInfo.csを作成し、

Editorフォルダに入れると準備完了です。


f:id:kan_kikuchi:20170530055041p:plain


使い方

まず、Window - SelectionWindowを選ぶか、

Shift + Alt + fキーを押すことでSelectionWindowを開きます。


f:id:kan_kikuchi:20170530055211p:plain


次に、任意のオブジェクト名を登録します。

なお、登録したオブジェクトの横にある×ボタンを押すと登録を解除できます。


f:id:kan_kikuchi:20170530060436g:plain


これで検索して選択したり、アクティブ切替ができるようになります。


f:id:kan_kikuchi:20170531070224g:plain


登録した名前に該当するオブジェクトが存在しない場合は選択ボタンが表示されず、

複数存在する場合は全オブジェクトが表示され、かつ一括表示、非表示のボタン

も表示されるようになります。


f:id:kan_kikuchi:20170531070532g:plain


ゲーム中にプログラムから作成された物も、もちろん検索可能です。

ただし、先にオブジェクト名を登録している場合は更新ボタンを押す必要があります。


f:id:kan_kikuchi:20170531071452g:plain


なお、オブジェクト名は数字、アルファベット順、50音順になるよう自動で整列されますし、

登録したオブジェクトが多い場合はスクロールするようになっています。


f:id:kan_kikuchi:20170531072105g:plain


さらに、登録されたオブジェクト名の設定は保存されるため、

SelectionWindowを閉じたりUnityを再起動したりしても、前の状態を維持できます。


実装方法

SelectionWindowの実装に関して、要点だけを説明していきます。


まずオブジェクトの取得についてですが、

Resources.FindObjectsOfTypeAllでHierarchyとProjectにある全オブジェクトを取得した後、

AssetDatabase.GetAssetOrScenePathを使い、その中からシーン(Hierarchy)上にあるものだけを取得

してます。

//全オブジェクト取得、その中からシーン上に存在するオブジェクトを取り出す(非アクティブのものも)
UnityEngine.Object[] allObjectArray      = Resources.FindObjectsOfTypeAll(typeof(GameObject));
List<GameObject>     hierarchyObjectList = new List<GameObject>();

foreach (UnityEngine.Object obj in allObjectArray) {
  if (AssetDatabase.GetAssetOrScenePath(obj).Contains(".unity")){
    hierarchyObjectList.Add(obj as GameObject);
  }
}


なお、オブジェクトの取得にはObject.FindObjectsOfTypeも使えますが、

こちらは非アクティブなオブジェクトが取得できません。


同様にHierarchy上にあるか判定するにはactiveInHierarchyも使えますが、

こちらは非アクティブなオブジェクトはfalseになります。


次にオブジェクトの選択方法ですが、Selectionクラスを使っています。

Selection.activeGameObject = targetObject;


さらに設定の保存には、JsonUtilityEditorUserSettingsを使っています。

SelectionWindowObjectInfoをJsonUtilityでjson化して、

それをEditorUserSettingsで保存している感じです。

//Jsonを読み込み、データがあればjsonから復元、なければ新規作成
string json = EditorUserSettings.GetConfigValue (SAVE_KEY);

if(string.IsNullOrEmpty(json)){
  _infoSet = new SelectionWindowObjectInfoSet();
}
else{
  _infoSet = JsonUtility.FromJson<SelectionWindowObjectInfoSet>(json);
}
//情報をjsonにして保存
private void Save (){
  EditorUserSettings.SetConfigValue (SAVE_KEY, JsonUtility.ToJson(_infoSet));
}



また、開閉のショートカットの設定にはMenuItemを使っています。

//ウィンドウの表示状態を切り替える(Shift + Alt + fキー)
[MenuItem("Window/SelectionWindow #&f+")]
public static void ChangeState (){




おわりに

ゲームの規模が大きくなってくると、オブジェクトも増え、

任意のオブジェクトを探すのも面倒になってくるので、そういう時には結構便利だったりします。


検索だと対象のオブジェクトしかHierarchyに表示されなくなってしまうし、

Inspectorのロックもランタイムで生成されるオブジェクトには使えないので、

そういう意味でも使い勝手は良いです。見栄えは改善の余地ありですが……。