Greetings everyone,
It’s the first time I ever post on Unreal Engine Forums so maybe I should have made a question post instead of a discussion one however I thought it fitted better since it’s not really a single question.
I come here today because I struggle to understand how network works in general and more specifically on Unreal Engine. I already use Neukirchen compendium and WizardCell site but it seems already awfully advanced without going into practical examples so I’m not sure if I understand everything correctly. That’s why I’m here.
I’m doing a test project to learn and apply what I learn immediatly. For now I managed to make a custom Online subsystem to create a session (listen server) or to join one as well as a BP lobby system with passwords that you can either create or join thanks to the subsystem.
Once created or joined the players receive a pawn given by the engine through the GameMode.
As you can see both players are the authority on the server player. I don’t know if this normal ? However the second player can control his character without problem. On the client side, his character is autonomous proxy while the server character is in simulated proxy.
I’m trying to make them shoot projectiles. They are not trace projectiles so they are actors spawned. So I use a server RPC to call a SpawnProjectile function. The problem is it moves smoothly on the server side but its movement is a little sketchy on the client side. It’s like it’s “vibrating” or glitching a little and sometimes even rollback. So I thought of spawning a non replicated projectile on the client side and another on the server side. That way each one will see only the one on their computer and there should be no lag or rollback I think.
void ATestCharacterMP::Fire(const FInputActionValue& _value)
{
const FVector _loc = GetActorLocation() + GetActorForwardVector() * 100;
const FRotator _rot = GetActorRotation();
ReliableServerSpawnProjectile(_loc, _rot);
}
void ATestCharacterMP::ReliableClientSpawnProjectile_Implementation(const FVector& _loc, const FRotator& _rot)
{
SpawnProjectile(bulletToSpawnClient, _loc, _rot);
}
void ATestCharacterMP::ReliableServerSpawnProjectile_Implementation(const FVector& _loc, const FRotator& _rot)
{
ReliableClientSpawnProjectile(_loc, _rot);
}
void ATestCharacterMP::SpawnProjectile(TSubclassOf<AProjectile> _projectile, const FVector& _loc, const FRotator& _rot)
{
AActor* _actor = GetWorld()->SpawnActor<AProjectile>(_projectile, _loc, _rot);
}
The problem is, how do I ensure that the server only spawn one and that each client spawn their own ? I thought of making a Fire function on the character that call a server RPCthat receive the location and rotation of the firing pawn among the list of players then call a Client RPC (not multicast) that will receive the coordinates that will spawn the projectile on every client in theory. The problem is that there will be lag between the fire command and the spawn of the bullet for the client. The thing is, how can I spawn locally the bullet and then make my server spawn it on all other client but this one ? Is there a way to filter client ? I thought of using the netID but then I run into how to use it to apply said filter.
Another question I have is, how do I truly differenciate between client and server in this situation ? As you saw both characters have authority it seems, so I cannot make them act or not through this method (HasAuthority).