UE4: C++er 視点での実行中の AActor への USceneComponent の動的なオブジェクトの実行中の生成、レジスター、アタッチ、デタッチ、アンレジスター、破棄の方法
状況 (½) おさらい編: AActor::AActor
(アクターのコンストラクター) で生成する場合
// .h
UHogeComponent* HogeComponent;
// .cpp AActor::AActor() { RootComponent = CreateDefaultSubobject< USceneComponent >( TEXT( "RootComponent" ) ); HogeComponent = CreateDefaultSubobject< UHogeComponent >( TEXT( "Hoge" ) ); HogeComponent->SetupAttachment( RootComponent ); }
以上のように ctor で"デフォルト"のサブオブジェクトとして生成する場合には CreateDefaultSubobject
を使う。
Note: コンポーネント間のアタッチメントは SetupAttachment
を使うのがナウい方式。やや古い参考文献を見ると [[deprecated]]
な API を使っている事があるのでコンパイラーの warning を見てモダン化する。
状況 (2/2) 本編: 実行中の任意のタイミングで生成する場合
// .h UHogeComponent* HogeComponent; void Fuga(); void Piyo();
// .cpp AActor::AActor() { // 比較用: ctor では CreateDefaultSubobject を使った。 RootComponent = CreateDefaultSubobject< USceneComponent >( TEXT( "RootComponent" ) ); } // 実行中の任意のタイミングでコンポーネントを生成 AActor::Fuga() { // 実行中の任意のタイミングで生成する場合は NewObject を使う。 // (ここでは AActor のデフォルトではないオブジェクト生成なので CreateDefaultSubobject は使えない事に注意) HogeComponent = NewObject< UHogeComponent >( this ); // NewObject で生成したオブジェクトは RegisterComponent が必要。 HogeComponent->RegisterComponent(); // ctor 以外でのコンポーネントのアタッチメント(取り付け)も SetupAttachemnt ではなく AttachToComponent を使う // ( SetupAttachment を使っても 4.16 時点では大量の警告とエラーを垂れ流しつつ一応は動作するのでうっかり使わないよう注意) HogeComponent->AttachToComponent( RootComponent, { EAttachmentRule::SnapToTarget, true } ); } // 実行中の任意のタイミングでコンポーネントを破棄 AActor::Piyo() { // RootComponent への Attachement (取り付け)を Detach (解除)する HogeComponent->DetachFromComponent( { EDetachmentRule::KeepRelative, true } ); // RegisterComponent によるコンポーネントの登録を UnregisterComponent で解除する HogeComponent->UnregisterComponent(); // コンポーネントオブジェクトの破棄をGCへ明示する // (ここで突然 DestroyComponent を呼び出すコードを書くとアクセス違反で死ぬことになるので注意) HogeComponent->ConditionalBeginDestroy(); // "立つ鳥跡を濁さず" HogeComponent = nullptr; }
実行中の AActor へ任意のタイミングで USceneComponent (というか実際にはその派生コンポーネントなど)を生成したり、付け足したり、消したり。公式の C++er 向けチュートリアルでも軽く触れるような ctor での生成とは違うポイントがいくつもあるので少し手間取った@w@
参考
- Unreal Engine | UObject インスタンスの作成
- What is the correct way to create and add components at runtime ?
- Explicitely Delete a UObject - UE4 AnswerHub
- その他としてコンパイラーの deprecated 警告、 Debug/Development ビルドの実行中の Warning, Error レベルのログなど。
事後修正
- 2017-06-19T22:20+09:00: 記事中のソース例で
AttachToComponent
をモダンなAPIとしてコードすべきところがAttachTo
になっていて[[deprecated]]
警告を受ける実装を示していたので修正しました。 - 2017-06-21T15:17+09:00: 記事中のソース例で
NewObject
の引数が誤ってTEXT( "Hoge" )
となっていたところをthis
に変更。