If you're having Authority movement issues

Edit: This code here is wrong, look in the replies for my final solution.

Whether it was just my project, or Unreal Engine 5.2, I’m not sure. But I was getting odd behavior with the authority/server side of simulation, specifically with it not even working, no movement or anything out of the authority. I checked and made sure my code matched exactly with the instructor’s, still nothing. If anyone else has this issue my solution was this:

Code must be modified in 2 places, one in the Server_SendMove_Implementation function on GoKartMovementReplication.cpp, you must add an if statement explicitly telling the authority to not simulate movement from here.

void UGoKartMovementReplication::Server_SendMove_Implementation(FGoKartMove Move)
{
	if (MovementComponent == nullptr) return;

	if (GetOwner()->GetLocalRole() != ROLE_Authority)
		MovementComponent->SimulateMove(Move);

	UpdateServerState(Move);
}

Secondly in GoKartMovementComponent.cpp, TickComponent function. Give the authority explicit permission to simulate from here in the if statement. (specifically GetOwner()->GetLocalRole() == ROLE_Authority) It may be possible to remove the entire if statement without anything breaking at this point since it’s letting everything through, I haven’t personally tried it.

void UGoKartMovementComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
	Super::TickComponent(DeltaTime, TickType, ThisTickFunction);

	if (GetOwnerRole() == ROLE_AutonomousProxy || GetOwner()->GetRemoteRole() == ROLE_SimulatedProxy || GetOwner()->GetLocalRole() == ROLE_Authority)
	{
		LastMove = CreateMove(DeltaTime);
		SimulateMove(LastMove);
	}
}

Again I’m not sure if this was just my project, or a version difference. Hope it helps someone.

1 Like

There are a number of breaking changes in 4.25 onwards which affected things like this. I used to have a list of code changes that had to be made to ensure it worked correctly. These changes do apply to 5.x as well.

1 Like

UPDATE:
Making those changes broke the client side of simulation and replication. After a few hours of debugging and testing, here is the final code I ended up with. With this both simulation and replication work perfectly for me. Most of my troubles came from roles.

On GoKartMovementReplicator.cpp:

void UGoKartMovementReplication::Server_SendMove_Implementation(FGoKartMove Move)
{
	if (MovementComponent == nullptr) return;
    // The issue is NOT here, no if statement should be here
	MovementComponent->SimulateMove(Move);

	UpdateServerState(Move);
}

In the TickComponent of GoKartMovementReplicator:

	if (GetOwner()->GetLocalRole() == ROLE_AutonomousProxy)
	{
		UnacknowledgedMoves.Add(LastMove);
		Server_SendMove(LastMove);
	}
	// THIS if statement is changed from the original, this is a much safer way of ensuring the authority is the one calling this.
	if (GetOwner()->GetLocalRole() == ROLE_Authority && Cast<APawn>(GetOwner())->IsLocallyControlled())
	{
		UpdateServerState(LastMove);
	}
	if (GetOwnerRole() == ROLE_SimulatedProxy)
	{
		ClientTick(DeltaTime);
	}

Now in GoKartMovementComponent.cpp, TickComponent:

void UGoKartMovementComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
	Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
    // This if statement is changed from the original, it allows only locally controlled pawns to simulate from here.
	if (Cast<APawn>(GetOwner())->IsLocallyControlled())
	{
		LastMove = CreateMove(DeltaTime);
		SimulateMove(LastMove);
	}
}

This code should simulate simulated proxies only from the movement replicator component, and locally controlled pawns from the movement component. It seems to me that a lot of the changes in 4.25 onwards had to do with roles, I’m not exactly sure why or how.

2 Likes

Privacy & Terms