プログラミング サブシステム

Unreal Engine 4 のプログラミング サブシステムの概要です。

Windows
MacOS
Linux

Unreal Engine 4 (UE4) のサブシステムは、管理されたライフタイムを持つ自動的にインスタンス化されたクラスです。このクラスを利用すると、拡張ポイントを簡単に使用できるため、プログラマはエンジン クラスの変更または上書きするといった複雑な作業を回避しつつ、ブループリントや Python を公開できます。

現在サポートされているサブシステムのライフタイムは以下です。

サブシステム

継承元

Engine

UEngineSubsystem クラス

Editor

UEditorSubsystem クラス

GameInstance

UGameInstanceSubsystem クラス

LocalPlayer

ULocalPlayerSubsystem クラス

例えば、次の基本クラスから派生するクラスを作成する場合、

class UMyGamesSubsystem : public UGameInstanceSubsystem

結果は次のようになります。

  1. UGameInstance が作成された後、UMyGamesSubsystem というインスタンスも作成されます。

  2. UGameInstance が初期化されるとき、サブシステムで Initialize() が呼び出されます。

  3. UGameInstance が終了するとき、サブシステムで Deinitialize() が呼び出されます。

  4. この時点で、サブシステムへの参照は削除されます。サブシステムへの参照がなくなると、サブシステムはガベージ コレクションされます。

サブシステムを使用する理由

プログラミング サブシステムを使用する理由は、以下をはじめ、いくつかあります。

  • プログラミング時間が短縮される。

  • エンジン クラスのオーバーライド回避に役立つ。

  • ただでさえ入り組んだクラスにさらに API を追加しなくてすむ。

  • ユーザー フレンドリなタイプのノードを通じてブループリントにアクセスできる。

  • エディタ スクリプティングやテスト コードの記述のために Python スクリプトにアクセスできる。

  • コードベースのモジュール性と一貫性を実現する。

サブシステムは、プラグインを作成する際に特に役立ちます。プラグインを機能させるのに必要なコードに関する指示を用意する必要がないからです。ユーザーはプラグインをゲームに追加するだけでよく、デベロッパーはプラグインがインスタンス化され、初期化されるタイミングが正確にわかります。その結果、デベロッパーは API と UE4 で提供されている機能の使用方法に注力できます。

ブループリントでサブシステムにアクセスする

サブシステムは、コンテキストを理解し、キャストを必要としないスマート ノードによって、自動的にブループリントに公開されます。標準の UFUNCTION() マークアップとルールを使用して、ブループリントで使用可能な API を管理しています。

ブループリント グラフで右クリックしてコンテキスト メニューを表示し、「subsystems」を検索すると、以下の画像のような表示になります。主要なタイプそれぞれにカテゴリがあり、具体的なサブシステムそれぞれに個別のエントリがあります。
Subsystems_01.png

上記からノードを追加すると、次のような結果が得られます。
Subsystems_02.png

Python でサブシステムにアクセスする

Python を使用している場合、ビルトインのアクセサーを使用して、以下の例のようにサブシステムにアクセスできます。

my_engine_subsystem = unreal.get_engine_subsystem(unreal.MyEngineSubsystem)
my_editor_subsystem = unreal.get_editor_subsystem(unreal.MyEditorSubsystem)

Python は現在実験的な機能です。

サブシステムのライフタイムの詳細

Engine サブシステム

class UMyEngineSubsystem : public UEngineSubsystem { ... };

Engine サブシステムのモジュールがロードされると、サブシステムはモジュールの Startup() 関数から戻った後に Initialize() を実行します。

また、モジュールの Shutdown() 関数から戻った後に Deinitialize() を実行します。

UMyEngineSubsystem* MySubsystem = GEngine->GetEngineSubsystem<UMyEngineSubsystem>();

Editor サブシステム

class UMyEditorSubsystem : public UEditorSubsystem { ... };

Editor サブシステムのモジュールがロードされると、サブシステムはモジュールの Startup() 関数から戻った後に Initialize() を実行します。

また、モジュールの Shutdown() 関数から戻った後に Deinitialize() を実行します。

UMyEditorSubsystem* MySubsystem = GEditor->GetEditorSubsystem<UMyEditorSubsystem>();

GameInstance Subsystems

class UMyGameSubsystem : public UGameInstanceSubsystem { ... };

これらのサブシステムは、以下のように UGameInstance を通してアクセスされます。

UGameInstance* GameInstance = ...;
UMyGameSubsystem* MySubsystem = GameInstance->GetSubsystem<UMyGameSubsystem>();

LocalPlayer サブシステム

class UMyPlayerSubsystem : public ULocalPlayerSubsystem { ... };

これらのサブシステムは、以下のように ULocalPlayer を通してアクセスされます。

ULocalPlayer* LocalPlayer = ...;
UMyPlayerSubsystem * MySubsystem = LocalPlayer->GetSubsystem<UMyPlayerSubsystem>();

サブシステムの例

次の例では、収集したリソースの数を追跡する統計システムをゲームに追加します。

UGameInstance から派生させて UMyGamesGameInstance を作成した後、それに IncrementResourceStat() 関数を追加します。しかし、ゆくゆくは他の統計や、統計の集計、統計の保存/読み込み機能などを追加した方が良いでしょう。そのため、UMyGamesStatsSubsystem など、1 つのクラスにそのすべてを配置することにします。

再び UMyGamesGameInstance を作成して、UMyGamesStatsSubsystem 型のメンバーを追加します。その後、そこにアクセサーを追加して、Initialize 関数と Deinitialize 関数をフックします。しかし、これにはいくつかの問題があります。

  • UGameInstance のゲーム固有の派生物がない。

  • UMyGamesGameInstance は存在するが、既に大量の関数があり、そこにさらに追加するのは最適性に欠ける。

十分に複雑なゲームで UGameInstance から派生させるのが妥当な理由は多数あります。しかし、サブシステムがある場合、それを使う必要はありません。なんと言っても、サブシステムを使用すると、他の方法よりも必要なコーディングが少なくなります。

そのため、最終的に使用するコードを以下の例に示します。

UCLASS()
class UMyGamesStatsSubsystem : public UGameInstanceSubsystem
{
    GENERATED_BODY()
public:
    // Begin USubsystem
    virtual void Initialize(FSubsystemCollectionBase& Collection) override;
    virtual void Deinitialize() override;
    // End USubsystem

    void IncrementResourceStat();
private:
    // All my variables
};
タグ
Select Skin
Light
Dark

新しい Unreal Engine 4 ドキュメントサイトへようこそ!

あなたの声を私たちに伝えるフィードバックシステムを含め、様々な新機能について開発をおこなっています。まだ広く使える状態にはなっていないので、準備ができるまでは、ドキュメントフィードバックフォーラムで、このページについて、もしくは遭遇した問題について教えていただけると助かります。

新しいシステムが稼働した際にお知らせします。

フィードバックを送信