---
# System prepended metadata

title: GAMEPLAY DOCUMENTATION
tags: [Documentation, ReptileMultiplayer]

---

---
title: 'GAMEPLAY DOCUMENTATION'
disqus: lucas cavataio
---

<style>
.markdown-body img[src$=".png"] {background-color:transparent;}

.alert-info.lecture,
.alert-success.lecture,
.alert-warning.lecture,
.alert-danger.lecture {
  box-shadow:0 0 0 .5em rgba(64, 96, 85, 0.4); margin-top:20px;margin-bottom:20px;
  position:relative;
  ddisplay:none;
}

.alert-info.lecture:before,
.alert-success.lecture:before,
.alert-warning.lecture:before,
.alert-danger.lecture:before {
  content:"👨‍🏫\A"; white-space:pre-line;
  display:block;margin-bottom:.5em;
  /*position:absolute; right:0; top:0;
  margin:3px;margin-right:7px;*/
}
</style>

GAMEPLAY FEATURES
===

:::success
## DOCUMENTATION INDEX

### Reptile Multiplayer Documentation

- PROJECT SETUP: [**GO TO PROJECT SETUP**](https://hackmd.io/@ReptileMultiplayerDocumentation/rkyWOa10n)
- MASTER, NETWORK AND STEAM: [**GO TO MASTER MASTER, NETWORK AND STEAM**](https://hackmd.io/@ReptileMultiplayerDocumentation/B1WzLoPph)
- MENU DOCUMENTATION: [**GO TO MENU DOCUMENTATION**](https://hackmd.io/@ReptileMultiplayerDocumentation/SJncKmApn)
- GAMEPLAY DOCUMENTATION: **YOU ARE HERE**
:::

# CONTENT

[TOC]

# OVERVIEW

## Overview

This comprehensive guide is designed to help you understand the various gameplay features and components of the Reptile Multiplayer Solution.

### Spawning Players

In this section, you will learn about the **player** **spawning** **process** in the Reptile Multiplayer Solution. This process covers both **single-player** and **split-screen player instantiation**, **camera** **configurations**, **controller** **assignments**, and **more**. Whether you are implementing **online** or **test mode**, this documentation provides insights into the spawning mechanism.

### Player Controller Setup

To ensure a smooth multiplayer experience, it's essential to set up **player** **controllers** correctly. This section provides guidance on **deactivating** **specific** **components** in the **character** **controller** based on whether the **PhotonView** is owned by the player. Proper configuration ensures that player input and camera control are managed seamlessly.

### Game Manager

The **Game Manager** plays a crucial role in **managing** **game states**, **transitions**, and **ending a match**. You will discover how to use the Game Manager script to conclude a game, **destroy networked objects**, and transition to the lobby scene. Additionally, this section offers insights into **maintaining** a **persistent matchmaking** room for a smooth multiplayer experience.

Please refer to the respective sections for in-depth information on each topic. If you are working on implementing gameplay features in your multiplayer game, this documentation will serve as a valuable resource.

::: info
This documentation is designed to help you understand the components and functionality of the Reptile Multiplayer Solution fully. If you have any questions or need further assistance, please email at: [**lucascavataio@gmail.com**](mailto:lucascavataio@gmail.com).
:::

# SPAWNING PLAYERS

For the demo of this template, I have created a simple PlayerSpawner.

## Player Instantiation Process

1. **Spawn Trigger**: The spawning process is triggered either in the `Update()` method for online mode or in test mode, based on the value of the `testMode` field.

2. **Spawn Players**: When the spawning process is triggered, the `SpawnPlayers()` method is called. This method determines whether to create a single player or multiple split-screen players based on the `LocalPlayerManager`.

```csharp=
public void SpawnPlayers()
{
    if (LocalPlayerManager.Instance == null || !LocalPlayerManager.Instance.enableSplitScreen)
    {
        CreatePlayer();
    }
    else
    {
        for (int i = 0; i < LocalPlayerManager.Instance.numberOfSplitScreenPlayersToSpawn; i++)
        {
            CreateSplitScreenPlayer();
            Debug.Log("CreateSplitScreenPlayer();");
        }
    }
}
```

3. **Create Player**: In the `CreatePlayer()` method, the player spawner instantiates a player GameObject at a specified spawn point. It first checks if a `spawnArea` is defined, and if not, it logs a warning. It then retrieves the spawn point and uses Photon's `PhotonNetwork.Instantiate` method to create the player GameObject from the specified prefab.

### SplitScreen Player Spawn

Only if split-screen mode is enabled (determined by `LocalPlayerManager.Instance.enableSplitScreen`).

4. **Create Split-Screen Players**: If split-screen mode is enabled, the player spawner can create multiple split-screen players using the `CreateSplitScreenPlayer()` method. This method essentially calls `CreatePlayer()` internally and then adds the player to the `LocalPlayerManager` for further management.

5. **Camera and Layer Configuration**: The `CreatePlayer()` method sets up the initial properties of the player GameObject. It determines the spawn point, instantiates the player, and places them in the game world. Additionally, it handles camera configurations and layer assignments to ensure the new player is properly integrated into the game environment.

6. **Controller Assignment**: After a player is created, the `AssignControllersToPlayers()` method is called, which assigns controllers to players based on available input devices. This ensures that players have control over their respective characters.

7. **Split-Screen Configuration**: If split-screen mode is enabled, the `splitScreenCameraManager` is used to configure split-screen views for the players.

8. **Logging and Debugging**: Throughout this process, the player spawner logs warnings and debug messages to provide feedback and information about the spawning process.

9. **Completion**: Once the players are spawned, the `myPlayerWasSpawned` flag is set to indicate that player spawning is complete.

## Player controller setup

Make sure that your character controller **deactivates** the following **components** in the '**Start**' **method** if the **PhotonView** is **not** **mine**:
:::info
Example:
```csharp=
if (!PV.IsMine)
{
    _playerInput.enabled = false;
    _mainCamera.SetActive(false);
    playerFollowCamera.SetActive(false);
    playerHudManager.gameObject.SetActive(false);
}
```
:::

* **PlayerInput**: 

![](https://hackmd.io/_uploads/ByZueaZ16.png)

* **Camera Object**: 

![](https://hackmd.io/_uploads/Hy9igaZJT.png)

* **CinemachineVirtualCamera Object**: 

![](https://hackmd.io/_uploads/r100g6b16.png)

* **CinemachineVirtualCamera.Follow Object**: 

![](https://hackmd.io/_uploads/r1LZZTbJa.png)

![](https://hackmd.io/_uploads/Sy77ZTZ16.png)

# GAME MANAGER

I've also created a simple **GameManager** script so you can know how to end a game and have a **persistent** **matchmaking** room.

## End Match

The process of finishing the game involves calling the EndMatch() method, which is typically initiated by the master client. Once the match is ended, networked objects are destroyed, and the game transitions to the lobby scene.

```csharp=
public void EndMatch()
{
    if (!PhotonNetwork.IsMasterClient) return;

    if (endingMatch) return; // Prevent ending the match if it's already in progress.

    // Update the room status and set custom properties.
    PhotonNetwork.CurrentRoom.CustomProperties[ReptileRoomPropertiesKeys.STATUS_KEY] = ReptileRoomPropertiesValues.ROOM_STATUS_INLOBBY;
    PhotonNetwork.CurrentRoom.SetCustomProperties(PhotonNetwork.CurrentRoom.CustomProperties);

    PhotonNetwork.DestroyAll();

    // Load the lobby level to transition after match ends.
    int levelIDToLoad = (int)ReptileIndexes.LevelsIndexes.LOBBY;
    PhotonNetwork.LoadLevel(levelIDToLoad);

    endingMatch = true; // Set the flag to prevent re-triggering the match ending.
}
```

:::info
Example:

```csharp!
using Reptile.Managers;
using StarterAssets;
using UnityEngine;

namespace Reptile
{
    public class EndGameButton : MonoBehaviour
    {
        void EndGame()
        {
            ReptileGameManager.Instance.EndMatch();
        }

        private void OnTriggerStay(Collider other)
        {
            StarterAssetsInputs player = other.GetComponent<StarterAssetsInputs>();

            if (player == null) return;

            if (player.interact)
            {
                Cursor.lockState = CursorLockMode.None;

                EndGame();
            }
        }
    }
}
```

Please note that **specific** **game** **logic**, such as determining **win/loss** conditions or handling **end-of-match scoring**, should be **implemented** **separately** and may **require** **additional** **customization** based on your **game's** **requirements**.

:::





