アクタのライフサイクル

アクタがロードまたはスポーンされて最終的に消滅するまでのライフサイクルで実際に何が起こるかを説明します。

Choose your operating system:

Windows

macOS

Linux

このページは アクタ のライフサイクルの概要です。アクタがレベルでインスタンス化 ( スポーン ) され、その後どのように除去 ( 破壊 ) されるかを説明します。

以下のフローグラフは、アクタをインスタンス化する 3 つの主要なパスを表しています。アクタの作成方法に関係なく、破壊は同じパスをたどります。

ライフサイクルの詳細

ActorLifeCycle1.png

ディスクからロードする

このパスは、レベルに配置済みのすべてのアクタがたどります。例えば、LoadMap が発生した時、または AddToWorld (ストリーミングまたはサブレベルから) が呼ばれた時などです。

  1. パッケージ / レベルに配置するアクタはディスクからロードします。

  2. PostLoad - ディスクからロード後、シリアル化されたアクタによって呼び出されます。カスタム仕様のバージョン体系や修正のビヘイビアはここに移動します。PostLoad は PostActorCreated と相互排他的です。

  3. InitializeActorsForPlay

  4. RouteActorInitialize はすべての初期化されていないアクタが対象です (シームレスな移行をカバー)。

    1. PreInitializeComponents - アクタのコンポーネントに InitializeComponent が呼ばれる前に呼ばれます。

    2. InitializeComponent - アクタに定義した各コンポーネントを作成するヘルパー関数です。

    3. PostInitializeComponents - アクタのコンポーネントが初期化された後に呼ばれます。

  5. BeginPlay - レベルが開始すると呼ばれます。

Play in Editor

Play in Editor パスは Load from Disk (ディスクからロード) とほぼ同じですが、アクタがディスクからロードされることは決してありません。アクタはエディタからコピーされます。

  1. エディタのアクタは新しいワールドで複製されます。

  2. PostDuplicate が呼ばれます。

  3. InitializeActorsForPlay

  4. RouteActorInitialize はすべての初期化されていないアクタが対象です (シームレスな移行をカバー)。

    1. PreInitializeComponents - アクタのコンポーネントに InitializeComponent が呼ばれる前に呼ばれます。

    2. InitializeComponent - アクタに定義した各コンポーネントを作成するヘルパー関数です。

    3. PostInitializeComponents - アクタのコンポーネントが初期化された後に呼ばれます。

  5. BeginPlay - レベルが開始すると呼ばれます。

Spawning

アクタをスポーン (インスタンス化) する場合、このパスをたどります。

  1. SpawnActor が呼ばれます。

  2. PostSpawnInitialize

  3. PostActorCreated - アクタ作成後にスポーンされるアクタに呼ばれます。ビヘイビアなどのコンストラクタはここに移動します。PostActorCreated は PostLoad と互いに排他的です。

  4. ExecuteConstruction :

    • OnConstruction - アクタの構築です。ここでブループリントのアクタのコンポーネントが作成されて、ブループリントの変数が初期化されます。

  5. PostActorConstruction :

    1. PreInitializeComponents - アクタのコンポーネントに InitializeComponent が呼ばれる前に呼ばれます。

    2. InitializeComponent - アクタに定義した各コンポーネントを作成するヘルパー関数です。

    3. PostInitializeComponents - アクタのコンポーネントが初期化された後に呼ばれます。

  6. OnActorSpawned は UWorld でブロードキャストします。

  7. BeginPlay が呼ばれます。

ディファード スポーン

アクタは、いずれかのプロパティが "Expose on Spawn" に設定されていると、ディファード スポーン (スポーンを先送り) を行うことができます。。

  1. SpawnActorDeferred - プロシージャルなアクタをスポーンする設計です。ブループリント コンストラクション スクリプトの前に追加設定を有効にします。

  2. SpawnActor のすべてが起こりますが、PostActorCreated の後に以下が起こります。

    1. 有効だが不完全なアクタのインスタンスを使って様々な初期化関数のセットアップ / 呼び出しをします。

    2. FinishSpawningActor - アクタを確定するために呼ばれます。スポーン アクタの並びにある ExecuteConstruction でピックアップします。

ライフの最後に到達する

アクタは様々な方法で破壊可能ですが、その消滅の仕方は常に同じです。

ゲームプレイ中

ほとんどのアクタはゲームプレイ中に実際に消滅しないので、これは完全に任意です。

Destroy - アクタを取り除こうとするたびにゲームによって手動で呼ばれますが、ゲームプレイはまだ続いています。アクタにはキル保留とマーク付けされ、レベルの一連のアクタから取り除かれます。

EndPlay - アクタのライフが終わりに近づくことを保証するために数か所で呼び出されます。プレイ中に Destroy や Level Transitions でこれを発行します。またアクタを含むストリーミングレベルがアンロードされた場合も発行します。EndPlay が呼び出されるすべての場所は以下の通りです。

  • Destroy の明示的な呼出し

  • Play in Editor を終了

  • レベル移行 (シームレスな移動またはマップのロード)

  • アクタを含むストリーミング レベルをアンロード

  • アクタのライフタイムの期限が終了

  • アプリケーションをシャットダウン (全アクタを破壊)

どのように発生するかには関係なく、次のガーベジ コレクション サイクルでメモリを解放するために、アクタは RF_PendingKill とマーク付けされます。また手動で保留中のキルをチェックせずに、よりクリーンな FWeakObjectPtr<AActor> の使用を考慮してください。

OnDestroy - Destroy に対するレガシー応答です。レベル移行や別のゲームクリーンアップ関数に呼ばれるため、ここにあるもの全てを EndPlay へ移動するといいでしょう。

ガーベジ コレクション

オブジェクトに破壊のマークが付けられた後にガーベジ コレクションがメモリからそれを取り除いて、オブジェクトが使用していた全リソースを解放します。

以下の関数はオブジェクトの破壊中に呼び出されます。

  1. BeginDestroy - オブジェクトがメモリを解放して別のマルチスレッドリソースを処理する機会です (例えばグラフィック スレッド プロキシ オブジェクト)。破壊されているものに関連するほとんどのゲームプレイ機能は、 EndPlay で以前に処理されているはずです。

  2. IsReadyForFinishDestroy - ガーベジ コレクション プロセスでは、この関数を呼び出して、オブジェクトがメモリを永続的に解放する準備が整っているかを判断します。 false を戻すことで、この関数は実際のオブジェクトの破壊を次のガーベジ コレクション パスまで遅らせます。

  3. FinishDestroy - 最後にオブジェクトは実際に破壊されます。これは内部データ構造を解放する別の機会です。これはメモリが解放される前の最後の呼び出しになります。

高度なガーベジ コレクション

Unreal Engine 4 のガーベジ コレクション プロセスでは、まとめて破壊されるオブジェクトのクラスターを構築します。クラスター化することでオブジェクトを個別に削除するのに比べて、ガーベジ コレクションに関連する合計時間と全体的なメモリ チャーン (確保開放の繰り返し) を減らします。オブジェクトがロードすると、サブオブジェクトを作成することがあります。オブジェクトがロードすると、サブオブジェクトを作成することがあります。オブジェクトとそのサブオブジェクトをガーベジ コレクタのためにひとつのクラスタにまとめることでクラスタが使うリソースの解放を遅延させて、すべてのリソースを一度に解放することができます。

ガーベジ コレクションはほとんどのオブジェクトに対して設定したり、修正する必要はありません。しかし、ガーベジ コレクターのクラスタリングの挙動を以下のように変更して効率を高めるように変更できる特殊なケースがあります。

  1. Clustering - クラスタリングをオフにします。 [Project Settings] [Garbage Collection] セクションで、 [Create Garbage Collector UObject Clusters] オプションを false に設定することができます。ほとんどのプロジェクトでは、これは効率性が低いガーベジ コレクションになります。そのため、これは性能テストの結果、確実に成果があるとわかった場合に限り行うことを推奨します。

  2. Cluster Merging - クラスタリングを true に設定すると、クラスタのマージを有効にするために、 [Merge GC Clusters] オプション ( Project Settings Garbage Collection セクション) を true に設定することができます。この挙動はデフォルトでオフになっており、すべてのプロジェクトに適しているわけではありません。オブジェクトのクラスタのビルド プロセス中にオブジェクトを調べて、オブジェクト内で他のオブジェクトへの参照が見つかることがあります。

    クラスタをマージしない場合 (デフォルトのビヘイビア)、こうした参照が見つかっても、ロード中のオブジェクトとそのサブオブジェクトが元のクラスタに残ります。

    クラスタのマージを使うと、ロード中のオブジェクトのクラスターと参照されるオブジェクトが結合されます。例えば、Particle System アセットは Material アセットを参照しますが、クラスタのマージがオフの場合、マテリアルとパーティクル システムはガーベジ コレクション目的で個別のクラスタに残ります。クラスタのマージがオンの状態で、パーティクル システムがマテリアルを参照することに起因して、パーティクル アセットのクラスタはマテリアルのクラスタとマージされます。

    このビヘイビアは多くの場合、例えば、オープンワールドのゲームなどコンテンツをストリーミングするゲームでは望ましくありません。より多くのクラスタがマージされて大きくなるにつれて、オブジェクトのグループの多様性が増すからです。クラスタのオブジェクトは個別に破壊されません。そのため、グループ内のすべてのオブジェクトが破壊に設定されるまで待機します。これが複数オブジェクトを持つ大きなクラスタになってメモリに存在し続けます。しかし、他のオブジェクトによって共有されない参照される大量のオブジェクトを持つアセットなどの特殊なケースでは、クラスタのマージを有効にし、コードでクラスタを手動で追加できるようにすることで、パフォーマンスを向上させることができます。これはサブオブジェクトのクリーンアップを統合し、ガーベジ コレクタが維持し、ゲーム中にチェックしなければならない個々のエントリ数と従属関係を減らすことによって実現します。

AdvancedGC.png

[Project Settings (プロジェクト設定)] メニュー内のガーベジコレクションのクラスタをマージするオプション

Unreal Engine のドキュメントを改善するために協力をお願いします!どのような改善を望んでいるかご意見をお聞かせください。
調査に参加する
閉じる