MultiCast function with strange behaviour

Hello,

I try to make my crouch logic work on network too (for coop purposes).
I use a server RPC and a multicast function. The multicast function is weird: it contains a Mesh->AddLocalTransform() function call and a CapsuleComponent->SetCapsuleHalfHeight() function call.

If I crouch with a client character in the viewport of another client I can see the effect of the SetCapsuleHalfHeight, but not the effect of the AddLocalTransform. They are called in the same multicast function.

Any idea?

The code:

void ATPSGameCharacter::CrouchPressed()
{
	if (CharacterState == ECharStates::CS_Default)
	{
		if (Role == ROLE_Authority)
		{
			CharacterState = ECharStates::CS_Crouch;
			float HalfHeight = CapsuleComponent->GetScaledCapsuleHalfHeight();
			CrouchMulticast(true, HalfHeight);
		}
		else
		{
			CrouchRequestRPC(true);
		}
	}
}

void ATPSGameCharacter::CrouchReleased()
{
	if (CharacterState == ECharStates::CS_Crouch)
	{
		if (Role == ROLE_Authority)
		{
			CharacterState = ECharStates::CS_Default;
			float HalfHeight = CapsuleComponent->GetScaledCapsuleHalfHeight() * 2;
			CrouchMulticast(false, HalfHeight);
		}
		else
		{
			CrouchRequestRPC(false);
		}
	}
}

void ATPSGameCharacter::CrouchRequestRPC_Implementation(bool bCrouchStart)
{
	if (bCrouchStart) CrouchPressed();
	else CrouchReleased();
}

void ATPSGameCharacter::CrouchMulticast_Implementation(bool bCrouchStart, float HalfHeight)
{
	if (bCrouchStart)
	{
		Mesh->AddLocalTransform(FTransform(FVector(0, 0, HalfHeight / 2)));
		CameraBoom->AddLocalTransform(FTransform(FVector(0, 0, HalfHeight / 2)));
		CapsuleComponent->SetCapsuleHalfHeight(HalfHeight / 2);
	}
	else
	{
		Mesh->AddLocalTransform(FTransform(FVector(0, 0, -HalfHeight / 2)));
		CameraBoom->AddLocalTransform(FTransform(FVector(0, 0, -HalfHeight / 2)));
		CapsuleComponent->SetCapsuleHalfHeight(HalfHeight);
	}
}

Hey Elathan,

Welcome to the nightmare of the network realm :-))

I’m no pro so take it for what it’s worth, but from my little experience, i have learnt not to trust multicast rpc. Plus, i have read (can’t find where) that they are not meant to be reliable and hence should be used only for cosmetic purposes in your game (visual effects, etc.)

Maybe you could try to make the CharacterState a replicating variable with notification (ReplicatingUsing = OnRep_CharacterState), and put your modifications in the OnRep_CharacterState() function.

Cheers

Cedric

Hi,

Thank you for your tip.
I implemented the same logic using the notification mechanism you mentioned. Unfortunately the result is the same.
CapsuleComponent->SetCapsuleHalfHeight(HalfHeight / 2) 's effect is displayed in the screen but the mesh is not translated.

Try to modify the UStaticMeshComponent only on the server, and set it to replicate in the constructor of the actor, something like:
MyMeshComponent->SetIsReplicated(true);

With a bit of luck, you don’t need all this mechanism, you just need to replicate your components and modify them on the server only. Maybe it works for the capsule because it is natively replicated ?

Just an idea.

It is the character’s default skeletalmesh.
I added “Mesh->SetIsReplicated(true);” to the constructor and moved the mesh translation to the server code part.
The result is the same.

Test with only a client and a server:

Client character uses crouch: okay

Server character uses crouch:
okay on server’s viewport, mesh isn’t translated on client’s viewport.

Thanks,

Elathan

Hey Elathan-

Could you post a short video of your crouch animation playing to help give an idea of what exactly is happening? Additionally can you post the header file so that we may see how the different variables are declared to help us reproduce what you’re seeing?

Cheers

Doug Wilson

Hello,

I created a test project from the tps template:
https://www.cubbyusercontent.com/pli/testproj.zip/_75e217c07abd4e5991cabbc139d2e94f

Here is a video too.

It is not like the code written above, I used the method mentioned by uced (replication notification). The issue is the same.

Thanks,

Elathan

Hello,

Any progress?

Thanks,

Elathan

Hey Elathan-

I’m actually testing the sample project you submitted at the moment to try to understand what exactly is happening. Just so I understand the problem you’re having is the capsule half height updating properly but the character mesh “sinking” into the ground, is that correct?

Hey Elathan-

In the character blueprint you can set the Can Crouch boolean of the Character Movement component to true. If you do you can then call the Crouch() and UnCrouch() functions inside CrouchPressed() or CrouchReleased() respectively. You can find more information on the built in crouch functions Crouch() and UnCrouch() here: ACharacter::Crouch | Unreal Engine Documentation

Cheers

Doug Wilson

Yes.
It’s strange because both function call is executed locally. The one on the capsule works everywhere, translating the mesh does not.
I see that I could use the built in crouch, but now I am curious.
What is the problem with the mesh translation?

Since the mesh is a child to the capsule component it is using that relationship for the AddLocalTransform call. I was having similar behavior when trying to do the same thing in blueprint.