UnityのPreloadedAssetsでメモリに常駐するファイルをシンプルに管理する方法です。
Unity2020.1.10
PreloadedAssets?
PreloadedAssetsは登録しておいたアセットをプレイヤーの起動時に自動的に読み込む機能です。
読み込まれたアセットはメモリに常駐するため簡単にアクセスできます。
何らかの初期化に必要な設定ファイルなど、サイズが小さくて起動時に読んでおきたいアセットを管理するのに便利です。
PreloadedAssetsの使い方
PreloadedAssetsは以下のように、PlayerSettings.GetPreloadedAssets()
で取得してPlayerSettings.SetPreloadedAssets()
で上書きします。
// 現在のPreloadedAssetsに登録されているアセットをすべて取得 var preloadedAssets = PlayerSettings.GetPreloadedAssets().ToList(); // 何か足す preloadedAssets.Add(instance); // 上書き PlayerSettings.SetPreloadedAssets(preloadedAssets.ToArray());
こうして登録したアセットは起動時(エディタだったら再生時)に自動的に読み込まれるので、
例えば以下のようにシングルトンなScriptableObjectを通してアクセスします。
using UnityEngine; public class Example : ScriptableObject { public static Example Instance { get; private set; } private void OnEnable() { Instance = this; } }
使用例
最後に使用例として、ScriptableObjectを設定ファイルとして使用する例を掲載します。
using System; using System.IO; using System.Linq; #if UNITY_EDITOR using UnityEditor; #endif using UnityEngine; public class FooConfig : ScriptableObject { private static FooConfig _instance; public static FooConfig Instance { get { #if UNITY_EDITOR if (_instance == null) { var asset = PlayerSettings.GetPreloadedAssets().OfType<FooConfig>().FirstOrDefault(); _instance = asset != null ? asset : CreateDefault(); } return _instance; #else if (_instance == null) { // PreloadedAssetsに登録されていなかったらデフォルトのインスタンスを返す _instance = CreateInstance<FooConfig>(); } return _instance; #endif } private set => _instance = value; } private void OnEnable() { _instance = this; } #if UNITY_EDITOR [MenuItem("Assets/Create/FooConfig")] private static void Create() { // 既に存在していたらエラー var asset = PlayerSettings.GetPreloadedAssets().OfType<FooConfig>().FirstOrDefault(); if (asset != null) { throw new InvalidOperationException($"{nameof(FooConfig)} already exists in preloaded assets"); } var assetPath = EditorUtility.SaveFilePanelInProject($"Save {nameof(FooConfig)}", nameof(FooConfig), "asset", "", "Assets"); if (string.IsNullOrEmpty(assetPath)) { // キャンセルボタン押下 return; } // フォルダがなかったら作る var folderPath = Path.GetDirectoryName(assetPath); if (!string.IsNullOrEmpty(folderPath) && !Directory.Exists(folderPath)) { Directory.CreateDirectory(folderPath); } // アセットを作成してPreloadedAssetsに設定 var instance = CreateInstance<FooConfig>(); AssetDatabase.CreateAsset(instance, assetPath); var preloadedAssets = PlayerSettings.GetPreloadedAssets().ToList(); preloadedAssets.Add(instance); PlayerSettings.SetPreloadedAssets(preloadedAssets.ToArray()); AssetDatabase.SaveAssets(); } #endif }