【UE5】もしかして、C++プロジェクトで作ったBPのクラスは、普通にレプリケーションできないのか?(そんなことなかった)

この記事は約5分で読めます。

このフォーラムの人と同じ現象が出てる。

GetLifetimeReplicatedProps() override in BP?
Hey, i have overridden GetLifetimeReplicatedProps() in my C++ superclass, and now when i set some variable (that i have ...

次のは古いけど、昔からなんかおかしいのかも。

Blueprint Components & Replication
Hello ElliotB, There is not a definite time frame in place for this issue at this time. The status has not be changed to...

もしかしたらUEプロジェクトをC++プロジェクトで作り始めた場合は、次のをやってやらなきゃいけないってことなんだろうか?

Subobject Replication for Blueprint Child Class
Wow I forgot I posted this so long ago but yes! I did find a solution which was answered on UE4 Answer HUB. Basically yo...

void UNetworkObject::GetLifetimeReplicatedProps(TArray< FLifetimeProperty > & OutLifetimeProps) const { Super::GetLifetimeReplicatedProps(OutLifetimeProps);

    UBlueprintGeneratedClass * bpClass = Cast<UBlueprintGeneratedClass>(this->GetClass());

if (bpClass != nullptr)
{
bpClass->GetLifetimeBlueprintReplicationList(OutLifetimeProps);
}
}

実はかなり前から、少なくともCharacterクラスに関しては、何かがおかしいと思いながら組んでた。BPで定義した変数はレプリケーションしないから、C++で定義してレプリケーション設定して、それをBPから取得してた。

【UE5】アニメーションBPの変数はレプリケーションできないのかな?
全てのアニメーションをアニメーションBP内で能動的に決められるのならそれに越したことはないんだろうけど、そうもいかない。どうしても外から特定のアニメーションを再生させたいってなる。で、再生させられるんだが、全てのクライアントでは実行されなか...

もしかしたら↑こういうのとかも、原因は・・って、そんな馬鹿な。

なんかPlayerStateは勝手にレプリケーションするみたいな話があるんだが、ブループリントで自作したPlayerState自体がレプリケーションしてない気がしなくもない。プロパティはちゃんとレプリケーションするようになってるけど。

C++プロジェクトで作り始めた人は、できるだけC++で書け、変数はC++で定義しろってことなんだろか?公式ドキュメントのサンプルを見ると、がっつりC++で組んでたりするし。いやまあC++のサンプルなんだから当たり前っちゃそうなんだけど。

追記)
いま試してみたら、GetLifetimeReplicatedPropsに次の行を丸コピーしてみたら、ほんとにちゃんと動いたかも。

UBlueprintGeneratedClass * bpClass = Cast<UBlueprintGeneratedClass>(this->GetClass());
if (bpClass != nullptr)
{
bpClass->GetLifetimeBlueprintReplicationList(OutLifetimeProps);
}

とりあえず継承してるBPが1つだけなら、本当にちゃんとキャストして取ってきてた。変数もレプリケートされてる。(ように見える。さっきまでと挙動が違う)

えええええ、もしかして今までしなくてもいい苦労を散々しちゃってたのかなぁ。なんか疲れた。

更に追記)やっぱり、↑これ取り消し。なんか上手く行かない。

更にさらに追記)
ちゃんとテストプログラムってか、ノードを組んで確認してみた。

間違いないはず。そして次のコードは不要

UBlueprintGeneratedClass * bpClass = Cast<UBlueprintGeneratedClass>(this->GetClass());
if (bpClass != nullptr)
{
bpClass->GetLifetimeBlueprintReplicationList(OutLifetimeProps);
}

これが無くてもブループリントで変数(レプリケーションあり)が、ちゃんとレプリケーションする。

レプリケーションについて正しく理解してなかったから勘違いしてた。

変数をReplicatedに変更してネットワーク上に作成する、と言ってもPlayerStateやCharacterクラスなどの場合、実際はサーバーとクライアントの両方に変数を持つことになる。

たとえばレプリケーション変数ABCの初期値が0だったとする。
で、何かの拍子でこの変数ABCがクライアントで1に書き換えられたとする。
すると同じ変数ABCでもサーバーとクライアントで保持してる値が違うことになる。
しかし、待てど暮らせどレプリケーションは行われない。
それならと、RPCで変数ABCに0を設定してあげてもレプリケーションしない。
サーバーでは値が変更されてないから。サーバーではずっと0のまま。
レプリケーションはサーバーで値が変更された時だけ行われる。
RPCで変数ABCを2に設定してあげると即座にレプリケートされて、クライアントの変数ABCも2になる。

大して難しい話ではないが、この特性を正しく理解して組んでやらないと、サーバーとクライアントで保持してる値が違うことになって、おかしなことになる。俺が何度も、ちゃんと動くような動かないような、よく分からない、となってしまってたのは、たぶんこれのせい。

クライアントで値を書き換えるのが悪いんだろ!というのはもっともな話だが、これがまたいろいろと複雑な事情があったりする。いや、そんな複雑でもないのか。

コメント

タイトルとURLをコピーしました