Ok, so am going to assume that you know how to create a new project with the FPS template to start with. Am going to be using the 4.13.2 version of the engine, but i think this will be basic enough to try it in other recent versions.
Now lets setup the editor into multiplayer mode, this is achieve by opening the options of the Play Button on the top toolbar. Change the number of players at the bottom of the list to 2 and launch the game in a New Editor Window fashion.
You can also access the advanced settings at the bottom of the same list and change the size of the new players windows to your liking.
Each window will have the name of the instanced players, check that one is created for the listen server and the other for the client 1.
Form here we can notice some things happening, for once we can see the players move around the map and that they can see each other, but nothing else that we perform is noticed neither by the server or the client side.
So why is that? That is because default multiplayer mode on UE4 will show to every connected client all the actor first spawned by the server, and that means the FPS characters possessed by each client (client and server in this case) as well every box, walls, floor, sky, lights, etc.
The movement we see form each character is being Replicated because by default the movement of the FirstPersonCharacter blueprints are set to do so. You can check this by opening the FirstPersonCharacter blueprint and filter the details window with the word “Replication”.
This is crucial for the server to know that we want to inform other clients that the movement of this character is relevant to be replicated to other connecting clients. All Actors on the map have this checkbox, also the components inside but we will talk about components later.
So, whats up with the projectiles? Why can´t i see them spawning other that in the own player window? Well that should be easy now that we know about the Replicates checkbox.
Open the FirstPersonProjectile blueprint and check the Replicates on and fire up the game again.
Something very strange happens, the client can see the projectiles form the server side as well as the impulse generated on the boxes, but the server cant see the projectiles from the client, nor any interaction of the client projectiles on the boxes. This is working as spected, as the server can spawn new actor in game, and as it is the server those actors interactions will be replicated to other clients. But now the client is not informing that he is performing an action like spawning projectiles.
Even when the client FirstPersonBlueprint was spawned by the server, new actors spawned form this blueprint are not necessarily replicated by default. The blueprint acts only on its realm unless we use a Remote Procedure call.
And that is what we are going to do next.
First we need to separate what is going to be needed to be spawned by the server and what is relevant to be shared to other clients. We need for sure to let the server do the spawn of the projectile because only the server can spawn actors relevant to connected clients. Then we need to inform other players of the sound and animations generated by that firing to other players around.
Lets first spawn the projectile.
When i talk about a server spawning doesn’t means that we need another server side blueprint, nor communication between different blueprints. You will see that being a server is not an entity, nor a place or process alone, is a authority thing. There will be places in our blueprint that will have the authority to act like a server while the rest will just act as a single player blueprint.
Lets see this graphically.
Open the FirstPersonCharacter blueprint and look for the “Spawn projectile” section on the event graph. Set aside the animation montage and the play sound from the actual spawning, if you will you can strip the vr and mobile support nodes and give yourselves some work space.
Ok, we need to first add a custom event, name it RPC Fire, and set in its properties to replicate “Run on Server” and check the Reliable box.
Now connect it to the SpawnActorFirstPersonProjectile, and summon that custom event from the InputActionFire.
Play the game now and you will see the client firing projectiles on the server side window.
Now lets inform the other clients that the blueprint is running some animations and sounds.
We will add a new Custom Event, lets call it “Multicast Fire” and set the replication on this custom event to “Multicast” then lets connect it to the Montage Play line of our blueprint. We need to summon this event from the server side, because the server is the only one that can fire multicast events. So in this case we need to summon it after the RPC Fire event we created earlier.
If you play the game now you will see the animations playing correctly on both windows.
We are getting nearer, but further testing of the game will show you that the client is not informing about the pitch of the weapon and consequentially all projectiles are spawned pointing forward.
This is expected too, the server spawned the FirstPersonCharacter blueprint with the weapon pointing forward and it assumes that it hasn’t change it position even if you change it on the client. Now lets replicate some variables.
Create a variable called “WeaponPitch” and assign a rotator type to it, change the Replication select box from None to Replicated.
Now we need to set the value of the World rotation of the First Person Camera to this new Variable but at the server level, this can be achieved by passing the value of the rotation of the camera to the RPC Fire custom event and then pass it to the Multicast Fire event. Do this by creating a parameter in both events of the type rotator. After we pass the value through both events we will set the value to the new created variable. Lastly we will get the value of the variable connecting it to the required nodes.
Now when playing the game you will see the projectiles spawning in the right direction, we are getting closer but no candy. The weapon itself is not showing any pitch on other clients or server. We need another event that fires up every time we change the pitch of the weapon.
From now on we are into optimization territory. Many of us would be happy with how this is working, the projectiles are working ok and are firing correctly out of the weapon. Depending on the number of players and other things that may still need to be replicated, like health and hits for example, we may be tempted to leave the characters not replicating every move. Still am going to go the whole way and show you how to replicate the movement of the weapon itself.
For this we need to hack a lil bit more the FirstPersonCharacter, that is because we need to unparent the arms mesh from the FirstPersonCamera and drive it from the movement of the camera on the blueprint. Also we need to create a scene component with the same position of the camera and parent the arms mesh to it. That way when we tell it to move like the camera it will move from the same pivot of the camera.
The blueprint itself change a little bit from the one we had, as we will update the WeaponPitch variable everytime we change the pitch of the weapon, not only when we fire. But be aware that his will add more to the net load.
The way to handle this is the same as we did before lets look at it.
Note that we are only feeding the pitch to the Weapon Pivot scene component that we created and using a Set Relative Rotation node because the rest of the rotation will still be drive by the capsule.
Now Play the game to see the weapon on each player updating ok on the rest of the clients. If you want to see the arms of the characters on the clients just search for “only owner see” on the details window of the Mesh2P component of the FirstPersonCharacter and check off that property.
Last but not least we have one last problem of replication. This one is very important to use sporadically and only on simulating environment that MUST replicate on all the clients connected. If you check the simulation of the boxes on all clients you will see that sometimes they become unsynchronized. This happens because even when the projectiles are being replicated the simulations are running separately on each client. This different evaluations by different clients with different graphic loads will make impossible to generate the same responses on environment simulations.
But some game mechanics may need to update rigorous simulations on all clients, like for example if a simulated rock should crush a character or something.
Lets create a new blueprint throw in a cube from the content browser. The blueprint should look something like this but beware that you will need to find better ways of updating its position to the other players.
There you are, if you replace all the boxes with this blueprint actor everything inside the FPS Template will replicate on every player that connects to the server.
Have fun!