Skip to content

Instantly share code, notes, and snippets.

@kankikuchi
Last active January 7, 2019 06:32
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kankikuchi/b5d3ad9341b26218a7cefe64017b6542 to your computer and use it in GitHub Desktop.
Save kankikuchi/b5d3ad9341b26218a7cefe64017b6542 to your computer and use it in GitHub Desktop.
オブジェクトの検索、選択、アクティブ切替を楽にする【Unity】【エディタ拡張】
// 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);
}
}
}
// 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