Last active
October 2, 2019 11:17
-
-
Save kankikuchi/5dd35f0b5c950d7e2d3e9355176c3641 to your computer and use it in GitHub Desktop.
楽にシーンを開く拡張機能を作ってみた(マルチシーン対応)【Unity】【エディタ拡張】
This file contains hidden or 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
// SceneUnit.cs | |
// http://kan-kikuchi.hatenablog.com/entry/SceneUnit | |
// | |
// Created by kan.kikuchi on 2017.09.16. | |
using UnityEngine; | |
using UnityEditor; | |
using UnityEditor.SceneManagement; | |
using System; | |
using System.IO; | |
using System.Collections.Generic; | |
/// <summary> | |
/// 複数のシーンをまとめるクラス | |
/// </summary> | |
[Serializable] | |
public class SceneUnit{ | |
//名前 | |
[SerializeField] | |
private string _name = ""; | |
//シーンのパスのリスト | |
[SerializeField] | |
private List<string> _pathList = new List<string>(); | |
//================================================================================= | |
//初期化 | |
//================================================================================= | |
/// <summary> | |
/// コンストラクタ | |
/// </summary> | |
public SceneUnit(string name, List<string> pathList){ | |
_name = name; | |
_pathList = new List<string>(pathList); | |
} | |
//================================================================================= | |
//読み込み | |
//================================================================================= | |
/// <summary> | |
/// 設定されているシーンを読み込む | |
/// </summary> | |
public void Load(){ | |
//現在のシーンに変更があった場合、保存するか確認のウィンドウを出す(キャンセルされたら読み込みをしない) | |
if(!EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo()){ | |
return; | |
} | |
//シーンが存在するかチェック | |
for (int i = 0; i < _pathList.Count; i++) { | |
string path = _pathList[i]; | |
if(AssetDatabase.LoadAssetAtPath<SceneAsset>(path) == null){ | |
Debug.LogError(path + "が存在しません!"); | |
return; | |
} | |
} | |
//シーンを開く | |
for (int i = 0; i < _pathList.Count; i++) { | |
EditorSceneManager.OpenScene (_pathList[i], i == 0 ? OpenSceneMode.Single : OpenSceneMode.Additive); | |
} | |
} | |
//================================================================================= | |
//取得 | |
//================================================================================= | |
/// <summary> | |
/// 名前とパスをまとめたものを取得 | |
/// </summary> | |
public string GetNameAndPath(){ | |
//シーンの名前をまとめて表示 | |
string nameAndPath = ""; | |
foreach (string path in _pathList) { | |
if(!string.IsNullOrEmpty(nameAndPath)){ | |
nameAndPath += " + "; | |
} | |
nameAndPath += Path.GetFileNameWithoutExtension(path); | |
} | |
return _name + " : (" + nameAndPath + ")"; | |
} | |
} | |
/// <summary> | |
/// 複数のシーンをまとめるクラスをまとめたもの | |
/// </summary> | |
[Serializable] | |
public class SceneUnitSet{ | |
//インスタンス | |
private static SceneUnitSet _instance; | |
public static SceneUnitSet Instance { | |
get { | |
if (_instance == null) { | |
//セーブデータのJsonを読み込み、データがあれば復元 | |
string json = EditorUserSettings.GetConfigValue(SAVE_KEY); | |
if(string.IsNullOrEmpty(json)){ | |
_instance = new SceneUnitSet(); | |
} | |
else{ | |
_instance = JsonUtility.FromJson<SceneUnitSet>(json); | |
} | |
} | |
return _instance; | |
} | |
} | |
//設定されたシーンユニットをまとめたList | |
[SerializeField] | |
private List<SceneUnit> _sceneUnitList = new List<SceneUnit>(); | |
//シーンユニットの数 | |
public int UnitNum{get{return _sceneUnitList.Count;}} | |
//設定を保存する時のKey | |
private const string SAVE_KEY = "SCENE_UNIT_SAVE_KEY"; | |
//================================================================================= | |
//保存と読み込み | |
//================================================================================= | |
//SceneUnitSetの保存 | |
private void SaveSceneUnitList(){ | |
EditorUserSettings.SetConfigValue (SAVE_KEY, JsonUtility.ToJson(this)); | |
} | |
//================================================================================= | |
//追加、取得、削除 | |
//================================================================================= | |
/// <summary> | |
/// SceneUnitを作成し、追加 | |
/// </summary> | |
public void Add(string sceneUnitName, List<string> scenePathList){ | |
//シーンユニットの名前が入力されていなければ、番号を設定 | |
if(string.IsNullOrEmpty(sceneUnitName)){ | |
sceneUnitName = UnitNum.ToString(); | |
} | |
_sceneUnitList.Add(new SceneUnit(sceneUnitName, scenePathList)); | |
SaveSceneUnitList(); | |
} | |
/// <summary> | |
/// 指定した番号のSceneUnitを取得 | |
/// </summary> | |
public SceneUnit GetAtNo(int no){ | |
return _sceneUnitList[no]; | |
} | |
/// <summary> | |
/// SceneUnitを削除 | |
/// </summary> | |
public void Remove(SceneUnit sceneUnit){ | |
_sceneUnitList.Remove(sceneUnit); | |
SaveSceneUnitList(); | |
} | |
//================================================================================= | |
//入れ替え | |
//================================================================================= | |
/// <summary> | |
/// 要素を移動する | |
/// </summary> | |
public void Move(SceneUnit sceneUnit, bool isUp){ | |
int beforeNo = _sceneUnitList.IndexOf(sceneUnit); | |
int afterNo = beforeNo + (isUp ? - 1 : 1); | |
_sceneUnitList[beforeNo] = _sceneUnitList[afterNo]; | |
_sceneUnitList[afterNo] = sceneUnit; | |
SaveSceneUnitList(); | |
} | |
} |
This file contains hidden or 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
// SceneUnitWindow.cs | |
// http://kan-kikuchi.hatenablog.com/entry/SceneUnit | |
// | |
// Created by kan.kikuchi on 2017.09.16. | |
using UnityEditor; | |
using UnityEditor.SceneManagement; | |
using UnityEngine; | |
using System; | |
using System.IO; | |
using System.Linq; | |
using System.Collections.Generic; | |
/// <summary> | |
/// 複数のシーンの一度に開くためのウィンドウ | |
/// </summary> | |
public class SceneUnitWindow : EditorWindow { | |
//スクロール位置 | |
private Vector2 _scrollPosition = Vector2.zero; | |
//プロジェクト内の全シーンのパスと、それが選択されているか | |
private Dictionary<string, bool> _scenePathDict = new Dictionary<string, bool>(); | |
//選択中のシーンのパスのList | |
private List<string> _selectingScenePathList = new List<string>(); | |
//シーンユニットの名前 | |
private string _sceneUnitName = ""; | |
//================================================================================= | |
//ウィンドウ表示 | |
//================================================================================= | |
//メニューからウィンドウを表示 | |
[MenuItem("Window/SceneUnitWindow")] | |
public static void Open (){ | |
SceneUnitWindow.GetWindow<SceneUnitWindow>(typeof(SceneUnitWindow)); | |
} | |
//================================================================================= | |
//初期化 | |
//================================================================================= | |
//初期化 | |
private void Init(){ | |
_scenePathDict = AssetDatabase.FindAssets("t:SceneAsset") //シーンのアセットのGUIDを取得 | |
.Select(guid => AssetDatabase.GUIDToAssetPath(guid)) //GUIDからパスに変換 | |
.ToDictionary(path => path, flag => false); //パスをKey、選択中かのフラグをfalseにしてDictonary作成 | |
_sceneUnitName = ""; | |
_selectingScenePathList.Clear(); | |
} | |
private void OnEnable(){ | |
Init(); | |
} | |
//================================================================================= | |
//表示するGUIの設定 | |
//================================================================================= | |
private void OnGUI(){ | |
//描画範囲が足りなければスクロール出来るように | |
_scrollPosition = EditorGUILayout.BeginScrollView(_scrollPosition, GUI.skin.scrollView); | |
EditorGUILayout.BeginVertical(GUI.skin.box);{ | |
if(SceneUnitSet.Instance.UnitNum != 0){ | |
OnGUIWithTitle(OnSettingSceneGUI, "設定したシーンユニット"); | |
} | |
OnGUIWithTitle(OnAllSceneGUI, "プロジェクト内のシーン"); | |
if(_selectingScenePathList.Count != 0){ | |
OnGUIWithTitle(OnSelectingSceneGUI, "選択中のシーン"); | |
} | |
}EditorGUILayout.EndVertical(); | |
EditorGUILayout.EndScrollView(); | |
} | |
//装飾とタイトルを付けて、GUIを表示 | |
private void OnGUIWithTitle(Action onGUIAction, string title){ | |
EditorGUILayout.BeginVertical(GUI.skin.box);{ | |
EditorGUILayout.LabelField(title); | |
GUILayout.Space(10); | |
onGUIAction(); | |
}EditorGUILayout.EndVertical(); | |
GUILayout.Space (10); | |
} | |
//設定したシーン一覧を表示するGUIの設定 | |
private void OnSettingSceneGUI(){ | |
for (int i = 0; i < SceneUnitSet.Instance.UnitNum; i++) { | |
EditorGUILayout.BeginHorizontal (GUI.skin.box); | |
//削除ボタン表示 | |
if (GUILayout.Button ("×", GUILayout.Width (20))) { | |
SceneUnitSet.Instance.Remove(SceneUnitSet.Instance.GetAtNo(i)); | |
return; | |
} | |
//読み込みボタン表示 | |
EditorGUILayout.LabelField (SceneUnitSet.Instance.GetAtNo(i).GetNameAndPath()); | |
if (GUILayout.Button ("読み込み", GUILayout.Width (100))) { | |
SceneUnitSet.Instance.GetAtNo(i).Load(); | |
return; | |
} | |
//上下ボタン表示 | |
if (i > 0) { | |
if (GUILayout.Button ("↑", GUILayout.Width (20))) { | |
SceneUnitSet.Instance.Move(SceneUnitSet.Instance.GetAtNo(i), isUp:true); | |
return; | |
} | |
} | |
else { | |
GUILayout.Label ("", GUILayout.Width (20)); | |
} | |
if(i < SceneUnitSet.Instance.UnitNum - 1) { | |
if (GUILayout.Button ("↓", GUILayout.Width (20))) { | |
SceneUnitSet.Instance.Move(SceneUnitSet.Instance.GetAtNo(i), isUp:false); | |
return; | |
} | |
} | |
else { | |
GUILayout.Label ("", GUILayout.Width (20)); | |
} | |
EditorGUILayout.EndHorizontal (); | |
} | |
} | |
//プロジェクト内の全シーンを表示するのGUIの設定 | |
private void OnAllSceneGUI(){ | |
//全シーンのパスを表示 | |
List<string> changedPathList = new List<string>(); | |
foreach (KeyValuePair<string, bool> pair in _scenePathDict) { | |
EditorGUILayout.BeginHorizontal (GUI.skin.box); | |
bool beforeFlag = pair.Value; | |
bool afterFlag = EditorGUILayout.ToggleLeft(Path.GetFileNameWithoutExtension(pair.Key), beforeFlag); | |
//チェックボックスの変更があればListに登録 | |
if(beforeFlag != afterFlag){ | |
changedPathList.Add(pair.Key); | |
} | |
//読み込みボタン表示 | |
if(GUILayout.Button ("読み込み", GUILayout.Width (100))) { | |
//現在のシーンに変更があった場合、保存するか確認のウィンドウを出す(キャンセルされたら読み込みをしない) | |
if(!EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo()){ | |
return; | |
} | |
//シーンが存在するかチェック | |
if(AssetDatabase.LoadAssetAtPath<SceneAsset>(pair.Key) == null){ | |
Debug.LogError(pair.Key + "が存在しません!"); | |
return; | |
} | |
//シーン読み込み | |
EditorSceneManager.OpenScene (pair.Key); | |
return; | |
} | |
EditorGUILayout.EndHorizontal (); | |
} | |
//変更があったパスのフラグを変更、選択中のシーンのListも更新 | |
foreach (string changedPath in changedPathList) { | |
_scenePathDict[changedPath] = !_scenePathDict[changedPath]; | |
if(_scenePathDict[changedPath]){ | |
_selectingScenePathList.Add(changedPath); | |
} | |
else{ | |
_selectingScenePathList.Remove(changedPath); | |
} | |
} | |
GUILayout.Space (10); | |
//シーン再取得と選択全解除を行うボタン表示 | |
if(GUILayout.Button ("シーン再取得、選択全解除")){ | |
Init(); | |
} | |
} | |
//選択中のシーンを表示するGUI | |
private void OnSelectingSceneGUI(){ | |
//選択中のシーンを表示 | |
EditorGUILayout.BeginVertical(GUI.skin.box);{ | |
for (int i = 0; i < _selectingScenePathList.Count; i++) { | |
string path = _selectingScenePathList[i]; | |
EditorGUILayout.LabelField((i + 1).ToString() + " : " + Path.GetFileNameWithoutExtension(path)); | |
} | |
}EditorGUILayout.EndVertical(); | |
GUILayout.Space (10); | |
//シーンユニットの名前を入力するGUIを表示 | |
_sceneUnitName = EditorGUILayout.TextField("シーンユニット名", _sceneUnitName); | |
GUILayout.Space (10); | |
//シーンユニットの設定を行うボタン表示 | |
if(GUILayout.Button ("設定")){ | |
SceneUnitSet.Instance.Add(_sceneUnitName, _selectingScenePathList); | |
Init(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment