Unreal Engine で使用する全てのゲームプレイ クラスは、クラス ヘッダ ファイル (.h
) とクラス ソース ファイル (.cpp
) で構成
されています。クラス ソース ファイルは、クラスに属する関数を 実装 することによってクラスの機能を定義するファイルである一方で、
クラス ヘッダ ファイルには変数や関数など、クラスの宣言とそのメンバーが
含まれています。
Unreal Engine のクラスには標準化した命名スキームがあり、クラスの最初の文字 (プレフィックス) を見ただけで、 瞬時にクラスの種類が判断できます。以下はゲームプレイ クラスのプレフィックスです。
プレフィックス | 意味 |
---|---|
A |
スポーン可能 なゲームプレイ オブジェクトの基底クラスからの拡張です。これらはアクタで、ワールド内へ直接スポーンすることができます。 |
U |
全ゲームプレイ オブジェクトの基底クラスからの拡張です。このクラスはワールド内へ直接インスタンス化することはできません。アクタに属さなければいけません。通常は コンポーネント のようなオブジェクトです。 |
クラスの追加
C++ クラス ウィザード は、新規クラスに必要なヘッダ ファイルとソース ファイルを設定し、それに応じてゲーム モジュールを更新します。 ヘッダ ファイルとソース ファイルには、 UCLASS() マクロのようなアンリアル エンジン固有のコードに加えて、クラス宣言とクラス コンストラクタを自動的にインクルードします。
クラスヘッダ
Unreal Engine のゲームプレイクラスにはそれぞれ、固有のクラス ヘッダ ファイルがあります。ファイルには、その中で定義されているクラスと一致する名前を付けなければなりません。
A
または U
のプレフィックスを差し引いて「.h
」ファイル拡張子を使用します。例えば AActor
クラスのクラス ヘッダ ファイルの名前は Actor.h
となります。
エピック ゲームズのコードはこうしたガイドラインに従いますが、現在のエンジンではクラス名とソースファイル名との間には正式な関係は存在しません。
ゲーム プレイ クラスのクラス ヘッダ ファイルは、クラス、変数、関数の宣言プロセスを単純化するために、特殊マクロと標準の C++ 記法を併用します。
各ゲームプレイ クラスのヘッダ ファイル最上部には、以下のようにクラス用に (自動) 生成されたヘッダ ファイルをインクルードしなくてはいけません。従って ClassName.h
の上には次の行が表示されます。
#include "ClassName.generated.h"
クラスの宣言
クラスの宣言はクラス名、継承元のクラス、継承した関数や変数があれば定義します。クラスの宣言では、クラス指定子 やメタデータ経由で望まれる 他のエンジンやエディタ固有の動作も定義します。
クラスの宣言の記法は以下の通りです。
UCLASS([specifier, specifier, ...], [meta(key=value, key=value, ...)])
class ClassName : public ParentName
{
GENERATED_BODY()
}
宣言は、クラスのための標準の C++ クラス宣言で構成されています。標準の宣言の上で、クラス指定子やメタデータなどの記述子が UCLASS マクロへ
渡されます。これらは宣言されているクラスに対して UClass
を作成するために使用され、エンジンの特別なクラス表現とみなされます。また、GENERATED_BODY()
マクロを
マクロはクラス本体の冒頭に配置しなくてはいけません。
クラス指定子
クラスを宣言するときに、エンジンやエディタのさまざまな側面でクラスがどのように動作するかを制御する クラス指定子 を宣言に追加することができます。
クラス指定子 | 効果 |
---|---|
Abstract |
Abstract 指定子によって、このクラスを「抽象基本クラス」として宣言し、このクラスのアクタがレベルに追加されないようにします。そのクラスだけでは意味をもたないクラスの場合は使用可能です。たとえば、ATriggerBase 基本クラスは抽象ですが、ATriggerBox サブクラスは抽象ではなく、レベルに配置可能です。 |
AdvancedClassDisplay |
AdvancedClassDisplay 指定子は、クラスのすべてのプロパティを、[Details (詳細)] パネル の詳細セクションでのみ見えるようにします。個々のプロパティでこれをオーバーライドするには、プロパティで SimpleDisplay 指定子を使います。 |
AutoCollapseCategories=(Category1, Category2, ...) |
AutoCollapseCategories 指定子は、親クラスの AutoExpandCategories 指定子のリストされているカテゴリの効果を無効にします。 |
AutoExpandCategories=(Category1, Category2, ...) |
このクラスのオブジェクトに対し、Unreal Editor のプロパティ ウィンドウで自動的に展開するカテゴリを 1 つ以上指定します。カテゴリなしで宣言された変数を自動展開するには、変数を宣言するクラス名を使用します。 |
Blueprintable |
ブループリントの作成にこのクラスを許容される基本クラスとして公開します。他のものを継承していない場合、デフォルトは NotBlueprintable となります。この指定子はサブクラスで継承されます。 |
BlueprintType |
このクラスを、ブループリントの変数に使用できる型として公開します。 |
ClassGroup=GroupName |
Unreal Editor の アクタのブラウザ に グループ ビュー が有効な場合、指定された GroupName 内でクラスとこのクラスのサブクラスが含まれていることを示します。 |
CollapseCategories |
このクラスのプロパティは、Unreal Editor のプロパティ ウィンドウのカテゴリでグループ化すべきでないことを示します。この指定子は子クラスに反映されますが、DontCollapseCategories 指定子によってオーバーライドすることができます。 |
Config=ConfigName |
このクラスがコンフィギュレーション ファイル (.ini ) 内にデータを格納できることを示しています。config 指定子または globalconfig の指定子で宣言されているクラスのプロパティがあれば、指定子によって、こうしたプロパティを指定されたコンフィギュレーション ファイルに格納します。この指定子はすべての子クラスへ反映され、無効にすることはできませんが、子クラスは config 指定子を再宣言し、別の ConfigName を指定することによって config ファイルを変更することができます。一般的な ConfigName 値は、Engine、Editor、Input、および Game です。 |
Const |
このクラスの全プロパティと関数は const です。また、const としてエクスポートされます。この指定子はサブクラスで継承されます。 |
ConversionRoot |
ルートの変換は、サブクラスの変換を階層の上位にある最初のルート クラスの子クラスのみに制限します。 |
CustomConstructor |
コンストラクタ宣言の自動生成を防ぎます。 |
DefaultToInstanced |
このクラスの全インスタンスは「インスタンス化された」とみなされます。インスタンス化されたクラス (コンポーネント) は構成時に複製されます。この指定子はサブクラスで継承されます。 |
DependsOn=(ClassName1, ClassName2, ...) |
リストされているクラスはすべて、このクラスより前にコンパイルされます。クラス名は同じ (あるいは以前の) パッケージのクラスを指定しなければなりません。1 行の DependsOn 行をカンマで区切って使用したり、クラスごとに別の DependsOn 行を使用したりすることで、複数の依存クラスを指定することができます。コンパイラはクラス内のコンパイル済みのものしか認識しないため、これは他のクラスで宣言された構造体や列挙型変数をクラスで使う場合に重要となります。 |
Deprecated |
このクラスは非推奨とし、クラスのオブジェクトはシリアル化されたときに保存されません。この指定子はサブクラスで継承されます。 |
DontAutoCollapseCategories=(Category, Category, ...) |
親クラスから継承した指定カテゴリに対して、AutoCollapseCategories 指定子を無効にします。 |
DontCollapseCategories |
基本クラスから継承した CollapseCatogories 指定子を無効にします。 |
EditInlineNew |
このクラスのオブジェクトは、既存のアセットから参照されるのではなく、Unreal Editor のプロパティ ウィンドウから作成できることを示します。デフォルトの動作として、既存のオブジェクトのみの参照をプロパティ ウィンドウで割り当てることができます。この指定子はすべての子クラスに反映されますが、子クラスは NotEditInlineNew 指定子を使ってこの指定子をオーバーライドできます。 |
HideCategories=(Category1, Category2, ...) |
ユーザーから完全に非表示にする必要がある 1 つ以上のカテゴリを表示します。カテゴリなしで宣言されたプロパティを非表示にするには、変数を宣言するクラス名を使います。この指定子は子クラスに反映されます。 |
HideDropdown |
プロパティ ウィンドウのコンボ ボックスにこのクラスが表示されないようにします。 |
HideFunctions=(Category1, Category2, ...) |
指定されたカテゴリのすべての関数をユーザーから完全に非表示にします。 |
HideFunctions=FunctionName |
名前付きの関数をユーザーから完全に非表示にします。 |
Intrinsic |
クラスは直接 C++ で宣言され、Unreal Header Tool はボイラープレートを生成しないことを示します。新規のクラスにこの指定子を使用しないでください。 |
MinimalAPI |
他のモジュールで使用するために、クラスの型情報のみをエクスポートさせます。クラスをキャストすることができますが、クラスの関数を呼び出すことはできません (インライン メソッドは除く)。これにより、他のモジュールではアクセスできる関数のすべてを必要としないクラスの場合はすべてをエクスポートせずに済むため、コンパイル時間を短縮できます。 |
NoExport |
このクラスの宣言は、ヘッダ ジェネレータで自動生成された C++ ヘッダ ファイルに含まれてはいけないことを示します。C++ クラス宣言は、別のヘッダ ファイルで手動で定義されなければなりません。ネイティブ クラスのみ有効です。新規のクラスにこの指定子を使用しないでください。 |
NonTransient |
基本クラスから継承した Transient 指定子を無効にします。 |
NotBlueprintable |
このクラスはブループリントを作成するための許容可能な基本クラスではないことを指定します。これはデフォルトであり、サブクラスで継承されます。 |
NotPlaceable |
基本クラスから継承した Placeable 指定子を無効にします。このクラスのオブジェクトはエディタでレベル、UI シーン、ブループリントなどには配置できないことを示します。 |
PerObjectConfig |
このクラスのコンフィギュレーション情報はオブジェクトごとに保存されます。この場合、各オブジェクトは [ObjectName ClassName] の形式でオブジェクトにちなんで名付けられた .ini ファイルのセクションを持ちます。この指定子は子クラスに反映されます。 |
Placeable |
このクラスはエディタで作成可能であり、レベル、UI シーン、ブループリント (クラスのタイプにより異なります) で作成可能であることを示します。このフラグは子クラスに反映されますが、子クラスは NotPlaceable 指定子を使ってこのフラグをオーバーライドできます。 |
ShowCategories=(Category1, Category2, ...) |
指定カテゴリに対して、HideCategories 指定子 (基本クラスから継承) を無効にします。 |
ShowFunctions=(Category1, Category2, ...) |
プロパティ ビューアで設定したカテゴリ内のすべての関数を表示します。 |
ShowFunctions=FunctionName |
プロパティ ビューアに名前付きの関数を表示します。 |
Transient |
このクラスに属するオブジェクトがディスクに保存されることはありません。プレイヤーやウィンドウなど、本質的に非永続的な、一定のネイティブ クラスと併用する場合に役立ちます。この指定子は子クラスに反映されますが、NonTransient 指定子によってオーバーライドすることができます。 |
Within=OuterClassName |
このクラスのオブジェクトは OuterClassName オブジェクトのインスタンス外では存在できません。つまり、このクラスのオブジェクトの作成では、OuterClassName のインスタンスが Outer オブジェクトとして指定されていることが必要です。 |
メタデータ指定子
クラス、インターフェース、構造体、列挙型変数、列挙型変数の値、関数、プロパティを宣言するときに、メタデータ指定子 を宣言に追加して、エンジンやエディタのさまざまな側面でどのようにインタラクタするかを制御することができます。データ構造またはメンバーのそれぞれの型には、固有のメタデータ指定子のリストがあります。
メタデータはエディタのみに存在しています。メタデータにアクセスするゲーム ロジックを書かないでください。
クラスは以下のメタタグ指定子を使用することができます。
クラス メタタグ | 効果 |
---|---|
BlueprintSpawnableComponent |
存在する場合、コンポーネント クラスはブループリントによってスポーンできます。 |
BlueprintThreadSafe |
ブループリント関数ライブラリでのみ有効です。この指定子は、このクラスの関数をアニメーション ブループリントの非ゲーム スレッドで呼び出し可能としてマークします。 |
ChildCannotTick |
Actor クラスと Component クラスに使用されます。ネイティブ クラスがティックできない場合、bCanBlueprintsTickByDefault が true であっても、このアクタまたはコンポーネントに基づいてブループリントで生成されたクラスはティックできません。 |
ChildCanTick |
Actor クラスと Component クラスに使用されます。ネイティブ クラスがチェックできない場合、このアクタまたはコンポーネントに基づいてブループリントで生成されたクラスでは、bCanBlueprintsTickByDefault が false であったとしても bCanEverTick フラグがオーバーライドされる可能性があります。 |
DeprecatedNode |
behavior tree ノードで、クラスが非推奨であることを示し、コンパイル時に警告が表示されます。 |
DeprecationMessage="Message Text" |
このメタデータを持つ非推奨クラスには、コンパイル時にブループリント スクリプトが生成する標準の非推奨警告とともにこのテキストが含まれます。 |
DisplayName="Blueprint Node Name" |
ブループリント スクリプト内のこのノードの名前は、コードによって生成された名前ではなく、ここで指定された値に置き換えられます。 |
DontUseGenericSpawnObject |
ブループリント スクリプトで Generic Create Object ノードを使用してクラスのオブジェクトをスポーンしないでください。この指定子は、アクタでもアクタ コンポーネントでもないブループリント タイプのクラスにのみ適用されます。 |
ExposedAsyncProxy |
このクラスのプロキシ オブジェクトを Async Task ノードで公開します。 |
IgnoreCategoryKeywordsInSubclasses |
これを使用すると、クラスの最初のサブクラスが継承されたすべての ShowCategories 指定子、HideCategories 指定子を無視するようになります。 |
IsBlueprintBase="true/false" |
このクラスが、Blueprintable または NotBlueprintable 指定子と同様に、ブループリントを作成するための許容可能な基本クラスである (または基本クラスでない) ことを示します。 |
KismetHideOverrides="Event1, Event2, .." |
オーバーライドが許可されていないブループリント イベントのリスト。 |
ProhibitedInterfaces="Interface1, Interface2, .." |
クラスと互換性のないインターフェースを一覧表示します。 |
RestrictedToClasses="Class1, Class2, .." |
ブループリント関数ライブラリ クラスでは、これを使用してリストに指定されたクラスのみの使用を制限できます。 |
ShortToolTip="Short tooltip" |
親クラス ピッカー ダイアログなど、完全なツールチップではコンテンツが長すぎる場合に使用する短いツール ヒントです。 |
ShowWorldContextPin |
このクラスが所有するグラフ内に配置されたブループリント ノードが、通常は非表示であってもワールド コンテキスト ピンを表示する必要があることを示します。このクラスのオブジェクトは、ワールド コンテキストとして使用できないためです。 |
UsesHierarchy |
クラスが階層データを使用していることを示します。[Details (詳細)] パネルで階層編集機能をインスタンス化するために使用されます。 |
ToolTip="Hand-written tooltip" |
コード コメントから自動的に生成されたツールチップをオーバーライドします。 |
ScriptName="DisplayName" |
このクラス、プロパティ、または関数をスクリプト言語にエクスポートするときに使用する名前。非推奨の名前を、セミコロンで区切った追加のエントリとして含めることができます。 |
クラスの実装
すべてのゲームプレイ クラスは、適切に実装するために GENERATED_BODY
マクロを使用しなければなりません。これは、クラスとそのすべての変数と関数を定義するクラスヘッダ (.h) ファイルで
行われます。クラス ソース ファイルとヘッダー ファイルのベスト プラクティスは、A
または U
のプレフィックスを取り除いて、実行中のクラスに一致する名前をつけることです。従って、AActor
クラスのソース ファイルは
Actor.cpp
という名前になります。そのヘッダ ファイルは Actor.h
という名前になります。これは、エディタ内の "Add C++ Class" メニュー オプションによって作成されるクラスを自動的に処理します。
このソース ファイル (.cpp) には C++ クラス宣言を含むヘッダ ファイル (.h) がインクルードされていなければなりません。これは通常自動生成されますが、必要に応じて手書きのコードでも作成可能です。例えば、AActor
クラスに対する C++ 宣言は
EngineClasses.h
ヘッダ ファイルで自動生成されます。つまり Actor.cpp
ファイルには、EngineClasses.h
ファイルかこのファイルをインクルードする
別のファイルがインクルードされていなければなりません。一般的には、ゲーム プロジェクト用のヘッダ ファイルをインクルードし、それがゲーム プロジェクトのゲームプレイ クラスのヘッダをインクルードします。AActor
と EngineClasses.h
の場合、
Engine プロジェクト用のヘッダ ファイルである Engine.h をインクルードする EnginePrivate.h
ヘッダがインクルードされ、それが Engine.h
ヘッダ ファイルをインクルードします。
#include "EnginePrivate.h"
インクルードされていないクラスの関数の実装で他のクラスを参照する場合、ファイルを追加でインクルードする必要があるかもしれません。単にそのファイルをインクルードして追加します。
クラス コンストラクタ
UObjects
は コンストラクタ を使ってプロパティおよびその他の変数のデフォルト値の設定や、その他必要な初期化を実行します。クラス コンストラクタは通常、クラス実装ファイル内に置かれます。
例えば、AActor::AActor
コンストラクタであれば、 Actor.cpp
の中です。
一部のコンストラクタは、モジュール別に特別な「コンストラクタ」ファイルに置かれる場合もあります。例えば、AActor::AActor
コンストラクタは EngineConstructors.cpp
内に存在します。これは
以前に、コンストラクタの採用に DEFAULTS
ブロックを使用した自動変換プロセスの結果です。これらは時間と共にそれぞれのクラス ソース ファイルに移動していきます。
コンストラクタ インラインをクラス ヘッダ ファイルに配置することも可能です。ただし、コンストラクタがクラス ヘッダ ファイル内にある場合、
自動コードジェネレータがヘッダにコンストラクタ宣言を生成することを防ぐために、 UClass は CustomConstructor
指定子で宣言されなければなりません。
コンストラクタの形式
以下が、 UObject コンストラクタの最も基本的な形式です。
UMyObject::UMyObject()
{
// クラスデフォルト オブジェクト プロパティをここで初期化する。
}
このコンストラクタが Class Default Object (CDO) を初期化し、クラスのその後のインスタンスがベースとするマスター コピーになります。特別なプロパティ変更構造体をサポートする セカンダリ コンストラクタもあります。
UMyObject::UMyObject(const FObjectInitializer& ObjectInitializer)
:Super(ObjectInitializer)
{
// CDO プロパティをここで初期化する。
}
上記のコンストラクタは両方とも実際には初期化は実行しませんが、エンジンがすべてのフィールドをゼロ、NULL、またはデフォルト コンストラクタが実装する値にしているはずです。
ただし、コンストラクタに書き込まれた初期化コードは CDO に適用されるので、
CreateNewObject
や SpawnActor
のように、エンジン内で正しく作成されたオブジェクトの新規インスタンスにコピーされます。
コンストラクタに渡される FObjectInitializer
パラメータは、const とマークされていますが、ビルトインの「可変」 (mutable) 関数経由で設定してプロパティとサブオブジェクトをオーバーライドすることができます。作成されている UObject
にこれらの値が反映されるので、
それを使って登録されたプロパティまたはコンポーネントの値を変更することができます。
AUDKEmitterPool::AUDKEmitterPool(const FObjectInitializer& ObjectInitializer)
:Super(ObjectInitializer.DoNotCreateDefaultSubobject(TEXT("SomeComponent")).DoNotCreateDefaultSubobject(TEXT("SomeOtherComponent")))
{
// CDO プロパティをここで初期化する。
}
上記のケースでは、スーパークラスは "SomeComponent" および "SomeOtherComponent" という名前のサブオブジェクトをコンストラクタ内に作成しようとしますが、FObjectInitializer があるので作成はしません。
次のケースでは、SomeProperty
が CDO でデフォルトで 26 になるので、AUTDemoHUD の各インスタンスが新しくなります。
AUTDemoHUD::AUTDemoHUD()
{
// CDO プロパティをここで初期化する。
SomeProperty = 26;
}
Constructor Statics と Helpers
さらに複雑なデータ型、特にクラスの参照、名前、アセットの参照のために値を設定する場合、
必要な様々なプロパティ値を保持するためにコンストラクタ内で ConstructorStatics 構造体を定義およびインスタンス化することが求められます。ConstructorStatics
構造体は、コンストラクタの初回実行時のみ作成されます。次の実行時にはポインタをコピーするだけなので、
処理速度が超高速になります。ConstructorStatics
構造体が作成されると、後にコンストラクタで実際のプロパティに値を代入する時に、
アクセス手段として構造体のメンバに値が代入されます。
ContructorHelpers は、コンストラクタ特有の共通のアクションを実行するために使用するヘルパー テンプレートを含む ObjectBase.h
で定義される特別な名前空間です。例えばヘルパー テンプレートには、
アセットやクラスへの参照を検索するためだけでなく、コンポーネントを作成したり検索するものもあります。
アセットの参照
クラスにアセットの参照が存在しないことが理想的です。ハードコード化されたアセットの参照は壊れやすいので、アセット プロパティの設定にはブループリントの使用が推奨されてきました。しかし、 ハードコード化された参照は完全にサポートされています。オブジェクトを構築するたびにアセットの検索を行いたくないため、検索は 1 度だけ行います。静的な構造体を使用して、アセット検索は必ず 1 回だけ 実行するようにできます。
ConstructorHelpers::FObjectFinder
は StaticLoadObject
を使って指定された UObject
への参照を検索します。一般的にこれはコンテンツ パッケージに格納されているアセットの参照に使用します。オブジェクトが見つからない場合、
失敗したことが報告されます。
ATimelineTestActor::ATimelineTestActor()
{
// 1度きりの初期化を維持するための構造体
struct FConstructorStatics
{
ConstructorHelpers::FObjectFinder<UStaticMesh> Object0;
FConstructorStatics()
:Object0(TEXT("StaticMesh'/Game/UT3/Pickups/Pickups/Health_Large/Mesh/S_Pickups_Base_Health_Large.S_Pickups_Base_Health_Large'"))
{
}
};
static FConstructorStatics ConstructorStatics;
// プロパティの初期化。
StaticMesh = ConstructorStatics.Object0.Object;
}
クラスの参照
ConstructorHelpers::FClassFinder
は指定された UClass
への参照を検索し、見つからない場合は失敗したことを報告します。
APylon::APylon(const class FObjectInitializer& ObjectInitializer)
:Super(ObjectInitializer)
{
// 1度きりの初期化を維持するための構造体
static FClassFinder<UNavigationMeshBase> ClassFinder(TEXT("class'Engine.NavigationMeshBase'"));
if (ClassFinder.Succeeded())
{
NavMeshClass = ClassFinder.Class;
}
else
{
NavMeshClass = nullptr;
}
}
たいていの場合、 USomeClass::StaticClass()
を使って ClassFinder の複雑さをまとめてスキップすることができます。例えば、ほとんどの状況で次のメソッドを利用できます。
NavMeshClass = UNavigationMeshBase::StaticClass();
モジュール間の参照の場合は、ClassFinder メソッドを使用した方が良いかもしれません。
コンポーネントとサブ オブジェクト
コンポーネント サブオブジェクトの作成およびアクタの階層へのアタッチも、コンストラクタ内で行うことができます。アクタのスポーン時に、そのコンポーネントは CDO からクローンされます。コンポーネントが毎回正しく作成、破棄、ガーベジコレクション処理されるように、 コンストラクタで作成された各コンポーネントへのポインタは、所有クラスの UPROPERTY に格納されます。
UCLASS()
class AWindPointSource : public AActor
{
GENERATED_BODY()
public:
UPROPERTY()
UWindPointSourceComponent* WindPointSource;
UPROPERTY()
UDrawSphereComponent* DisplaySphere;
};
AWindPointSource::AWindPointSource()
{
// 新しいコンポーネントを作成し、名前を付けます。
WindPointSource = CreateDefaultSubobject<UWindPointSourceComponent>(TEXT("WindPointSourceComponent0"));
// 新しいコンポーネントをこのアクタのRootComponentとして設定するか、すでに存在する場合はルートにアタッチします。
if (RootComponent == nullptr)
{
RootComponent = WindPointSource;
}
else
{
WindPointSource->AttachTo(RootComponent);
}
// 2つ目のコンポーネントを作成します。これは、先ほど作成したコンポーネントに添付されます。
DisplaySphere = CreateDefaultSubobject<UDrawSphereComponent>(TEXT("DrawSphereComponent0"));
DisplaySphere->AttachTo(RootComponent);
// 新しいコンポーネントにいくつかのプロパティを設定します。
DisplaySphere->ShapeColor.R = 173;
DisplaySphere->ShapeColor.G = 239;
DisplaySphere->ShapeColor.B = 231;
DisplaySphere->ShapeColor.A = 255;
DisplaySphere->AlwaysLoadOnClient = false;
DisplaySphere->AlwaysLoadOnServer = false;
DisplaySphere->bAbsoluteScale = true;
}
親クラスに属するコンポーネントの修正は通常必要ありません。ただし、親クラスによって作成されたコンポーネントを含め、アタッチされたすべてのコンポーネントの現在のリストが、
ルート コンポーネントを含め、USceneComponent
の GetAttachParent
、GetParentComponents
、GetNumChildrenComponents
、GetChildrenComponents
、GetChildComponent
を
呼び出すことで利用することができます。