Unityのツールバー拡張と言ったらコレでしょ!
という事で、Project内のシーンを列挙して簡単に切り替えられるエディタ拡張となります
いやー、本当にMainToolbar拡張の標準サポートは有難いですねぇ。
前提
本記事は
- Uniy 6000.3.8f1
- Windows
環境で記載されています
コード
という事でコードです
MainToolbarSceneDropDown.cs
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEditor.Toolbars;
using UnityEngine;
using UnityEngine.SceneManagement;
namespace ScreenPocket.Core.Editor
{
/// <summary>
/// ツールバーにSceneを表示
/// </summary>
public static class MainToolbarSceneDropDown
{
private const string ElementPath = "ScreenPocket/Scene";
private const string IconFilePath = "d_SceneAsset Icon";
private const string ToolTip = "Project内のScene一覧を表示し、選択する事でシーン変更できます";
private const string SceneSearchFilter = "t:Scene";
private static readonly string[] SceneSearchTargetFolders = {"Assets/"};
/// <summary>
/// DropDown作成
/// </summary>
/// <returns></returns>
[MainToolbarElement(ElementPath, defaultDockPosition = MainToolbarDockPosition.Left)]
private static MainToolbarElement CreateDropdown()
{
EditorSceneManager.sceneOpened -= OnSceneOpened;
EditorSceneManager.sceneOpened += OnSceneOpened;
var icon = (Texture2D)EditorGUIUtility.Load(IconFilePath);
var sceneName = GetActiveScene().name;
var content = new MainToolbarContent(sceneName, icon, ToolTip);
return new MainToolbarDropdown(content, ShowDropdownMenu);
}
/// <summary>
/// アクティブシーンを取得
/// </summary>
/// <returns>アクティブシーン</returns>
private static Scene GetActiveScene() => UnityEngine.SceneManagement.SceneManager.GetActiveScene();
/// <summary>
/// DropDownを押された時のコールバック
/// </summary>
/// <param name="dropDownRect"></param>
private static void ShowDropdownMenu(Rect dropDownRect)
{
//Packages以下は不要なのでAssets以下とする
var guids = AssetDatabase.FindAssets(SceneSearchFilter, SceneSearchTargetFolders);
//Scene一覧をメニュー項目に並べる
var menu = new GenericMenu();
//チェック用パス
var activeScene = GetActiveScene();
var activeScenePath = activeScene.path;
foreach (var guid in guids)
{
var path = AssetDatabase.GUIDToAssetPath(guid);
var on = path == activeScenePath;
menu.AddItem(new GUIContent(path), on, () =>
{
//変更チェック&保存確認
if (!EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo())
{
//キャンセルで抜ける
return;
}
EditorSceneManager.OpenScene(path);
});
}
menu.DropDown(dropDownRect);
}
/// <summary>
/// シーン開き時のコールバック
/// </summary>
/// <param name="scene"></param>
/// <param name="mode"></param>
private static void OnSceneOpened(Scene scene, OpenSceneMode mode)
{
//シーン名の更新
MainToolbar.Refresh(ElementPath);
}
}
}
たったの(?)90行!
ポイントは
- プロジェクト全体と言っても、"Assets/"以下でないとPackagesの下も調べに行ってしまうのでそこだけ制限してます
- SaveCurrentModifiedScenesIfUserWantsTo() で保存確認は大事
- MainToolbar.Refresh()はOpenScene()の下に置いても良いかなぁと思いつつも、別ステップでシーンを開かれたときに備えてコールバック化
- OnOpenedSceneでなくてOnSceneOpenedなのはUnity内部の記載に揃えています
って感じでしょうか
終わりに
という事で、よくあるシーンチェンジャーでした。
よくある割に、今までQiitaに書いたことが無い&Unity側がオフィシャルにMainToolbarをサポートしてくれたので忘れないうちに書いておきます。
シーンの数が膨大になってきたら辿るのが大変になるので、フィルタリングできるように改造しても良さそうですね~