Back with another Multiplayer!
- Adam House
- 1 day ago
- 8 min read
Type: Practise project.
Genre: First person shooter and Multiplayer.
Engine: Unity. Key Roles: Programming and some Game design.
Released: 20/12/2025.
Last updated: 20/12/2025.
Learned from: Create Your First RPG And FPS Multiplayer Game in Unity by Awesometuts (Fahir) from Udemy. Made by: Only myself, though the assets were provided to me by the instructor.
Finishing of this busy year is a Multiplayer practice project I was originally going to do first before the Battle Royale Prototype, but the instructor did not have the available videos to help me finish this project myself. I than decided to learn the Battle Royale prototype and use what I learned to finish this project once and for all. Am I satisfied with the multiplayer mechanics that I learned? Found out below….
Some Fps mechanics are similar or just about the same I learned before, so I will only cover new skills and techniques I learned to keep this post mortem short. Should you want to see what I learned from my earlier projects like “Survival shooter”, ”Punk-ass 3000”, ”Into the Darkness”, “Humanoid animation control”, and last but not least “Battle Royale Prototype”, you can see what I learned from them on my portfolio site.
I originally started this project to research how different fps mechanics are made. I decided to warm up my game design skills by assigning each gun different fire rates and damage. More info on WHAT WENT WELL?
The rules of the game are simple, the two Players must find and kill each other, the last one alive wins the game. Players have 3 guns they can select at a time ready at their disposal each with its strengths and weaknesses. There is no respawns or rounds since it would be complex for me for this prototype.
WHAT WENT WELL?:
• As mentioned above, I used what I learned from Battle Royale Prototype.
- Determined which type of weapon the Player holds can be a Pistol (Deagle) or rifle (machine guns) in the Animator controller and show the weapon the Player is currently using.
- Made each gun have a different fire rate and damage to work through the network when the Player fires the equipped weapon.
Deagle Pistol: slow fire rate, but high damage.
AK-47 Machine gun: medium(ish) fire rate, but medium damage.
M4A1 Pistol: high fire rate, but low damage
- I made the Player that died to switch cameras showing the entire map before destroying the Player itself by setting active on the game object (camera) without affecting the other Player by using a Command.
- Used Commands and RPCs to instantiate the muzzle flash for all 3 Player's guns and set it as a child object under each Player's gun parent.
- Made the wall (Player shot at building) and blood particles (Shot at Player) instantiate in the server so all Players can see.
- Made the local Player see the text of which gun their currently equipped displaying their ammo, and magazine size of each gun.
- Player can reload gun to a full magazine only if the clip is less than the Magazine.
- Made almost all the networking mechanics in one script, some do have their own network scripts.
- Made sure the Character animations don't play twice.
- Made gun shots heard by all Players through commands and RPCs, though the reload sounds only can be heard by the local Player, not in the server so all Players can hear it.
- I did the best I can to make sure each of the Player's guns fit in their characters hands so clients can see.
• Made the shooting controls as tight as I can so they reduce the chances of being broken by using some if statements, bools, methods, and enums.
WHAT I LEARNED:
–Player–
• Used an if statement to determine if the Player moves forward or backward by either the W or S inputs, the same is done for Left(A) or Right (D) for a separate if statement.
• Made the Player lerp with Inputs with X and Y from values 0-2 with Time.deltatime which is similar to the Get axis raw. If 0, The Player does not move at all.
• Used an advanced if statement to make the Player not speed up when going diagonally while smoothing its movement.
• Used CollisionFlags to check if the Player is grounded.
- CollisionFlags.Below means it's grounded.
- If not equal to 0, it is true which means we are grounded.
- If it is equal to 1, it is false and we are midair.
- Collisionflags gives you a broad overview of where your character collided with any other objects, for e.g did your character controller collide by the side? above ceiling, or below ground?
• Used a float which is the antibump factor to smooth Player landing while assigning them with new X and Y values when grounded.
• Used bools to determine which keys the Player is pressing: inputX and inputY.
• Used one script “FPSMouseLook” that also controls the Players fps camera on two child gameobjects with each an enum.
- Mouse X on Player parent: Allows the Player to rotate the Player character and camera horizontally within its clamped values. It rotates the Player character model on the Y axis using x rotation while using a Quaternion with local rotation.
- Mouse Y: Allows the camera to be rotated vertically and horizontally within the clamped values. It also rotates using a Quaternion with local rotation.
• Uses TransformDirection for the Players vector3 movement times with speed from local space to world space.
• To make character model and Players arms in the first-person view animate at the same time for StandShoot, crouchShoot, and reloading guns in state machines.
• Used Vector3.lerp for smooth rotation of the Player camera while also using LocalEulerAngles.
• Set a mouse sensitivity default setting in an if statement to make sure the Mouse X and Y does not have the same value as a precaution.
• Adjusts the Ray distance and gets of half the height of character controller and radius in Start function to prepare it for Player crouching.
• Auto sets the default height of the character controller and default camera position.
• Can Change Player Colours RGB within an array each with 4 int values.
• Able to change Player's character model equipped weapon and FPS hands equipped weapon at the same time from 2 separate arrays. It also clears the selection first before changing to the next equipped weapon so 2 Players hands and 2 character model guns don't appear at the same time. Only keys 1,2,3 are activated to select one equipped weapon at a time.
–Multiplayer–
• Made an if statement each for Local and Client Player that will execute depending on which out of these two is the Player.
LocalPLayer gets...
- Players character model with its child gameobjects is tagged “Player” in a foreach loop which means Local Player won't see his/her character model, but other clients will.
- Changes the Local Players guns from his/her character model to “Player” while using a for loop so clients can see what gun the Local Player is using while he/she can't see it.
- Changes the FPS guns and its child components tag to “Enemy” so the Local Player can see his/her hands carrying the selected equipped gun while the clients won't see it.
!LocalPLayer (Client) gets...
- Client Players character model with its child gameobjects is tagged “Enemy” in a foreach loop which means the Client Player won't see his/her character model, but other clients will.
- Changes the Client Players guns from his/her character model to “Enemy” while using a for loop so other clients can see what gun the Client Player is using while he/she cant see it.
- Changes the FPS guns and its child components tag to “Player” so the Client Player can see his/her hands carrying the selected equipped gun, but the other clients won't see it.
• Able to override on Start for Local player for their tag to be changed as “Player”.
• A little more detail of using Commands
- Command is an attribute that can be put on methods for network behaviour class's that can be invoked on the server by sending a command from a client.
- These functions need to have Cmd short for command in front of the function.
- Commands are called on the server to send info to all clients. - Cmd is a suffix.
–Other–
• Rigidbodys apply gravity straight away, unlike character controllers which need to be programmed.
• Update is one of those functions that doesn't return a value.
WHAT WENT WRONG, COULD I HAVE DONE BETTER?
• The bullet holes from gun shots don't always face where they were shot. The map is complicated when almost all of its mesh is one game object, I decided not to worry about it for now since I want to focus on mostly the Multiplayer mechanics. I will look on my notes on how to normalise bullet holes on objects properly for next time.
• I could have made the Player reload automatically once their clip reaches 0, but I wanted to focus on the complex Multiplayer mechanics and not accidentally break code, so there's always a next time to implement that reload mechanic.
• I could have given a health bar or text and damage screen UI to each of the Players, so they know their health and if damaged by another Player, but it ended up being a little tricky for a Multiplayer. I have decided that making Multiplayer games isn't my first type of product for the market, so I only focused on mechanics that not only I can easily implement, but also to make the game playable and to keep the gameplay loop going until one of the Player characters die.
• I get an error whenever one of the Player characters die due something to do with executing a code that does not exist, possibly referring to the code of the Player gameobject that's destroyed, normally I don't like errors in my games, but I decided to let it go since it is a mild error, not a game-breaking bug and only a prototype, not a commercial game.
• Syncing the Player character crouch shooting from both shooting guns may not be what I expected since the machine gun goes straight down after each shot, next time I will make sure the character points the gun towards its target rather than aiming down.
• Like I mentioned in Battle Royale Prototype, I wish the Players characters hands move to where he/she is aiming that we can see. But unfortunately, I haven't been taught to do that yet.
• Next time I should not have OBS shown while screen recording.
OVERALL:
Despite all this trouble, I still have decided that I won't make multiplayer games early in my game dev journey, I will be sticking to making fps single player games instead.
Though this project really demonstrated my skills to finish the project on my own which I am very proud of.
I am happy to not only finish this project, but also learned to make similar fps mechanics for my future games, as much as I learned some similar multiplayer mechanics, I am still not satisfied with what I learned and may learn more of these complex mechanics when the time comes or hire a programmer to develop those mechanics for me.
My skills will be ready when the time comes to include multiplayer.


Comments