Language:
Page Info
Engine Version:
The translation of this page is out of date. Please see the English version for the latest version of the page.

コンポーネント

コンポーネント は、アクタ 内のサブオブジェクトとして使用するように設計された特殊な オブジェクト です。コンポーネントは、所有するアクタの特定の動作や機能を変更するために、 簡単に取り替えられる部分が必要な状況で一般的に使用されます。例えば、車の制御や動きは飛行機とは異なり、飛行機の制御や動きは船とは異なります。 しかし、これらはすべて他に共通点を持つ乗り物です。コンポーネントを使って制御や動きを処理することにより、 いずれかの特定タイプと同様の動作をする乗り物を簡単に作成できます。

一般的にサブオブジェクトのデフォルトの挙動とは逆に、アクタ内でサブオブジェクトとして作成されたコンポーネントはインスタンス化されます。 つまり、各アクタの特定クラスのインスタンスは、コンポーネントの独自の固有インスタンスを取得します。上述の乗り物の例で思い描くとわかりやすいでしょう。Car クラスは、車の車輪の表現にコンポーネントを使用する場合もあります。クラスのデフォルトプロパティにはサブオブジェクトとして 4 つの Wheel コンポーネントが作成され、 Wheels[] 配列へ割り当てられます。新規の Car インスタンスが作成されると、 Wheel コンポーネントの新しいインスタンスは前述の Car 専用に作成されます。これが該当しない場合、ワールドにある一台の Car が動くと、全ての Car の車輪が回転します。これは明らかに望まれる動作ではありません。デフォルトのコンポーネントのインスタンス化は、 アクタへ固有のサブオブジェクトを迅速に追加するプロセスを簡素化します。

コンポーネントをインスタンス化しないと、全てのコンポーネント変数は [インスタンス化][Instanced](Programming\UnrealArchitecture\Reference\Properties\Specifiers\Instanced) したプロパティ指定子を使用して宣言する必要があります。

Actor コンポーネント

ActorComponent は、様々なタイプのアクタに追加できる再利用可能なビヘイビアを定義するコンポーネントの基底クラスです。通常は、コリジョン ジオメトリやレンダリング メッシュの形式でジオメトリとアクタの関連付けに使用します。 アクタがワールドを移動する際の制御や、アクタに関係したサウンドの再生、 アクタに光や影をワールドへ放つ機能をもたらします。事実、ゲームをプレイ中にワールド内でプレイヤーが目にするものや相互作用するもの全ては、実際に何らかのタイプの Actorcomponent が作用したものです。 変形を持つ ActorComponent は SceneComponents であり、リンダリング可能な ActorComponent は PrimitiveComponents です。

コンポーネントの登録

ActorComponent を各フレームで更新してシーンへ反映させるには、コンポーネントをシーンへ 登録 しなくてはいけません。登録は UActorComponent::RegisterComponent() を呼んで実行します。

void UActorComponent::RegisterComponent()

この関数は、ActorComponent が所有アクタの Components[] 配列に格納されていること、シーンと関連付けること、 ActorComponent 用に レンダープロキシ物理ステート を作成することを確認するために、UActorComponent::RegisterComponentWithScene() を呼びます。

ActorComponent は、所有アクタがスポーンされると自動的に登録されます。 またサブオブジェクトとして作成され、アクタのデフォルトプロパティの Components[] 配列へ追加された場合も自動登録されます。再生中のどの時点においても UActorComponent::RegisterComponent() を呼ぶことによって登録することができます。 ただし、コンポーネントの登録は若干負荷がかかる操作なので、本当に必要な場合だけ実行してください。

イベントの登録

コンポーネントが登録されると以下のイベントが発行されます。

関数 説明
UActorComponent::OnRegister() 必要であれば、コンポーネントの登録時に追加の初期化を可能にするイベントです。
UActorComponent::CreateRenderState() コンポーネントのレンダリング ステートを初期化します。
UActorComponent::CreatePhysicsState() コンポーネントの物理ステートを初期化します。

コンポーネントの登録の取り消し

更新、シュミレーション、またはレンダリングを回避するために、ActorComponent の登録を取り消すこともできます。UActorComponent::UnregisterComponent() を呼び出すと、コンポーネントの登録の取り消しが実行されます。

void UActorComponent::UnregisterComponent()

イベントの登録の取り消し

コンポーネントの登録が取り消されると以下のイベントが発行されます。

関数 説明
UActorComponent::OnUnRegister() コンポーネントの登録を取り消す際に、必要に応じて追加の動作を可能にするイベントです。
UActorComponent::DestroyRenderState() コンポーネントのレンダリング ステートの初期化を解除します。
UActorComponent::DestroyPhysicsState() コンポーネントの物理ステートの初期化を解除します。

更新

ActorComponent は、TickComponent() 関数を用いて各フレームで更新することができます。これにより、コンポーネントは特定タイプやフレーム単位で実行が可能となります。例えば、 例えば、SkeletalMeshComponents はアニメーションとスケルタル コントローラーを更新する際に TickComponent() を使用します。 システムのエミッタの更新や処理するパーティクル イベントのチェックには ParticleSystemComponents を使用します。

コンポーネントを更新するためには、コンポーネントが登録され、ティックの設定 (bComponentNeverTicks=false)、またティック関数が設定されている必要があります。

レンダリング ステート

ActorComponent をレンダリングするには、レンダリング ステートを作成しなくてはいけません。ActorComponent のレンダリング ステートは、 レンダリング データの更新を必要とするコンポーネントに変更がもたらされたかどうかをエンジンへ伝達します。変更があった場合、レンダリング ステートはダーティとマークされます。そして現在のフレームの終了時に、全てのダーティ コンポーネントはレンダリング データを更新します。

物理ステート

物理エンジンを使用したシミュレーションは、ActorComponent に物理ステートを作成しなくてはいけません。レンダリング ステートとは異なり、変更があると直ちに更新がされる物理ステートは、 決してダーティとマークされることはありません。フレームの後ろのアーティファクトなどの問題を防ぐため大変重要です。

シーン コンポーネント

SceneComponent は、変換をともなう ActorComponent の拡張です。例えば、位置、回転、スケーリングなどです。変換の追加は SceneComponent もまた相互にアタッチすること を意味します。

アタッチメント

アンリアル・エンジン 4 の全てのアタッチメントはコンポーネント レベルで処理され、SceneComponent のみが相互にアタッチすることができます。SceneComponent には、 それ自体がアタッチするコンポーネントをポイントする AttachParent プロパティがあります。これは主に、Actor に複数のコンポーネントが含まれていて、その全てをアタッチするために使用します (アタッチすることが望ましい場合)。ただし、別のアクタに属するコンポーネントを指定し、 あるアクタのコンポーネントを別のアクタのコンポーネントにアタッチする場合にも使用できます。

つまり、実際にアタッチするコンポーネントであり、またアタッチされているアクタの SceneComponent はルート コンポーネントでなければならないので、 アクタをお互いにアタッチするためには、関連するそれぞれのアクタが最低 1 つの SceneComponent を格納しなくてはいけないということです。理由は明確です。各コンポーネントは 1 つの親しか持てないため、アタッチされたコンポーネントはアタッチしているアクタのルートコンポーネントでない場合、 コンポーネントとその子コンポーネントのみがアタッチされます。ルートコンポーネントはアタッチされず影響を受けないままです。 同様に Actor 全体はルートコンポーネントとその変換に依存するため、アタッチされず影響を受けないままです。

コンポーネントの変換

FTransform 構造は Translation ベクター、Rotation クォータニオン、Scale3D ベクターを格納します。各 SceneComponent は、独自の FTransform があります。 通常は内部使用のためで、ワールドに相対する位置、回転、そしてスケーリングを表現します。追加の RelativeLocation ベクター、RelativeRotation ローテータ、そして RelativeScale3D ベクターも使用します。 親コンポーネント、もしくはワールドに相対して機能します。これらはコンポーネントを変換、もしくはコンポーネントの変換設定をする際に一般的に使用します。

デフォルト設定で、RelativeLocationRelativeRotation、 そして RelativeScale3DAttachParent に対して相対的です。これらの値は bAbsoluteLocationbAbsoluteRotation、そして bAbsoluteScale プロパティを使用して強制的にワールドと相対的になります。いずれかの値を true に設定すると、対応するプロパティがワールドに相対的となる要因になります。

親に相対的な変換値を使用している時でさえ、以下のメソッドにワールドの絶対値を使用して、平行移動や回転を設定することができます。

関数 説明
SceneComponent::SetWorldLocation() ワールド空間で与えられた位置に配置するためこのコンポーネントに相対的な平行移動を設定します。
SceneComponent::SetWorldRotation() ワールド空間で与えられた位置に配置するためこのコンポーネントに相対的な回転を設定します。

プリミティブ コンポーネント

PrimitiveComponents はある種のジオメトリを格納または生成する SceneComponents で、通常はレンダリングされるかコリジョン データとして使用されます。さまざまなタイプのジオメトリに対していくつかのサブクラスがありますが、 最も一般的なのは CapsuleComponentStaticMeshComponent、そして SkeletalMeshComponent です。CapsuleComponents はコリジョン検知に使用するジオメトリを生成しますが、レンダリングはしません。 StaticMeshComponents と SkeletalMeshComponents はレンダリングするビルド済みのジオメトリを格納しますが、コリジョン検知にも使用されます。

シーン プロキシ

PrimitiveComponent の SceneProxy は、シーンデータをカプセル化する FPrimitiveSceneProxy インスタンスです。シーンデータは、ゲームスレッドに対しプリミティブを平行にレンダリングするためにミラーリングされています。 FPrimitiveSceneProxy のサブクラスは、各プリミティブタイプに対し作成され、そのタイプのプリミティブをレンダリングするために必要な特定のレンダリングデータを保持します。

プリミティブとレンダリング ジオメトリに関する詳細は、レンダリングシステムの概要 を参照してください。