Moving forward: Enhancing the Multiplayer Shooter Game

Moving forward: Enhancing the Multiplayer Shooter Game

New features including reloading, respawning and more ...

·

4 min read

With the foundations laid by implementing networking and player movement through Photon and Unity, the next step is adding more features to the game. Let's take a closer look at the recent additions.

New Features Added

Loading Screen

A loading screen has been added to provide players with visibility on the connection status when joining the game.

Weapon Implementation

A weapon has been introduced to the game to allow players to engage in some form of combat. For initial implementation, this is a free model from Sketchfab.

The Fire method is used for the weapon firing mechanic:

    void Fire()
    {
        Ray ray = new Ray(camera.transform.position, camera.transform.forward); 
        RaycastHit hit;
        if(Physics.Raycast(ray.origin, ray.direction, out hit, 100f))
        {
            PhotonNetwork.Instantiate(hitEffect.name, hit.point, Quaternion.identity);
            if(hit.transform.gameObject.GetComponent<Health>() != null)
            {
                hit.transform.gameObject.GetComponent<PhotonView>().RPC("TakeDamage", RpcTarget.All, damage);
            }
        }
    }

Shooting Animations

A shooting animation has been added so that when the player fires the weapon an animation plays. When shooting, the animation plays and the ammo decreases (in this case ammo is shown in the bottom right).

Reloading Mechanism

If the player presses the "R" key during the game, the weapon reloads. There is also a reloading animation created that plays. During reloading the shooting is disabled, the ammo increases.

The reload method handles the reloading mechanics, including updating ammo counts:

    void Reload()
    {
        animation.Play(reloadAnimation.name);
        if (magAmmo > 0)
        {
            mag--;
            ammo = magAmmo;
        }
        magText.text = mag.ToString();
        amoText.text = ammo + " / " + magAmmo;
    }

Respawning functionality

Originally, the player could not respawn in the game, however now respawning has been added when players reach zero health. Health starts at 100 and decreases based upon a damage amount taken during gameplay.

Player Health System

A health system has been implemented to monitor the players health status. When the player is hurt by another in the game, their health decreases.

Realm Switching

Due to the concept of the game being around the ability for players to travel between two separate realms, realm switching was implemented. During the game, players can press the "V" key to transform their position to the second realm. In this case, the second realm is just a second plane in Unity. It should become invisible or visible based on what realm the player is located in.

This is the script created for switching realms:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Photon.Pun;

public class MoveOnKeyPress : MonoBehaviourPun
{
    public float yoffset = 52f;
    public float doffset = 50f;
    private bool inFirstRealm = true; //Have a bool to check if we are in the second realm or not

    void Update()
    {
        //If we are in the second realm, we can't go back to the first realm
        if (photonView.IsMine)
        {
            if (Input.GetKeyDown(KeyCode.V))
            {
                if (inFirstRealm)
                {
                    photonView.RPC("Move", RpcTarget.AllBuffered, yoffset);
                }
                else
                {
                    photonView.RPC("MoveDown", RpcTarget.AllBuffered, doffset);
                }
            }
        }
    }

    [PunRPC]
    void Move(float yoffset)
    {
        Vector3 curerntPos = transform.position;
        curerntPos.y += yoffset;
        transform.position = curerntPos;
        inFirstRealm = false; //If we are in the second realm, set the bool to true
    }
    [PunRPC]
    void MoveDown(float doffset)
    {
        Vector3 curerntPos = transform.position;
        curerntPos.y -= doffset;
        transform.position = curerntPos;
        inFirstRealm = true; //If we are in the first realm, set the bool to false
    }
}

How it works:

  • Upon pressing the "V" key, the script checks if the player is in the first realm or not.

  • If in the first realm, an RPC (Remote Procedure Call) is used to move the players position to the second realm using the move method.

  • If in the second realm, another RPC is invoked to move the player back down to the first realm using the moveDown method.

💡
Note: In the future, additional logic will be added to control the visibility of each realm. For example using Unity's GameObject activation/deactivation settings to make the second realm visible or invisible based on the player‘s current realm.

Weapon Movement

A slight weapon sway has been incorporated to simulate realistic movement in the game. This is the WeaponSway script that was added:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class WeaponSway : MonoBehaviour
{
    public float swayClamp = 0.09f;
    public float smoothing = 3.0f;
    private Vector3 origin;

    void Start()
    {
        origin = transform.localPosition;     
    }
    void Update()
    {
        Vector2 input = new Vector2(Input.GetAxisRaw("Mouse X"), Input.GetAxisRaw("Mouse Y"));
        input.x = Mathf.Clamp(input.x, -swayClamp, swayClamp);
        input.y = Mathf.Clamp(input.y, -swayClamp, swayClamp);
        Vector3 target = new Vector3(-input.x, -input.y, 0);
        transform.localPosition = Vector3.Lerp(transform.localPosition, target + origin, Time.deltaTime * smoothing);     
    }
}

Summary of the variables used:

  • swayClamp defines the maximum amount of sway allowed in any direction.

  • smoothing - controls the rate at which the weapon returns to its original position.

  • origin - stores the original position of the weapon at the start of the game.

Source Control

This code has been kept up-to-date using GitHub. The full code can be found here.

Acknowledgements

Special thanks to Lakshya Tyagi for the creation of the map, which will be implemented in future updates.

Thanks for reading this article!

Molly

Did you find this article valuable?

Support Molly by becoming a sponsor. Any amount is appreciated!