0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

UnityのSceneのリストをランタイムでも使用できる形で自動保存する

Posted at

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;
        }
    }
}
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?