[4.7] How Can I Fully Disable Character Movement Replication?

Dear Epic,

How can I completely disable character movement replication so I can use my own movement replication system?

I developed a method that works great for me, including when there is packet loss, but I cannot figure out how to

  1. disable character movement replication

  2. still be able to a client controlled unit (server is free to move, but client always ends up unable to move freely, constantly having its position reset/adjusted by server.

#Context

I am using nettest.txt, run on both client and server during game time, to simulate network conditions

Net PktLoss=1
Net PktOrder=0
Net PktDup=0
Net PktLag=75
Net PktLagVariance=0
p.netshowcorrections 1
log lognetplayermovement verbose

#Issue

The client jitters / jumps positions with the above amount of packet loss.

I’ve experienced this in real multiplayer games, which have similar jumping/jittering/stuttering behavior to the artifical test using nettest.txt

I have my own custom movement replication code that I’d like to use, but I cannot figure out how to disable UE4’s standard character movement replication code.

The server is fine, but the client’s experience is always that the character becomes stuck / unable to move when I try to disable movement replication.

#My Goal

I am trying to completely remove standard UE4 character movement replication, so I can use my own method, but no matter what I try, the client’s controlled character will either be stuttering as usual or simply unable to move.

#What I’ve Tried

bReplicatesMovement, trued turning this off. The server stops replicating movement to client, but client controlled unit still stutters and jumps during packet loss!

Tried overriding and nullifying various movement replication functions in custom CharacterMovementComponent,

including

//virtual void SendClientAdjustment() override;
	//virtual bool ClientUpdatePositionAfterServerUpdate() override;
	
	//virtual void SmoothCorrection(const FVector& OldLocation) override;
	//virtual void SmoothClientPosition(float DeltaTime) override;
	
	//virtual void ForcePositionUpdate(float DeltaTime) override;
	//virtual void CallServerMove(const class FSavedMove_Character* NewMove, const class FSavedMove_Character* OldMove) override;
	//virtual void ServerMoveHandleClientError(float TimeStamp, float DeltaTime, const FVector& Accel, const FVector& ClientLoc, UPrimitiveComponent* ClientMovementBase, FName ClientBaseBoneName, uint8 ClientMovementMode) override;

This usually results in the client controlled character being unable to move at all!

#Conclusion

No matter what I do I can’t seem to “free” the client’s character from the influences of the character replication code that causes severe jitter when running nettest.txt

It’s a monumental task to re-write entire character class, I just want to disable character movement replication and still be able to move the client controlled character around freely!

#My Exact Question
How do I free the client’s controlled character to roam freely without influence of UE4 standard character movement replication?

Thanks!

Rama

In UE3, I invested quite some time in checking how Actor were replicated, and in the base Actor replication channel, the transform was replicated no matter what, interpolated and “packed” as to be smaller to transfer over the network. You could not remove the position property to be replicated directly from Unreal Script.

I have not checked UE4 replication system yet, but I would bet it’s the same. I’ll try to check in the source and find a better lead, but maybe this can help in the meantime…

Mick

Nice to hear from you Mick!

:slight_smile:

Rama

still waiting on this one, would love to hear from you Epic!

Hi Rama!

So since you were still looking into this, I digged a bit deeper in the code to try and find out where this code resides.

So first in

void UActorChannel::ProcessBunch( FInBunch & Bunch )

I can find where new actor are replicated, and they do force replication of Location, Rotation and Velocity.

After digging a bit more, I found that it uses this to do movement replication on an actor:

/** Used for replication of our RootComponent's position and velocity */
	UPROPERTY(ReplicatedUsing=OnRep_ReplicatedMovement)
	struct FRepMovement ReplicatedMovement;

And this is where the server seems to fill that info:

/** fills ReplicatedMovement property */
	virtual void GatherCurrentMovement();

So since this function is virtual, have you tried overriding that and doing your own stuff?

Great to hear from you Michael!

I did try as you suggested, and set bReplicateMovement to false and also overrided the function GatherCurrentMovement();

#The Problem

The problem I have is that when there is packet loss, the client loses total control over their unit and it jitters as it gets server adjustements

I tried overriding every single function I list in my original post but I cannot get rid of this behavior!

#Epic?

Epic any commentary on how I can just completely free the client from getting any influence from the server while also still being able to move?

Cause if I override all the server adjustment functions then the client simply hangs out in mid air and cant move at all!

I’d really love to use the Character class and be able to write my own replication code so I can handle the packet loss differently.

Rama

Did you get a response or find an answer for this Rama? I also want to be able to roll my own movement replication but all my attempts leave my client character jittering in place after attempting to move.

@Playground

Not yet!

#@Epic

Epic would love to hear from youuuuu!

#:heart:

Rama

It seems my problems are caused by the CharacterMovementComponent, “Characters using CharacterMovementComponent automatically have client-server networking built in.”, I assumed this functionality was turned off if replicate movement was turned off but it seems like it is not. I have switched to using Pawns with no CharacterMovementComponent with my own movement replication and with my small amount of testing it seems to have fixed my problems.

I tested on a new project with two pawns that are replicated and replicate movement turned off. I can move my client freely around locally without it snapping back, which is what I need so I can roll my own movement replication code.

Source: Understanding Networked Movement in the Character Movement Component for Unreal Engine | Unreal Engine 5.1 Documentation

Edit:

Using p.NetCorrectionLifetime 5 on a character with Replicate on and Replicate Movement off when you try to set the location of the actor you can see the debug of where the Server is correcting the location of the actor using the CharacterMovementComponent.

I’m going to log a bug report as I believe this isn’t the desired behavior or is atleast misleading.

Great to hear from you PlaygroundCircus!

Yes I was just investigating using Pawn instead of Character myself, the last tests I need to verify involve making sure that UE4 navigation system still works with the Pawn! Seems like everything should work since UE4 navigation seems to only go up to UPawnMovementComponent, not all the way to UCharacterMovementComponent.

Thank you for sharing your research PlaygroundCircus!

#:heart:

Rama

#Getting AI Working with Pawn Only

I’ve discovered that the single and only function you have to re-implement to get the whole AI system working with a UPawnMovementComponent is this!

//Base
public:
	/** request direct movement */
	virtual void RequestDirectMove(const FVector& MoveVelocity, bool bForceMaxSpeed) override;

This was the same function I over-rode to get UE4 nav system to work with my PhysX simulating characters!

#Video

#Yay! RPCs Working Great With Only APawn inheritance

I made a playable character that extends APawn, and I am happy to report that RPCs still work, client to server!

I wrote this code to test:

#.h

UCLASS(config=Game)
class APawnGameCharacter : public APawn
{
	GENERATED_BODY()
public:

//RPC Test
public:
	UFUNCTION(Reliable,Server,WithValidation)
	void SERVER_SendMessage(const FString& Message);
	bool SERVER_SendMessage_Validate(const FString& Message);
	void SERVER_SendMessage_Implementation(const FString& Message);
	
	UFUNCTION(BlueprintCallable,Category="RPC Test")
	void LOCAL_SendMessageToServer(FString Message);

#.cpp

void APawnGameCharacter::LOCAL_SendMessageToServer(FString Message)
{
	if(HasAuthority())
	{
		SERVER_SendMessage("Server is talking to Self ~ " + Message);
	}
	else
	{
		SERVER_SendMessage("CLIENT RPC SEND MESSAGE TO SERVER SUCCESS WOOHOO!!!!!! ~ " + Message);
	}
}
    
bool APawnGameCharacter::SERVER_SendMessage_Validate(const FString& Message)
{ 
	return true; 
}
void APawnGameCharacter::SERVER_SendMessage_Implementation(const FString& Message)
{
	UE_LOG(Joy,Warning,TEXT("%s"), *Message);
}

#Summary

With both client to server RPCs working and the UE4 Naigation system working with just APawn I am happy to report that the ability to circumvent the ACharacter class to handle movement replication in one’s own way is indeed quite do-able and pleasantly so!