Announcement

Collapse
No announcement yet.

Networking for Multiplayer and Unreal Physics desync.

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Networking for Multiplayer and Unreal Physics desync.

    I've recently beem working on a networked game and ran into some troubles with replication on physics objects. The image below was with an object with replicate movement off:
    Click image for larger version

Name:	Coins_RepMovOff_S.PNG
Views:	1868
Size:	29.5 KB
ID:	1523014

    Even with replicate movement on I get some desync (its hard to tell in the image but its subtle) and other issues (like characters glitching when they touch the object or disappearing).
    Click image for larger version

Name:	Coins_S.PNG
Views:	1815
Size:	29.2 KB
ID:	1523015

    Am I doing replication for physics objects incorrectly? Ideally for these types of objects i would like physics to only be generated from the server.

    Code:
    // Fill out your copyright notice in the Description page of Project Settings.
    //@CoinPickup.h
    #pragma once
    
    #include "CoreMinimal.h"
    #include "Pickup.h"
    #include "CoinPickup.generated.h"
    
    /**
     * 
     */
    UCLASS()
    class CPPTEST_API ACoinPickup : public APickup
    {
        GENERATED_BODY()
    public:
        //set default values for constructor
        ACoinPickup();
    
    
    
    
    };
    
    // Fill out your copyright notice in the Description page of Project Settings.
    //@CoinPickup.cpp
    #include "CoinPickup.h"
    
    ACoinPickup::ACoinPickup()
    {
        //keep physics synced from client to server
        bReplicateMovement = true;
        //this coponent is physics enabled and should move
        GetStaticMeshComponent()->SetMobility(EComponentMobility::Movable);
        GetStaticMeshComponent()->SetSimulatePhysics(true);
    }
    
    
    // Fill out your copyright notice in the Description page of Project Settings.
    //@Pickup.h
    #pragma once
    
    #include "CoreMinimal.h"
    #include "Engine/StaticMeshActor.h"
    #include "Pickup.generated.h"
    
    /**
     * 
     */
    UCLASS()
    class CPPTEST_API APickup : public AStaticMeshActor
    {
        GENERATED_BODY()
    
    public:
        //Set default values
        APickup();
    
        //Code for networking
        void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;
    
        //Returns wether or not the pickup is activated
        UFUNCTION(BlueprintPure, Category = "Pickup")
        bool IsActive();
    
        //Allows other classes to safely change the pickup's activation state
        UFUNCTION(BlueprintCallable, Category = "Pickup")
        void SetActive(bool newPickupState);
    
    
    protected:
    
    
        //True when pickup can be activated
        UPROPERTY(ReplicatedUsing = OnRep_IsActive)
        bool bIsActive;
    
        //This is called whenever bIsActive is updated
        UFUNCTION()
        virtual void OnRep_IsActive();
    };    
    // Fill out your copyright notice in the Description page of Project Settings.
    //@Pickup.cpp
    #include "Pickup.h"
    #include "Net/UnrealNetwork.h"
    
    
    
    APickup::APickup()
    {
        //Tells UE4 to replicate actor
        bReplicates = true;
    
        //Pickups will never tick
        PrimaryActorTick.bCanEverTick = false;
    
        if (Role = ROLE_Authority)
        {
            bIsActive = true;
        }
    }
    
    void APickup::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
    {
        Super::GetLifetimeReplicatedProps(OutLifetimeProps);
    
        DOREPLIFETIME(APickup, bIsActive);
    }
    
    void APickup::OnRep_IsActive()
    {
    
    }
    
    void APickup::SetActive(bool newPickupState)
    {
        if (Role == ROLE_Authority)
        {
            bIsActive = newPickupState;
        }
    }
    
    bool APickup::IsActive()
    {
        return bIsActive;
    }

    #2
    Physics does not play well with the network. Typically it is reserved for visual-only effects like destruction etc, or for vehicles (but they are usually client-authoritative and only used because people don't bother to write their own proper vehicle movement components - but hey, they give me a job...).

    Physics replication is therefore a sore subject. To fix desync, you have a couple of initial options:

    1) Do not use replicated movement, and instead send the replicated movement data to all clients via a Multicast RPC at a frequent interval. Have clients update their object with the most recent state when they receive it, and implement some smoothing for the rendered object if you can. This will give the most fluid results and would be my recommend approach if you absolutely need to use physics.

    2) Use replicated movement, but only simulate physics on the server and override the default replicated movement behaviour to NOT copy the simulate physics flag to clients. This will result in frequent snapping, but requires less work.

    3) Don't use physics, and redesign the objects behaviour if it's not essential to the game. Coins dropping for example can be easily simulated locally without any need to real collision processing or even movement. Some stuff can be done with simple curves.

    I am currently putting together a generic network movement framework that will provide some more out-of-the-box solutions including some of the above, but it's not quite ready yet.

    Comment


      #3
      Ah, alright. Thanks for the reply and i'll give those a whirl!

      Comment


        #4
        Originally posted by TheJamsh View Post

        I am currently putting together a generic network movement framework that will provide some more out-of-the-box solutions including some of the above, but it's not quite ready yet.
        Interesting. Please elaborate.

        WIP Thread

        Comment


          #5
          Originally posted by Rhynedahll View Post

          Interesting. Please elaborate.
          I'll make a post soon(ish) - but I will provide more details when I can.

          Comment


            #6
            Originally posted by TheJamsh View Post

            2) Use replicated movement, but only simulate physics on the server and override the default replicated movement behaviour to NOT copy the simulate physics flag to clients. This will result in frequent snapping, but requires less work.
            Hi TheJamsh,

            I am currently trying to implement this solution, but I am having trouble with it. I'm a novice when it comes to network programming (especially network programming in UE4), so I was hoping you could give me some pointers on how to do this.

            Comment

            Working...
            X