Last active
January 7, 2019 06:32
-
-
Save kankikuchi/b5d3ad9341b26218a7cefe64017b6542 to your computer and use it in GitHub Desktop.
オブジェクトの検索、選択、アクティブ切替を楽にする【Unity】【エディタ拡張】
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// SelectionWindow.cs | |
// http://kan-kikuchi.hatenablog.com/entry/SelectionWindow | |
// | |
// Created by kan kikuchi on 2017.05.26. | |
using System; | |
using System.Linq; | |
using System.Collections.Generic; | |
using UnityEditor; | |
using UnityEngine; | |
/// <summary> | |
/// オブジェクトの検索、選択、アクティブ切替を楽にするウィンドウ | |
/// </summary> | |
[InitializeOnLoad] | |
public class SelectionWindow : EditorWindow { | |
//生成したウィンドウ | |
private static SelectionWindow _selectionWindow = null; | |
//入力したのオブジェクトの名前 | |
private string _inputObjectName = ""; | |
//登録時の警告文 | |
private string _registrationWarningText = ""; | |
//操作対象のオブジェクトの情報の集合クラス | |
private SelectionWindowObjectInfoSet _infoSet = null; | |
//スクロール位置 | |
private Vector2 _scrollPosition = Vector2.zero; | |
//設定を保存する時のKey | |
private const string SAVE_KEY = "SELECTION_WINDO_SAVE_KEY"; | |
//================================================================================= | |
//初期化 | |
//================================================================================= | |
public void Awake (){ | |
//Jsonを読み込み、データがあればjsonから復元、なければ新規作成 | |
string json = EditorUserSettings.GetConfigValue (SAVE_KEY); | |
if(string.IsNullOrEmpty(json)){ | |
_infoSet = new SelectionWindowObjectInfoSet(); | |
} | |
else{ | |
_infoSet = JsonUtility.FromJson<SelectionWindowObjectInfoSet>(json); | |
} | |
_infoSet.Update(); | |
} | |
//================================================================================= | |
//保存 | |
//================================================================================= | |
//情報をjsonにして保存 | |
private void Save (){ | |
EditorUserSettings.SetConfigValue (SAVE_KEY, JsonUtility.ToJson(_infoSet)); | |
} | |
//================================================================================= | |
//ウィンドウ表示 | |
//================================================================================= | |
//ウィンドウの表示状態を切り替える(Shift + Alt + fキー) | |
[MenuItem("Window/SelectionWindow #&f+")] | |
public static void ChangeState (){ | |
if(_selectionWindow == null){ | |
_selectionWindow = SelectionWindow.GetWindow (typeof(SelectionWindow)) as SelectionWindow; | |
} | |
else{ | |
_selectionWindow.Close(); | |
_selectionWindow = null; | |
} | |
} | |
//================================================================================= | |
//表示するGUIの設定 | |
//================================================================================= | |
private void OnGUI(){ | |
//オブジェクトの名前を登録するためのテキスト入力GUIとボタンを表示 | |
EditorGUILayout.BeginVertical(GUI.skin.box);{ | |
//警告文が設定されていたら表示 | |
if(string.IsNullOrEmpty(_registrationWarningText)){ | |
EditorGUILayout.LabelField("オブジェクト名登録"); | |
} | |
else{ | |
EditorGUILayout.HelpBox(_registrationWarningText, MessageType.Warning); | |
} | |
//入力欄の表示 | |
string beforeInputObjectName = _inputObjectName; | |
_inputObjectName = EditorGUILayout.TextField(_inputObjectName); | |
//入力が変更されたら警告を非表示に | |
if(beforeInputObjectName != _inputObjectName){ | |
_registrationWarningText = ""; | |
} | |
//登録ボタン表示 | |
if(GUILayout.Button ("登録", GUILayout.Width(150))){ | |
RegisterNewObjectName(); | |
} | |
}EditorGUILayout.EndVertical(); | |
GUILayout.Space (10); | |
//操作対象のオブジェクトが登録されていなければここで終了 | |
if(_infoSet.InfoList.Count == 0){ | |
return; | |
} | |
//設定したオブジェクトがなくなってたら更新するように | |
foreach (SelectionWindowObjectInfo info in _infoSet.InfoList) { | |
if(info.HasNullGameObject()){ | |
_infoSet.Update(); | |
break; | |
} | |
} | |
EditorGUILayout.BeginVertical(GUI.skin.box);{ | |
EditorGUILayout.LabelField("オブジェクトの情報一覧"); | |
//更新ボタン表示 | |
if(GUILayout.Button ("更新", GUILayout.Width(150))){ | |
_infoSet.Update(); | |
} | |
GUILayout.Space (10); | |
//スクロール開始位置 | |
_scrollPosition = EditorGUILayout.BeginScrollView(_scrollPosition, GUI.skin.scrollView); | |
//各操作対象のオブジェクトの情報を表示 | |
for (int i = 0; i < _infoSet.InfoList.Count; i++) { | |
ShowInfo(_infoSet.InfoList[i]); | |
} | |
//スクロール終了位置 | |
EditorGUILayout.EndScrollView(); | |
}EditorGUILayout.EndVertical(); | |
} | |
//各操作対象のオブジェクトの情報を表示 | |
private void ShowInfo(SelectionWindowObjectInfo info){ | |
EditorGUILayout.BeginHorizontal(GUI.skin.box); | |
//削除ボタン | |
if(GUILayout.Button ("×", GUILayout.Width(20))){ | |
_infoSet.InfoList.Remove(info); | |
Save(); | |
return; | |
} | |
//要素が2個以上あれば、一括表示切替ボタン表示 | |
if(info.ObjectList.Count >= 2){ | |
EditorGUILayout.LabelField(info.ObjectName, GUILayout.MaxWidth(80)); | |
if(GUILayout.Button ("一括表示", GUILayout.Width(70))){ | |
SetActive(info, true); | |
} | |
if(GUILayout.Button ("一括非表示", GUILayout.Width(70))){ | |
SetActive(info, false); | |
} | |
} | |
else{ | |
EditorGUILayout.LabelField(info.ObjectName, GUILayout.MaxWidth(230)); | |
//操作対象のオブジェクトが存在しなければここで終了 | |
if(info.ObjectList.Count == 0){ | |
EditorGUILayout.EndHorizontal(); | |
return; | |
} | |
} | |
EditorGUILayout.EndHorizontal(); | |
EditorGUI.indentLevel = 2; | |
//各オブジェクトごとに | |
foreach (GameObject targetObject in info.ObjectList) { | |
EditorGUILayout.BeginHorizontal();{ | |
//オブジェクト名と示切替トグル表示 | |
bool isActive = EditorGUILayout.ToggleLeft(targetObject.name, targetObject.activeSelf, GUILayout.Width(155)); | |
if(isActive != targetObject.activeSelf){ | |
targetObject.SetActive(isActive); | |
} | |
//選択ボタン | |
if(GUILayout.Button ("選択", GUILayout.Width(50))){ | |
Selection.activeGameObject = targetObject; | |
} | |
}EditorGUILayout.EndHorizontal(); | |
} | |
EditorGUI.indentLevel = 0; | |
} | |
//================================================================================= | |
//オブジェクトの情報 | |
//================================================================================= | |
//新しくオブジェクト名を登録する | |
private void RegisterNewObjectName(){ | |
if(string.IsNullOrEmpty(_inputObjectName)){ | |
_registrationWarningText = "オブジェクト名が入力されていません!"; | |
return; | |
} | |
//既に同じオブジェクト名が登録されていないかチェック | |
foreach (SelectionWindowObjectInfo info in _infoSet.InfoList) { | |
if(info.ObjectName == _inputObjectName){ | |
_registrationWarningText = "既に" + _inputObjectName + "は登録されています!"; | |
return; | |
} | |
} | |
//新しくオブジェクト名を登録し、更新、警告を非表示に | |
_infoSet.InfoList.Add(new SelectionWindowObjectInfo(_inputObjectName)); | |
_registrationWarningText = ""; | |
_infoSet.Update(); | |
//保存 | |
Save(); | |
} | |
//入力した情報に含まれる全オブジェクトのアクティブ設定を行う | |
private void SetActive(SelectionWindowObjectInfo info, bool isActive){ | |
foreach (GameObject gameObject in info.ObjectList) { | |
gameObject.SetActive(isActive); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// SelectionWindowObjectInfo.cs | |
// http://kan-kikuchi.hatenablog.com/entry/SelectionWindow | |
// | |
// Created by kan kikuchi on 2017.05.26. | |
using System; | |
using System.Linq; | |
using System.Collections.Generic; | |
using UnityEditor; | |
using UnityEngine; | |
/// <summary> | |
/// SelectionWindowでの操作対象のオブジェクトの情報 | |
/// </summary> | |
[Serializable] | |
public class SelectionWindowObjectInfo{ | |
[SerializeField] | |
private string _objectName = ""; | |
public string ObjectName{get{return _objectName;}} | |
private List<GameObject> _objectlist = new List<GameObject>(); | |
public List<GameObject> ObjectList{get{return _objectlist;}} | |
//================================================================================= | |
//初期化 | |
//================================================================================= | |
public SelectionWindowObjectInfo(string objectName){ | |
_objectName = objectName; | |
} | |
//================================================================================= | |
//設定 | |
//================================================================================= | |
/// <summary> | |
/// 入力されたオブジェクト群から、対象の名前を含むものだけ設定する | |
/// </summary> | |
public void SetObject(List<GameObject> gameObjectList){ | |
_objectlist = new List<GameObject>(); | |
List<GameObject> tmpObjectlist = new List<GameObject>(); | |
foreach (GameObject gameObject in gameObjectList) { | |
//完全一致しているものはそのまま追加 | |
if(gameObject.name == _objectName){ | |
_objectlist.Add(gameObject); | |
} | |
//部分一致しているものは一時的に違うリストに | |
else if(gameObject.name.Contains(_objectName)){ | |
tmpObjectlist.Add(gameObject); | |
} | |
} | |
//部分一致しているものをオブジェクト名で昇順に並び替え | |
tmpObjectlist = tmpObjectlist.OrderBy(gameObject => gameObject.name).ToList(); | |
//完全一致しているものの後に部分一致しているものを追加 | |
_objectlist.AddRange(tmpObjectlist); | |
} | |
//================================================================================= | |
//判定 | |
//================================================================================= | |
/// <summary> | |
/// 設定されているGameObjectに、nullのものがあるかを判定 | |
/// </summary> | |
public bool HasNullGameObject(){ | |
foreach (GameObject gameObject in _objectlist) { | |
if(gameObject == null){ | |
return true; | |
} | |
} | |
return false; | |
} | |
} | |
/// <summary> | |
/// SelectionWindowでの操作対象のオブジェクトの情報の集合クラス | |
/// </summary> | |
[Serializable] | |
public class SelectionWindowObjectInfoSet{ | |
//操作対象のオブジェクトの情報 | |
[SerializeField] | |
private List<SelectionWindowObjectInfo> _infoList = new List<SelectionWindowObjectInfo>(); | |
public List<SelectionWindowObjectInfo> InfoList{get{return _infoList;}} | |
//================================================================================= | |
//更新 | |
//================================================================================= | |
/// <summary> | |
/// 操作対象のオブジェクトの情報を更新する | |
/// </summary> | |
public void Update(){ | |
//全オブジェクト取得、その中からシーン上に存在するオブジェクトを取り出す(非アクティブのものも) | |
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); | |
} | |
} | |
foreach (SelectionWindowObjectInfo info in _infoList) { | |
info.SetObject(hierarchyObjectList); | |
} | |
//オブジェクト名で昇順に並び替え | |
_infoList = _infoList.OrderBy(info => info.ObjectName).ToList(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment