アクタのライフサイクル

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

このドキュメントでは、アクタのライフサイクルの概要について説明しています。これには、以下の内容が含まれます。

  • アクタがレベル内にインスタンス化またはスポーンされる方法 (アクタの初期化方法を含む)。

  • アクタが PendingKill としてマークされてから、ガーベジ コレクションによって削除または破棄される方法。

  • 以下のフロー チャートは、アクタのインスタンス化方法の主要なパスを示しています。アクタの作成方法に関係なく、破棄は同じパスをたどります。

ライフサイクルの詳細

ActorLifeCycle1.png

ディスクからロードする

このディスクからロードするパスは、レベルに配置済みのすべてのアクタがたどります。たとえば、UEngine::LoadMap が発生したときや、レベル ストリーミング によって UWorld::AddToWorld が呼び出されたときなどです。

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

  2. シリアル化されたアクタが、ディスクからのロード完了後に PostLoad を呼び出します。カスタム仕様のバージョン管理や修正の動作はここで実装する必要があります。PostLoad は AActor::PostActorCreated に対して相互排他的です。

  3. ワールドが UAISystemBase::InitializeActorsForPlay を呼び出し、アクタのゲームプレイ開始を準備します。

  4. 初期化されていないアクタを対象とし、シームレスな移行の引き継ぎのため、レベルが ULevel::RouteActorInitialize を呼び出します。

    1.AActor::PreInitializeComponents は、アクタのコンポーネントに InitializeComponent が呼び出される前に呼び出されます。 1.UActorComponent::InitializeComponent は、アクタに定義した各コンポーネントを作成するヘルパー関数です。 1.AActor::PostInitializeComponents は、アクタのコンポーネントが初期化された後に呼び出されます。

  5. AActor::BeginPlay は、レベルが開始すると呼び出されます。

Play in Editor

Play in Editor パスでは、アクタはディスクからロードされるのではなく、エディタからコピーされます。続いて、ディスクからロードするパスで説明したのと同様のフローでコピーされたアクタが初期化されます。

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

  2. UObject::PostDuplicate が呼び出されます。

  3. UAISystemBase::InitializeActorsForPlay

  4. ULevel::RouteActorInitialize は初期化されていないアクタを対象とし、シームレスな移行の引き継ぎに対応します。

    1.AActor::PreInitializeComponents は、アクタのコンポーネントに InitializeComponent が呼び出される前に呼び出されます。 1.UActorComponent::InitializeComponent は、アクタに定義した各コンポーネントを作成するヘルパー関数です。 1.AActor::PostInitializeComponents は、アクタのコンポーネントが初期化された後に呼び出されます。

  5. AActor::BeginPlay は、レベルが開始すると呼び出されます。

スポーン中

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

  1. UWorld::SpawnActor が呼び出されます。

  2. アクタがワールド内にスポーンされた後で AActor::PostSpawnInitialize が呼び出されます。

  3. AActor::PostActorCreated が、スポーン済みのアクタに対し、その作成後に呼び出されます。コンストラクタの実装動作はここで行います。PostActorCreated は、PostLoad に対して相互排他的です。

  4. AActor::ExecuteConstruction

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

  6. AActor::PostActorConstruction

    1.AActor::PreInitializeComponents は、アクタのコンポーネントに InitializeComponent が呼び出される前に呼び出されます。 1.UActorComponent::InitializeComponent は、アクタに定義した各コンポーネントを作成するヘルパー関数です。 1.AActor::PostInitializeComponents は、アクタのコンポーネントが初期化された後に呼び出されます。

  7. UWorld::OnActorSpawned は、UWorld でのブロードキャストです。

  8. AActor::BeginPlay が呼び出されます。

ディファード スポーン

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

  1. UWorld::SpawnActorDeferred は、プロシージャルなアクタをスポーンすることを目的としており、ブループリント コンストラクション スクリプトの前の追加設定を許可します。

  2. SpawnActor のすべてが発生しますが、AActor::PostActorCreated の後に以下が発生します。

    1.有効だが不完全なアクタのインスタンスを使って、さまざまな初期化関数の設定および呼び出しを行います。 1.AActor::FinishSpawning がアクタを確定するために呼び出されます。スポーン アクタの並びにある AActor::ExecuteConstruction でピックアップします。

アクタのライフサイクルの終了

アクタは複数の方法で破棄できますが、ワールドから削除される方法は同じ方法に従います。ゲームプレイ中に、以下の関数を呼び出すことができます。ただし、多くのアクタは実際にはプレイ中に破棄されないため、これらは完全に任意です (「ガーベジ コレクション」を参照)。

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

  • AActor::EndPlayアクタの存続期間が終了することを保証するために複数の場所で呼び出されます。プレイ中に Destroy がこのメソッドを呼び出し、アクタを含むストリーミング レベルがアンロード済みの場合はレベルが移行します。

  • EndPlay は、次によって呼び出されます。

    • Destroy への明示的な呼び出し。

    • Play in Editor の終了時。

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

    • アクタを含むストリーミング レベルがアンロードされている。

    • アクタの存続期間が終了した。

    • アプリケーションのシャットダウン (すべてのアクタが破棄された)。

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

アクタは、EndPlay の呼び出し時に必ずしも破棄しなければならないわけではありません。たとえば、s.ForceGCAfterLevelStreamedOutfalse の場合に、サブレベルがすぐにリロードされてからアクタの EndPlay が呼び出されても、アクタは「復活」し、デフォルトに再初期化されていないローカル変数とともに、以前に存在していたのとまったく同じものになる場合があります

  • AActor::OnDestroyed - Destroy に対するレガシー応答です。レベル移行や別のゲーム クリーンアップ関数によって呼び出されるため、ここにあるものすべてを EndPlay へ移動することをお勧めします。

ガーベジ コレクション

オブジェクトが破棄の対象としてマークされてからしばらくすると、ガーベジ コレクションによってそのオブジェクトはメモリから削除され、オブジェクトが使用していた全リソースが解放されます。

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

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

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

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

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

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

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

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

AdvancedGC.png

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

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