跳到主要内容

Foundation Services

OpenMon.Foundation 层是整个引擎所依托的共享框架:依赖注入、持久化、场景管理与本地化。这些接口 稳定、可通过 Zenject 注入,并可在你自己的系统中复用。本页记录三个服务接口,以及你最常继承的两个 DI 辅助类。

Foundation 与引擎无关

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。

参数类型说明
dataTOriginal要持久化的对象
destinationstring写入位置
suppressErrorsbool不记录错误——对资源缺失时仍能工作的系统(例如首次启动时读取不存在配置的配置管理器)有用

返回: bool——成功时为 true。

Load<TOriginal>(out TOriginal data, string origin, bool suppressErrors = false)​

从 origin 反序列化到 data。

参数类型说明
dataout TOriginal接收加载的对象
originstring读取位置
suppressErrorsbool当资源可能合法缺失时不记录错误

返回: 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"));
}
}