Loading

comp->SetIsReplicated(true) 与 actor->SetReplicateMovement(true)

前情提要:

最近在做联机下的MovingObject的同步,MovingObject包含一个或者多个StaticMeshComponent

因为是新手所以不太理解actor->SetReplicateMovement(true)comp->SetIsReplicated(true) 的区别,特此写文来说明研究过程

结论:

actor->SetReplicateMovement(true)会将Actor中的root component的Transform(position, rotation, scale)属性同步

comp->SetIsReplicated(true)则是会将comp中所有的属性都拷贝过去,而不仅仅是component的Transform

也就是两者侧重点不同,一个是只关注actor的root component的Transform,一个是关注comp的各个属性。

探究过程:

一开始按照函数名字解读以为是只要Actor内部有运动,其Transform都会被复制到各个客户端,但在探索联机MovingObject的同步时,发现并不如所想的那样运行。

其主要原因是我现在在做的MovingObject包含了两个StaticMeshComp,运动的话类似于天平一上就会一下,于是我就没有把他们其中任意一个设置为RootComponent,这也就是探究的开始...

由于较为简单,于是并没采用曲线而是直接手搓了一个在Tick中根据状态(一上一下/一下一上/停止)不断设置两个StaticMeshComp的Location的办法,类似于:

void AMyActor::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);
    if (state == 一上一下)
    {
        // TODO...SetLocation
    }
    else if (state == 一下一上)
    {
        // TODO...SetLocation
    }
    else 
    {
        //TODO
    }
}

然后我就将state设置为了Replicated,并只设置了这个Actor的SetReplicateMovement(true)。结果发现并没有同步,也就是客户端最后呈现的位置与服务器上的位置有所偏差,于是就去看了对应的源码。

很容易得知,假如设置了SetReplicateMovement(true)那么,简单地说其实就是把Actor中的bReplicateMovement设置为true。

然后我们看如果为True会影响什么:

image-20240109185656094

从这里我们可以看出来,其实Actor的Transform的同步是基于属性同步实现,其中关键的就是ReplicatedMovement这个成员变量。

image-20240109190259065

然后我们去看这个ReplicatedMovement是怎么生成的,其实主要就是在AActor::GatherCurrentMovement

image-20240109190840762

我们可以看出:

  • 该函数在每次属性同步前都会被调用, 以生成相应的位置信息.

    • bReplicateMovement 生成 ReplicatedMovement
    • RootComponent->GetAttachParent() 生成 AttachmentReplication
  • 判断是否开启物理, 物理的同步和没有物理的同步方式不一样

image-20240109191358869

但是不管怎么样都会把RootComponent的Transform同步到ReplicatedMovement

接下来我们看回调函数OnRep_ReplicatedMovement,也是比较简单,就是把同步过来的Transform设置给本地

image-20240109192738430

因为PostNetReceiveLocationAndRotation调用栈有点多就不赘述,最底层是用RootComponent->MoveComponent()这个函数实现变换,值得注意的是,这个函数并没有实现平滑变换(插值外推等),仅仅是Set的作用

建议

如果只有一个StaticMeshComponent并且为RootComponent,并且只想同步其Transform的话就不需要把StaticMeshComponent->SetIsReplicated(true),仅需要设置ReplicatedMovement=true

否则还是建议把所有的StaticMeshComponent都设置Replicated,并设置ReplicatedMovement=true

posted @ 2024-01-09 20:17  ViKyanite  阅读(19)  评论(0编辑  收藏  举报