執筆バージョン: Unreal Engine 4.22
|
以前に
[UE4] マルチプレイでの所有権とRPC
で、所有権の違いによるRPCの動作についてフレンドリーに紹介させていただきました。
PlayerControllerを使用した通信方法として以下の記事では
[UE4]RPCを使ったチャット機能の作成
PlayerControllerを経由してのRun on owning ClientとRun on Serverを使用した例をご紹介いたしました。
ローカル環境の変化を通知する手段としてPlayerControllerやPlayerControllerが参照するCharacterを経由して使うのは
クラス自体のアクセスのしやすさから使用しやすいものかと思います。
一方で処理が集中しやすくクラスの必要以上の肥大化やBPで作成してる場合、依存関係にも注意しないといけなかったりと気になる部分ではあります。
回避方法として所有権を持ったActorやComponentに処理を逃がすことも考えらるかと思いますが今回は別のアプローチとして
UE4の基底となるUObjectから継承したオブジェクトで
・プロパティのレプリケーション
・RPC
に対応したものを作成することをしてみました。
では以下がサンプルコードになります
↑のサンプルのオブジェクトを所有権のあるアクターなどに所持させることでRPCとプロパティのレプリケーションができるようになります。
使用方法は以下のようになります。
1:使用するCharacterやPlayerControllerで変数を追加し
UPROPERTY(Replicated)
UReplicationObject* ReplicationObject;
2:GetLifetimeReplicatedPropsにレプリケーションする変数を設定
void ABlogProjectCharacter::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(ABlogProjectCharacter,ReplicationObject);
}
2:ReplicateSubobjectsでアクターチャンネルに追加したオブジェクトをレプリケーションできるように設定
bool ABlogProjectCharacter::ReplicateSubobjects(class UActorChannel *Channel,class FOutBunch *Bunch,FReplicationFlags *RepFlags)
{
bool WroteSomething = Super::ReplicateSubobjects(Channel,Bunch,RepFlags);
if( ReplicationObject != nullptr )
{
WroteSomething |= Channel->ReplicateSubobject(ReplicationObject,*Bunch,*RepFlags);
}
return WroteSomething;
}
3:BeginPlayなどで権限のある環境でオブジェクトを生成。このとき第一引数にオーナーとなるアクターを設定します(このアクターが所有権があればオブジェクト内でRunOnServerなどは使用可能に)
if( HasAuthority() != false )
{
/** 第一引数のOuterにはオーナーになるActorを渡すこと */
ReplicationObject = NewObject<UReplicationObject>(this);
}
簡単ではありますが以上となります。
UEのActorやComponentは多くの便利機能が備わっていますがものによっては使用しないものもあるため
UObjectから作成することで最小サイズで必要機能を作ることができるのはメリットなのかと思います。
またサンプルクラスを継承してBP化することも可能なためイテレーションの面でも特にデメリットはないのかなぁというのが作ってみての感想です。
使用する機会は少ないかもしれませんが覚えておくといつか役に立つ日があるかもしれません(ないかもしれません)
少しでも皆様の開発に役立てばと思います。
ここまで読んでいただきありがとうございました。