Might
(Might)
November 2, 2018, 7:18pm
1
いつもお世話になります。
Actorを継承したC++クラスのパラメータによって、
ActorのRootComponentに対してAttachToを行いたいと考えていますが、
AttachToを「コンストラクタに近い場所(欲を言えばコンストラクタ)」で行うことはできますでしょうか?
具体的には、
UPROPERTY( EditAnywhere , BlueprintReadWrite , Category = "Text" , Meta = (ExposeOnSpawn = true , AllowPrivateAccess = true) )
FString DisplayString;
というプロパティがあり、エディタから上記変数に値を設定します。
その後、
for( int32 i = 0 ; i < DisplayString.Len() ; i++ )
{
auto a = CreateDefaultSubobject<UPaperSpriteComponent>(TEXT("sprite"));
a->AttachTo(RootComponent);
}
というようにAttachToを「コンストラクタに近い場所(欲を言えばコンストラクタ)」で行いたいのです。
しかしながら、
エディタで設定したメンバ変数はコンストラクタではまだ初期化されていない。(これは当然と思います。)
Actorから継承したBeginPlayやPostInitializeComponentsなどでAttachToを行うことはできるかもしれませんが、自作のActorをStreamLevelに配置し、StreamLevelをLoadStreamLevelで先読みした際にコンストラクタしか呼ばれず、BeginPlayやPostInitializeComponentsは実際にStreamLevelを表示した際にしか呼び出されない。
という動作になっているようで、
LoadStreamLevelで読み込んだ段階でActor内のコンポーネントの初期化を行えない状況です。
上記、メンバ変数に基づいてコンストラクタ内で初期化する事は可能でしょうか?
※またはLoadStreamLevelで自作Actorを読み込んだ段階でメンバ変数に基づいてコンポーネントの初期化を行うことは可能でしょうか?
以上です。ご教示の程お願いいたします。
alwei
(alwei)
November 3, 2018, 11:17am
2
要はBPのコンストラクションスクリプトのようなことをやりたいということでよろしいでしょうか?
コンストラクションスクリプトはBPだと簡単に設定できますが、C++では多少特殊な方法で構築します。詳しくは以下のブログ記事でわかると思います。
もし用途が違うということであればすみません。
Might
(Might)
November 3, 2018, 5:11pm
3
いつもご回答ありがとうございます。
まさにやりたい事はリンク先のような内容です。
ただ1点気になったことがあるので、追加質問させていただいてもよろしいでしょうか。
※質問を別スレッドで立てた方がよい場合は、別スレッドで質問させていただきます。
OnConstructionもコンストラクションスクリプトも、
レベルロード時ではなく、レベルを表示した際に呼び出されているようなのですが、
パフォーマンス的に問題なさそうか気になっております。
実際にNewObjectで30個の新規コンポーネントを作成しAttachToComponentでRootComponentに追加を行う処理をOnConstructionで行ってみましたがFPS落ちもせず問題なく動作しています。
しかしながら大量のコンポーネントを作成するActorをレベル上に配置するとLoadStreamLevelで先読みした状態でも実際にレベルの表示を行うと処理落ちするという事になる事を恐れています。
OnConstructionをLoadStreamLevelで読み込んだ際に呼び出す方法などはないでしょうか?
※実際に現状は処理落ちしておりませんので杞憂かもしれませんが、気になったので質問させていただきました。
alwei
(alwei)
November 3, 2018, 9:21pm
4
次回からは別質問は別スレッドで立てるようにお願いします。
パフォーマンス的な問題は必ず発生します。LoadStreamLevel時にヒッチが発生してしまうということは避けられず、それ自体は仕方ないのですが最適化する方法は存在しています。それに詳しい内容をEGJの方が公開してくれています。
[4.20版] UE4におけるLoadingとGCのProfilingと最適化手法
ただし、コンストラクションスクリプトやOnConstructはエディター実行時とパッケージされたゲーム内では呼び出されるタイミングが違います。私の記憶が正しければそれらはアセットをCookする際に呼び出されており、ゲーム中には負荷として計上されないようになっています。普段は調整がしやすいようにそのように呼び出されているはずです。