エンジンサービス
エンジン機能のほとんどは、エンジンサービスを介して実装されます。 エンジンサービスは IEngineService
インターフェースの実装であり、naninovelスクリプトの実行、アクターの管理、ゲームのセーブロードなど、特定のジョブを処理します。
エンジンシステムとやり取りする場合は、エンジンサービスを使用することをお勧めします。エンジンサービスへの参照は、静的メソッド Engine.GetService<TService>()
で取得できます。ここで TService
は、参照するサービスのタイプ(インターフェース)です。 たとえば、 IScriptPlayer
サービスを取得するには:
var player = Engine.GetService<IScriptPlayer>();
player.Stop();
以下のサービスが利用可能です:
サービスインターフェース | 説明 |
---|---|
IBackgroundManager | 背景 アクターの管理 |
ICharacterManager | キャラクター アクターの管理 |
IChoiceHandlerManager | 選択肢ハンドラー アクターの管理 |
ITextPrinterManager | テキストプリンター アクターの管理 |
IAudioManager | オーディオ: SFX、 BGM、 ボイスの管理 |
IInputManager | ユーザー 入力処理の管理 |
ILocalizationManager | ローカライズ アクティビティの管理 |
ITextManager | テキスト管理 機能を制御 |
IMoviePlayer | ムービー 再生を制御 |
IScriptManager | Naninovel スクリプト リソースの管理 |
IScriptPlayer | Naninovel スクリプト 実行を制御 |
ICameraManager | シーンのレンダリングに必要なカメラやその他のシステムを管理 |
IResourceProviderManager | IResourceProvider オブジェクトを管理 |
IStateManager | IEngineService 関連の永続的なデータの逆シリアル化を処理。 セーブロードシステム ゲームステートにAPIを提供。 |
IUIManager | IManagedUI オブジェクトを管理し、カスタムUI 機能を制御 |
ICustomVariableManager | カスタム変数 へのアクセスと編集を可能にする |
ISpawnManager | @spawn コマンドで生成されたオブジェクトを管理 |
IUnlockableManager | 収集アイテム (CGやムービーギャラリー, tipsなど) を管理 |
サービスの組み込み実装は、 Naninovel/Runtime
に格納されているランタイムソースコードにあります。
カスタムサービスの追加
新しいカスタムエンジンサービスを追加するには、IEngineService
インターフェースを実装し、実装クラスに InitializeAtRuntime
属性を追加します。実装のインスタンスはエンジンの初期化中に自動的に作成され、Engine.GetService<TService>()
APIを介して利用できるようになります。
InitializeAtRuntime
属性の InitializationPriority
引数を使用して、他のサービスの前後にカスタムサービスを強制的に初期化できます。値を小さくすると、初期化キュー内の他のサービスの前にプッシュされます。逆も同様です。
自動的にインスタンス化するには、サービス実装に互換性のあるコンストラクター(またはデフォルトのコンストラクター)が必要です。以下の引数(任意の順序)を使用できます:
- 任意の数の他のサービス (
IEngineService
-派生) - 任意の数の構成オブジェクト (
Configuration
-派生) - Unityの "MonoBehavior" プロキシーオブジェクト (
IEngineBehaviour
-派生)
コンストラクタで他のサービスを使用するのは安全ではないので、注意してください。代わりに、 InitializeServiceAsync
メソッドで他のサービスを使用する必要がある初期化アクティビティを実行します。サービスにアクセスするときに必要なサービスが確実に初期化されるようにするには、それらをサービスコンストラクターにリストします(初期化キューは、コンストラクターの引数に基づいてトポロジ的にソートされます)。
カスタムサービスに永続的なステートがあり、他のエンジンサービスで非/シリアル化したい場合は、 IStatefulService<TState>
インターフェイスを実装します。ここで、TState
は、GameStateMap
、GlobalStateMap
、または SettingsStateMap
です。これはステートをゲームセッション固有のもの、グローバルステートまたは、設定で保存するかによって決まります。必要に応じて、1つのサービスに3つすべてのインターフェースを実装することができます。さまざまなタイプのエンジン状態の詳細については、ステート管理ガイドを参照してください。
以下は、いくつかの使用上の注意を伴うカスタムエンジンサービス実装の例です:
using Naninovel;
using UniRx.Async;
using UnityEngine;
[InitializeAtRuntime]
public class CustomService : IEngineService
{
private readonly InputManager inputManager;
private readonly ScriptPlayer scriptPlayer;
public CustomService (InputManager inputManager, ScriptPlayer scriptPlayer)
{
// サービスはここではまだ初期化されていない可能性があるため、
// 使用しないでください。
this.inputManager = inputManager;
this.scriptPlayer = scriptPlayer;
}
public UniTask InitializeServiceAsync ()
{
// ここでサービスを初期化します。
// これで、コンストラクターでリクエストされたサービスを使用しても安全です。
Debug.Log(inputManager.ProcessInput);
Debug.Log(scriptPlayer.PlayedScript);
return UniTask.CompletedTask;
}
public void ResetService ()
{
// ここでサービスステートをリセットします。
}
public void DestroyService ()
{
// サービスを停止し、使用されているリソースをここで解放します。
}
}
前述のサービスの場合、次の方法でエンジンAPIを介して取得できます:
var customService = Engine.GetService<CustomService>();
EXAMPLE
アイテムのリソースとインベントリUIの構成を管理するカスタムエンジンサービスを追加する別の例は、GitHubのインベントリサンプルプロジェクト にあります。
具体的には、カスタムエンジンサービスは InventoryManager.cs ランタイムスクリプトを介して実装されます。
組み込みサービスの上書き
すべての組み込みサービスは、エンジンのソースコード内のインターフェイスを介して参照されるため、カスタム実装で入れ替えることができます。
カスタムサービスは上記と同じ方法で追加しますが、IEngineService
の代わりに具象エンジンインターフェースを実装し、InitializeAtRuntime
属性で上書きするタイプ(インターフェースではなく実装タイプ)を指定します。すると、組み込みサービスの代わりにカスタム実装が初期化されます。
以下は、ダミーの IInputManager
実装の例です。これは何もしませんが、いずれかのメソッドが呼び出されるとログに記録します。
using Naninovel;
using Naninovel.UI;
using UniRx.Async;
using UnityEngine;
[InitializeAtRuntime(@override: typeof(InputManager))]
public class CustomInputManager : IInputManager
{
public InputConfiguration Configuration { get; }
public bool ProcessInput { get; set; }
public CustomInputManager (InputConfiguration config)
{
Configuration = config;
}
public UniTask InitializeServiceAsync ()
{
Debug.Log("CustomInputManager::InitializeServiceAsync()");
return UniTask.CompletedTask;
}
public void ResetService ()
{
Debug.Log("CustomInputManager::ResetService()");
}
public void DestroyService ()
{
Debug.Log("CustomInputManager::DestroyService()");
}
public IInputSampler GetSampler (string bindingName)
{
Debug.Log($"CustomInputManager::GetSampler({bindingName})");
return default;
}
public void AddBlockingUI (IManagedUI ui, params string[] allowedSamplers)
{
Debug.Log($"CustomInputManager::AddBlockingUI({ui.GetType().Name})");
}
public void RemoveBlockingUI (IManagedUI ui)
{
Debug.Log($"CustomInputManager::RemoveBlockingUI({ui.GetType().Name})");
}
}
これで、Engine.GetService<IInputManager>()
から入力マネージャーが要求されると、組み込みの Naninovel.InputManager
ではなく、カスタム実装が提供されます。