0. 完成像
UnityのSceneのリスト(もう少し具体的に言うと Build Settings
で登録済みのSceneのリスト)は、 UnityEditor.EditorBuildSettings.scenes
で取得できる。
ただ、どう見てもエディタ上でのみ動かすAPIで、実際のランタイム使用に耐えうるものではない。
今後、必要があるかはともかく、ランタイムで使用でき、かつ自動で保存・更新の機構があるSceneリストの実装をちょっと残しておこうと思う。
1. プログラム
CurrentScenesObserver.cs
using System;
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace UnitySceneList.RunTime
{
/// <summary>
/// シーンリストに登録されているシーンの名前情報をランタイムまで保持しておくScriptableObject
/// </summary>
public sealed class CurrentScenesObserver : ScriptableObject
{
[SerializeField, ToolTip("シーン名とその詳細説明のデータ群")]
private CurrentSceneData[] currentSceneDatas = null;
/// <summary>
/// シーンリストに登録されているシーンのデータを返す
/// </summary>
/// <returns>シーン名とその詳細説明</returns>
public (string sceneName, string detail)[] GetCurrentSceneDatas()
{
return Array.ConvertAll(currentSceneDatas, data => data.SceneData);
}
#if UNITY_EDITOR
[InitializeOnLoadMethod]
private static void Initialize()
{
EditorBuildSettings.sceneListChanged += () =>
{
var scenes = EditorBuildSettings.scenes;
// CurrentScenesObserverのインスタンスを取得
string[] guids = AssetDatabase.FindAssets($"t:{nameof(CurrentScenesObserver)}");
if (guids.Length != 1) return;
CurrentScenesObserver instance = AssetDatabase.LoadAssetAtPath<CurrentScenesObserver>(AssetDatabase.GUIDToAssetPath(guids[0]));
// シーンが一つもない場合はnullを代入
if (scenes.Length == 0)
{
instance.currentSceneDatas = null;
return;
}
// シーンが一つ以上ある場合はシーンのデータを代入
instance.currentSceneDatas = new CurrentSceneData[scenes.Length];
for (int i = 0; i < scenes.Length; i++)
{
string sceneName = System.IO.Path.GetFileNameWithoutExtension(scenes[i].path);
instance.currentSceneDatas[i] = new CurrentSceneData(sceneName, sceneName);
}
};
}
#endif
}
/// <summary>
/// シーン単体のデータ
/// </summary>
[Serializable]
internal struct CurrentSceneData
{
[SerializeField, Tooltip("シーン名")]
private string sceneName;
[SerializeField, Tooltip("シーンの詳細説明")]
private string detail;
/// <summary>
/// シーンのデータを返す
/// </summary>
internal (string sceneName, string detail) SceneData => (sceneName, detail);
/// <summary>
/// コンストラクタ
/// </summary>
/// <param name="sceneName">シーン名</param>
/// <param name="detail">シーンの詳細説明</param>
internal CurrentSceneData(string sceneName, string detail)
{
this.sceneName = sceneName;
this.detail = detail;
}
}
}