Foundation Services
OpenMon.Foundation 层是整个引擎所依托的共享框架:依赖注入、持久化、场景管理与本地化。这些接口
稳定、可通过 Zenject 注入,并可在你自己的系统中复用。本页记录三个服务接口,以及你最常继承的两个
DI 辅助类。
OpenMon.Foundation 中的任何内容都不了解怪物或对战。注入这些接口(而非具体实现)可让你的代码保持
可测试,并允许引擎在不破坏你的前提下替换实现。
IPersister
Namespace: OpenMon.Foundation.Persistence
每次保存背后的存储抽象。实现(JsonFilePersister、ConfigurationJsonFilePersister 等)决定字节
落在何处;调用方只处理带类型的保存/加载。
public interface IPersister
{
bool Save<TOriginal>(TOriginal data, string destination, bool suppressErrors = false);
bool Load<TOriginal>(out TOriginal data, string origin, bool suppressErrors = false);
}
Save<TOriginal>(TOriginal data, string destination, bool suppressErrors = false)
将 data 序列化到 destination。
| 参数 | 类型 | 说明 |
|---|---|---|
data | TOriginal | 要持久化的对象 |
destination | string | 写入位置 |
suppressErrors | bool | 不记录错误——对资源缺失时仍能工作的系统(例如首次启动时读取不存在配置的配置管理器)有用 |
返回: bool——成功时为 true。
Load<TOriginal>(out TOriginal data, string origin, bool suppressErrors = false)
从 origin 反序列化到 data。
| 参数 | 类型 | 说明 |
|---|---|---|
data | out TOriginal | 接 收加载的对象 |
origin | string | 读取位置 |
suppressErrors | bool | 当资源可能合法缺失时不记录错误 |
返回: bool——成功时为 true(缺失的文件返回 false,而非抛出异常)。
ISceneManager
Namespace: OpenMon.Foundation.SceneManagement
包装 Unity 的 SceneManager,增加已加载场景追踪、可用性校验与事件广播。场景通过 SceneReference
或名称寻址。
public interface ISceneManager
{
List<string> LoadedScenes { get; }
string[] SceneNames { get; }
bool IsSceneAvailable(SceneReference scene);
bool IsSceneAvailable(string scene);
void LoadScene(SceneReference sceneReference, Action<float> progressCallback,
Action<bool> callback, LoadSceneMode mode = LoadSceneMode.Additive);
void LoadScene(string sceneName, Action<float> progressCallback,
Action<bool> callback, LoadSceneMode mode = LoadSceneMode.Additive);
void UnloadScene(SceneReference sceneReference, Action<float> progressCallback, Action<bool> callback);
void UnloadScene(string sceneName, Action<float> progressCallback, Action<bool> callback);
Scene GetActiveScene();
string GetActiveSceneName();
void SetActiveScene(SceneReference scene);
void SetActiveScene(string sceneName);
void MoveObjectToActiveScene(GameObject gameObject);
void MoveObjectToScene(GameObject gameObject, SceneReference scene);
void MoveObjectToScene(GameObject gameObject, string scene);
}
LoadedScenes
当前所有已加载场景的名称。
类型: List<string>(只读)
SceneNames
所有已知场景名称——Build Settings 与 addressable 两者皆包含。
类型: string[](只读)
IsSceneAvailable(SceneReference scene)
场景是否确实可加载(其资产是否存在)。有一个接受场景名称的重载。
返回: bool。
LoadScene(SceneReference sceneReference, Action<float> progressCallback, Action<bool> callback, LoadSceneMode mode = LoadSceneMode.Additive)
加载场景,通过 progressCallback 报告进度,通过 callback 报告成功。默认为 Additive,以便启动/
持久场景保持加载。存在按名称的重载。
UnloadScene(SceneReference sceneReference, Action<float> progressCallback, Action<bool> callback)
卸载场景,报告进度与成功。存在按名称的重载。
GetActiveScene() / GetActiveSceneName() / SetActiveScene(...)
读取或设置 Unity 的活动场景(新对象实例化到的场景)。
MoveObjectToActiveScene(GameObject gameObject) / MoveObjectToScene(...)
将一个 GameObject 移动到活动场景或指定场景——将池化/持久对象交给应拥有它的场景的标准方式。
ILocalizer
Namespace: OpenMon.Foundation.Localization
本地化服务。文本按键寻址;valueModifiers 替换已解析字符串中的 {0}、{1} … 占位符。索引器是
单个键的便捷路径;GetText / GetTexts 重载增加语言选择与批处理。
public interface ILocalizer
{
string this[string key, bool modifiersAreLocalizableKeys = true, params string[] valueModifiers] { get; }
string GetText(string key, bool modifiersAreLocalizableKeys = true, params string[] valueModifiers);
string GetText(string key, string language, bool modifiersAreLocalizableKeys = true, params string[] valueModifiers);
string GetText(string key, int languageIndex, bool modifiersAreLocalizableKeys = true, params string[] valueModifiers);
List<string> GetTexts(List<string> keys);
List<string> GetTexts(List<string> keys, string language);
string GetCurrentLanguage();
int GetCurrentLanguageIndex();
int GetLanguageIndex(string language);
List<string> GetAllLanguageIds();
void SetLanguage(string language);
void SetLanguage(int language);
void SubscribeToLanguageChange(Action<string> callback);
void SubscribeToLanguageChange(Action callback);
void UnsubscribeFromLanguageChange(Action<string> callback);
void UnsubscribeFromLanguageChange(Action callback);
void LoadNewLanguageValues(List<ScriptableLanguage> newLanguages);
void ReDownloadLanguagesFromGoogleSheet();
}
this[string key, bool modifiersAreLocalizableKeys = true, params string[] valueModifiers]
以当前语言返回 key 的本地化字符串的索引器。valueModifiers 替换 {number} 占位符;当
modifiersAreLocalizableKeys 为 true 时,修饰符本身也被当作键并先行本地化。
返回: string。
GetText(string key, bool modifiersAreLocalizableKeys = true, params string[] valueModifiers)
索引器的方法形式。重载增加目标 language(按 id 或索引),以便无论当前语言如何都从特定语言取值。
返回: string。
GetTexts(List<string> keys)
一次性批量解析多个键。重载增加目标语言。
返回: List<string>。
GetCurrentLanguage() / GetCurrentLanguageIndex() / GetAllLanguageIds()
查询活动语言(键或索引),并枚举所有可用语言 id。
SetLanguage(string language) / SetLanguage(int language)
按 id 或索引切换活动语言。触发语言变更事件。
SubscribeToLanguageChange / UnsubscribeFromLanguageChange
注册/注销语言变更通知(带或不带新语言 id)。注销时使用同一委托实例。
依赖注入辅助类
Namespace: OpenMon.Foundation.DependencyInjection
引擎通过小型 Zenject 安装器绑定每个共享资产。当你让数据资产可注入时,继承其中之一。
LazySingletonScriptableInstaller<T>
一个 ScriptableObjectInstaller,将检视器中指定的 ScriptableObject 绑定为类型 T 的惰性单例。
public class LazySingletonScriptableInstaller<T> : ScriptableObjectInstaller
where T : ScriptableObject
{
[SerializeField] protected T Reference;
public override void InstallBindings()
{
Container.QueueForInject(Reference);
Container.Bind<T>().FromInstance(Reference).AsSingle().Lazy();
}
}
QueueForInject 是必需的Container.QueueForInject(Reference) 并非可选。ScriptableObject 不会被 Zenject 自动注入——
没有此调用,资产上任何 [Inject] 成员都会保持 null。随后 .AsSingle().Lazy() 绑定会共享一个
实例,并将解析推迟到首次请求 T 时。
要让你自己的数据资产可注入,用具体的 T 继承:
using OpenMon.Foundation.DependencyInjection;
using UnityEngine;
[CreateAssetMenu(menuName = "MyGame/MyConfig")]
public class MyConfig : ScriptableObject { public int Difficulty; }
public class MyConfigInstaller : LazySingletonScriptableInstaller<MyConfig> { }
同级的 LazySingletonMonoInstaller<T> 对场景 MonoBehaviour 单例做同样的事。
AssetManagementUtils(仅编辑器)
Namespace: OpenMon.Foundation.Editor.Utils
用于批量加载资产的编辑器辅助类。位于 Runtime 程序集,但整个主体被 UNITY_EDITOR 门控,因此永不
随玩家构建发布。
public static class AssetManagementUtils
{
public static void CreateFolderIfDoesNotExist(string path);
public static List<T> FindAssetsByType<T>() where T : Object;
}
FindAssetsByType<T>()
加载项目中类型为 T 的所有资产。
朴素的 AssetDatabase.FindAssets("t:BaseType") 对抽象基类型返回空——Unity 将资产存储为具体
子类。当 T 为抽象时,FindAssetsByType<T> 回退为扫描所有已加载程序集中的每个具体子类。若没有该
回退,加载例如抽象 Move 基类会得到空列表,而像 MonsterDatabaseInstance.LoadAllMoves() 这样的
调用方会在更新时用空内容覆盖数据库的招式列表——抹掉导入游戏与演示游戏中的所有招式。若你编写类似的
批量加载器,请复用 此辅助方法,而非直接调用 FindAssets。
返回: List<T>——匹配的资产,若无则为空列表。
用法示例
using OpenMon.Foundation.Localization;
using OpenMon.Foundation.SceneManagement;
using Zenject;
public class TitleScreen : MonoBehaviour
{
[Inject] private ILocalizer localizer;
[Inject] private ISceneManager sceneManager;
private void Start()
{
// 带占位符替换的本地化文本。
Debug.Log(localizer["TitleScreen/Welcome", true, "Player"]);
Debug.Log($"Language: {localizer.GetCurrentLanguage()}");
// 加性地加载第一张地图,并记录进度。
sceneManager.LoadScene(
"Overworld",
progress => Debug.Log($"Loading: {progress:P0}"),
success => Debug.Log(success ? "Loaded" : "Failed"));
}
}