[UE4] RPC and OnRep in the development of online games (3)

Finally, talk about how to use OnRep to complete the synchronization of bullets.

OnRep

Using attribute synchronization can also complete the synchronization of Client and Server, still taking the previous Fire function as an example.

All relevant parts of Multicast can be commented out. In the header file, declare the attribute Fired to be synchronized and the function OnRep_OnFire() to be called:

UPROPERTY(ReplicatedUsing = OnRep_OnFire)
uint8 Fired;

UFUNCTION()
void OnRep_OnFire();

The ReplicatedUsing here can be simply understood as follows: When the Fired value of the Server changes, the function OnRep_OnFire() is triggered in the Client, but OnRep_OnFire() needs to be manually called on the Server .

Carry out the realization of OnRep_OnFire() in cpp, and carry out the conditional copy of attributes:

void AMultiplayerCharacter::OnRep_OnFire()
{
    
    
    /*生成投射物*/
    /*开枪的动画*/
    /*生成声音*/
    /*...*/
}

void AMultiplayerCharacter::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
    
    
    Super::GetLifetimeReplicatedProps(OutLifetimeProps);
    /*将Fired属性进行条件复制,COND_SkipOwner枚举值表示忽略Shooter本身,防止产生两枚子弹*/
    DOREPLIFETIME_CONDITION(AMultiplayerCharacter, Fired, COND_SkipOwner);
}

Next, in order to clearly show the call logic, compare the call sequence diagram using Multicast in the previous article:
Insert picture description here
Remove the original Multicast part, and see what the logic diagram looks like:
Insert picture description here
Delete the Multicast part, and it will be like this:
Insert picture description here
Source : Page Tour http://www.laoshoucun.com/ Page Tour

Then replace it with the attribute copy and the logic should be like this, the red letter represents the modification, this is the final effect we want (the most important picture in this article, the key point, compared to other nonsense ☺):
Insert picture description here
Source: Page Tour http://www.laoshoucun.com/page tour

The whole process is:

  1. Client1 fires.
  2. Call Server_OnFire() for RPC.
  3. The server receives the RPC, executes Server_OnFire_Implementation(), modifies the synchronization attribute Fired in it, and manually calls OnRep_OnFire() to generate a Fire bullet, animation, sound effect, etc. on the server.
  4. When the synchronization property Fired is modified, the property will be copied and copied to each Client (except Client1, because Client1 itself is ignored through COND_SkipOwner).
  5. The OnRep_OnFire() callback is generated through ReplicatedUsing on each Client, and a Fire bullet, animation, and sound effect are generated on each Client.

After clarifying the logic, the code implementation is very clear. The places that need to be modified are Server_OnFire_Implementation() and OnFire():

void AMultiplayerCharacter::OnFire()
{
    
    
    // 投射物、音效、开枪动画的生成仍放在OnFire()中
    // 生成音效
    // ...
    // 生成动画
    // ...
    // 生成投射物
    FActorSpawnParameters ActorSpawnParams;
    ActorSpawnParams.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AdjustIfPossibleButDontSpawnIfColliding;
    GetWorld()->SpawnActor<AMultiplayerProjectile>(ProjectileClass, Location, Rotation, ActorSpawnParams);
    if(!HasAuthority())
    {
    
    
        // 如果Shooter是在Client端,调用Server_OnFire(),使Server端执行Server_OnFire_Implementation()
        Server_OnFire(SpawnLocation, SpawnRotation); 
    }
    else
    {
    
    
        // 如果Shooter是在Server端,修改同步属性即可,OnRep会在Client端自动调用
        ++Fired;
    }
}

void AMultiplayerCharacter::Server_OnFire_Implementation(FVector Location, FRotator Rotation)
{
    
    
    // Shooter在Client端,当前Server端修改同步属性并手动执行OnRep_OnFire(),Fired修改后会在Client端自动回调OnRep
    ++Fired;
    OnRep_OnFire();
}

Adapt to local conditions

In the current example, the difference between multicast and attribute replication may not be well demonstrated, but in fact the use of the two should be "adjusted to local conditions."

The multicast method is unreliable, and there is no guarantee of arrival. I want to show this explosion effect and show the sound effect, but there may be players who are thousands of miles away from me, and they don’t care what special effects I shoot in another part of the world. Or what sound effects should be heard, or that although they can see me, they are very far away and can only see me "shooting empty shots". It doesn't really matter, this situation is suitable for Multicast.

And attribute replication is reliable. What you want to synchronize is "late but arrives" for friends across the ocean. If it is not synchronized now, it will be synchronized sooner or later. If I implement this explosion effect and sound effect attribute replication, maybe When I was playing Boss, others couldn't see or hear from afar, but after I finished playing for a long time, someone ran over and had a sound effect, it was a little haunted.

I won’t talk too much about this part. There are also some explanations in the Unreal official documents, just a reminder to adapt to local conditions and decide what method to use for synchronization according to the actual situation.

Guess you like

Origin blog.csdn.net/weixin_52308504/article/details/112992769
Recommended