---
# System prepended metadata

title: MENU DOCUMENTATION
tags: [Documentation, ReptileMultiplayer]

---

---
title: 'MENU 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>

MENU DOCUMENTATION
===

:::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: **YOU ARE HERE**
- GAMEPLAY DOCUMENTATION: [**GO TO GAMEPLAY DOCUMENTATION**](https://hackmd.io/@ReptileMultiplayerDocumentation/rJxH4yz0h)
:::
---

# CONTENT

[TOC]

---

## OVERVIEW

In this section, we'll explore the main menu user interface and scripting flow in Reptile Multiplayer. You'll find information on managing menus, handling room interactions, and scripting flows for various components.

### Main Menu UI

The **MenuUIManager** is responsible for managing the main menu's user interface. It handles menu creation, opening/closing, and user interactions.

- **Create New Menu**: Learn how to create a new menu and integrate it with the MenuUIManager.

- **Open/Close Menu**: Understand how to open and close menus programmatically.

- **Loading Menu**: Explore how to display loading menus with custom descriptions.

### Room UI Manager

The **RoomUIManager** manages UI elements specific to the game room in the lobby. It handles player lists, room information, countdowns, and master client interactions.

- **Static Instance**: Get details about the RoomUIManager's static instance for easy access.

- **Player List UI**: Learn about the player list UI and its components.

- **ROOM UI**: Understand the room-related UI elements.

- **Awake() and Update()**: Explore the initialization and update functions.

- **CleanPlayerList() and HandleRoomInfoText()**: Discover methods for managing player lists and room info.

- **HandleMasterClientButtons()**: Learn how master client buttons are managed.

- **Matchmaking and CustomGame**: Understand regions related to matchmaking and custom games.

- **UIButtonsMethods**: Explore methods triggered by UI buttons.

### Main Menu Scripting Flow

Visualize the scripting flow of the main menu components, including how they interact with each other.

### LAUNCHER

The **Launcher** class manages initialization, connections, room handling, and various networking events.

- **Static Instance**: Get details about the Launcher's static instance for easy access.

- **Initialization**: Explore the initialization process, including flags and options.

- **Awake() and Start()**: Understand the initialization and startup actions.

- **PlayOnline() and PlayOffline()**: Learn how online and offline modes are initiated.

- **LeaveRoom() and CreateLobbyRoom()**: Manage room joining and creation.

- **JoinMatchmaking() and JoinFriendRoom()**: Join matchmaking and friend's rooms.

- **DisconnectFromServer() and LoadLevel()**: Handle server disconnection and level loading.

- **OpenCustomGame() and OpenMatckmaking()**: Open custom games and matchmaking menus.

- **LeaveCustomGameRoom() and ResetJoiningStatus()**: Manage custom game rooms and joining status.

- **PunCallbacks and RoomHandler**: Explore methods and callbacks for network events.

- **ExitGame()**: Handle game application exit.

### Spawning Players Cells

Learn how to spawn player list cells in the lobby and update them across the network.

### Matchmaking

The **MatchmakingManager** class handles matchmaking and countdown before starting a match.

- **How to join**: Understand how to join matchmaking games.

- **Fields and Methods**: Explore the class's fields and methods for matchmaking management.

### Custom Game

The **CustomGameManager** class manages custom game settings and countdown.

- **Fields and Methods**: Learn about custom game management.

### Map View

Discover how the map view UI component displays map information.

### LOADING SCREEN

Learn about the loading screen in Reptile Multiplayer and how it manages loading times.

### ReptileLoadingScreenHandler Class
Explore the `ReptileLoadingScreenHandler` class responsible for handling the loading screen.

---

::: 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).
:::

# MAIN MENU UI

## Menu UI Manager

The **MenuUIManager** is responsible for managing the user interface (UI) menus in the game. 

It handles the opening and closing of various menus, including loading menu (not the LOADING SCREEN), friends menu, and error menus. This script provides easy access to UI interactions and menu control.

### Create New Menu

Create a new empty GameObject inside the MenuUIManager.

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

Add the component `ReptileMenu`.

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

Set the ID and if the menu has buttons, set the first one to select. This is for the gamepad input.

![](https://hackmd.io/_uploads/rktu-UoR2.png)

Add your new menu in the `Menus` List of the `MenuUIManager` of the MainSceneUI object.

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

In this case, the menu has ID 6 to match the position in the "Menus" List.

And now add the new menu ID in the `ReptileIndexes.MenuIndexes` enumerator.

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

Now you can access the `Menu` from code, like this:

```csharp= 
MenuUIManager.Instance.OpenMenu((int)ReptileIndexes.MenuIndexes.NEW_MENU);
```

### Open/Close Menu

OPEN MENU:

```csharp= 
MenuUIManager.Instance.OpenMenu((int)ReptileIndexes.MenuIndexes.NEW_MENU);
```

CLOSE MENU:

When you open a menu all open menus are closed, so it is not really necessary to close one to open another. But in case you need to close a specific one, you can do it this way:

```csharp= 
MenuUIManager.Instance.CloseMenu((int)ReptileIndexes.MenuIndexes.NEW_MENU);
```

### Loading Menu

When you open the loading menu, you need to set a description for that payload using this function of the MenuUIManager:

```csharp= 
public void SetLoadingDescription(string _description)
{
    loadingDescription.text = _description;
}
```

Example:

```csharp= 
// After disconnect attempt, open the loading menu to provide visual feedback to the user
// while the desconnection process is underway.
MenuUIManager.Instance.OpenMenu((int)ReptileIndexes.MenuIndexes.LOADING);
MenuUIManager.Instance.SetLoadingDescription(LoadingMessages.DisconnectingFromServer);
```


## Room UI Manager

The **RoomUIManager** is responsible for managing the user interface (UI) elements specific to the game room in the lobby. It handles various aspects of UI control, including player lists, room information, countdowns, and master client interactions.

#### Static Instance
- **Type**: `RoomUIManager`
- **Description**: The `RoomUIManager` includes a static instance, allowing other scripts to access its functionality without direct references.

#### Player List UI
- **Type**: `Transform`
- **Description**: The parent transform of the player list UI, which displays information about players in the current room.

#### ROOM UI
This section includes references to various UI elements related to the room:

- **roomInfoText**: Displays room information, such as the number of players.
- **matchmakingCountdownInfoText**: Displays matchmaking countdown information.
- **customGameCountdownInfoText**: Displays custom game countdown information.
- **localGameCountdownInfoText**: Displays local game countdown information.
- **masterClientButtons**: Buttons that are interactable only for the master client.

#### Awake()
- **Description**: Initializes the `RoomUIManager` instance, ensuring it is a singleton and can be accessed from other scripts. Destroys any duplicate instances.

#### Update()
- **Description**: Updates the visibility and content of UI elements based on the game's state. It manages player lists, room information, and master client button interactivity.

#### CleanPlayerList()
- **Description**: Clears the player list UI by destroying all player list cells.

#### HandleRoomInfoText()
- **Description**: Updates the room information text based on the current game state, including matchmaking and player counts.

#### HandleMasterClientButtons()
- **Description**: Manages the interactivity of master client-exclusive buttons based on the player's master client status.

#### Matchmaking
This region includes methods related to matchmaking UI:

- **UpdateSearchingPlayerCellsInList()**: Updates the list of searching player cells in the UI.
- **GetPlayerListCellsCount()**: Returns the count of player list cells.

#### CustomGame
This region can be used for custom game-related methods if needed in the future.

### UIButtonsMethods
This region contains methods triggered by UI button presses. These methods are responsible for various actions, including starting matchmaking, opening custom games, leaving lobbies, and more.

Example:

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

## Main Menu Scripting Flow

The scripting flow of the main menu components, and how they interact with each other.

```graphviz
digraph hierarchy {

                nodesep=1.0 // increases the separation between nodes

                node [color=Blue,fontname=Courier,shape=box] 
                edge [color=Red, style=dashed]

                ReptileNetwork->{Launcher}
                Launcher->{RoomManager MatchmakingManager CustomGameManager LocalGameManager}
                
}
```

# LAUNCHER

The **Launcher** class manages the initialization, connection, and room handling aspects of the Reptile Multiplayer Solution. It serves as the entry point for starting online and offline game modes, joining lobbies, creating rooms, and handling various networking events.

#### Static Instance
- **Type**: `Launcher`
- **Description**: The `Launcher` class includes a static instance, allowing other scripts to access its functionality without direct references.

#### Initialization
- **Pending Join Room After Leave**: A flag indicating if a room join attempt is pending after leaving.
- **Joining Friend**: A flag indicating if joining a friend's room is in progress.
- **Cached Joining Room Name**: The name of the room being joined, cached for rejoining after leaving.
- **Manual Disconnect**: A flag indicating manual disconnection.
- **Joining Matchmaking**: A flag indicating if matchmaking join attempt is in progress.

#### Awake()
- **Description**: Initializes the `Launcher` instance as a singleton and ensures there are no duplicate instances.

#### Start()
- **Description**: Determines the initial actions to take when the game starts. It checks if the player is in a room or connected to the network and opens the appropriate menu.

#### PlayOnline()
- **Description**: Initiates the process to play the game online. It checks if the Steam platform is initialized and opens the loading menu during the connection process.

#### PlayOffline()
- **Description**: Initiates the process to play the game offline. It checks if the Steam platform is initialized, sets the room type to local, and opens the local game menu.

#### LeaveRoom()
- **Description**: Leaves the current room and resets joining status flags, then opens the loading menu with a "Waiting for Server" message.

#### CreateLobbyRoom()
- **Description**: Creates a lobby room with specified options, including maximum players, visibility, and custom properties.

#### JoinMatchmaking()
- **Description**: Initiates the process to join a matchmaking game. It ensures that the player is the master client or delays joining for non-master clients.

#### JoinFriendRoom(string _roomName)
- **Description**: Joins a friend's room with the specified room name. It handles checks for existing room membership and online status.

#### JoinRoomAfterLeave(string _roomName, bool _isJoiningMatchmacking, bool _isJoiningFriend)
- **Description**: Initiates the room joining process after leaving a room. It sets joining status flags and opens the loading menu with an "Attempting to Join Room" message.

#### DisconnectFromServer()
- **Description**: Disconnects from the server, handling manual disconnection and cleaning the player list UI.

#### LoadLevel()
- **Description**: Loads the game level while setting room status and map properties.

#### OpenCustomGame()
- **Description**: Sets the room type to custom and opens the custom game menu.

#### OpenMatckmaking()
- **Description**: Opens the matchmaking menu and triggers an event to notify other players if the current player is the master client.

#### LeaveCustomGameRoom()
- **Description**: Handles leaving a custom game room by setting the room type to lobby and opening the lobby menu.

#### ResetJoiningStatus()
- **Description**: Resets the joining-related status flags.

#### PunCallbacks
This region includes methods that handle Photon callbacks related to network connection, room joining, disconnection, and room properties updates.

#### RoomHandler
This region includes methods for setting the room type and opening menus based on room properties.

#### IsJoiningMatchmaking()
- **Description**: Checks if a player is in the process of joining a matchmaking game.

#### ExitGame()
- **Description**: Exits the game application.

::: info
The `Launcher` class is responsible for orchestrating the game's network functionality, room creation, and connection processes. It ensures a smooth transition between online and offline modes and handles various network events. If you have any questions or need further assistance, please email at: [lucascavataio@gmail.com](mailto:lucascavataio@gmail.com).
:::

## Spawning Players Cells

To spawn a player list cell you must have an a prefab of this in the **GamePrefabs** scriptable object.

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

This prefab must contain a **PhotonView** and the **PlayerListCell** component

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

Use this to spawn the player list cell across the network:

``` C=
RoomManager.Instance.SpawnPlayerListItem();
```

### SpawnPlayerListItem Method

**Purpose**: Spawning a player list item in the UI for a player in the lobby.

**Parameters**:
- `bool _isSplitScreenPlayer`: A flag indicating whether the player is a split-screen player (default is `false`).

**Method Steps**:
1. Instantiate a `PlayerListCell` prefab from the game settings and attach it to the `player` variable.

3. Get the `PhotonView` component of the spawned player list item (`player`).

5. Update the `myPlayerItem` reference to point to the newly spawned player list item (`player`).

7. Generate the player's nickname based on whether they are a split-screen player or not. If it's a split-screen player, the nickname includes the player's name and an index based on the number of local split-screen players.

9. Reset the `PhotonView`'s ViewID to 0 and clean it locally if it's not already 0. A unique ViewID will be allocated in the next step.
10. Attempt to allocate a unique ViewID for the `PhotonView`. A ViewID is essential for network synchronization.

12. If ViewID allocation is successful, prepare data to be sent in a custom event. This data includes the ViewID, player nickname, Steam ID, and player level.

14. Set up the player list cell (`player`) with the specified information (nickname, Steam ID, and level).

16. Configure options for raising a custom event, specifying receivers, caching, and reliability.

18. Raise a custom event with the specified event code. This event informs other players in the room about the newly spawned player list item, ensuring proper synchronization.

**Error Handling**:
- If ViewID allocation fails, an error message is logged, indicating the failure, and the locally spawned player object (`player`) is destroyed to prevent synchronization issues.


# COMPONENTS

## Matchmaking

The `MatchmakingManager` class is responsible for managing the matchmaking process and countdown before starting a match.

### How to join

:::info

Use this method to join matchmaking:
```csharp= 
Launcher.Instance.JoinMatchmaking() 
```

This method also joins the same matchmaking for friends in the room.

:::

## Matchmaking Manager

This documentation provides an overview of the `MatchmakingManager` class, its methods, and its functionality. The `MatchmakingManager` is responsible for managing the matchmaking process in a game, including room creation, player joining, and countdown to start the match.

### Class Structure

The `MatchmakingManager` class is structured as follows:

```csharp
namespace Reptile.Managers
{
    public class MatchmakingManager : MonoBehaviourPunCallbacks, IMatchmakingCallbacks
    {
        // Class fields and properties
        // ...

        // Awake method
        private void Awake()
        {
            // ...
        }

        // Start method
        private void Start()
        {
            // ...
        }

        // Public methods
        public void SetupMatchmaking()
        {
            // ...
        }

        // ...

        // Private methods
        private void ResetMatchmakingStatus()
        {
            // ...
        }

        // ...

        private void StartMatch()
        {
            // ...
        }

        // ...

        // Join matchmaking
        public void JoinMatchmaking(string[] _expectedFriends = null)
        {
            // ...
        }

        // ...

        // PunCallbacks methods
        public override void OnPlayerEnteredRoom(Player newPlayer)
        {
            // ...
        }

        public override void OnPlayerLeftRoom(Player otherPlayer)
        {
            // ...
        }

        public override void OnJoinedRoom()
        {
            // ...
        }

        public override void OnLeftRoom()
        {
            // ...
        }

        // ...

        // Custom methods
        public bool IsInMatchmaking()
        {
            // ...
        }

        public int RequiredPlayersToStartMatch()
        {
            // ...
        }

        // Countdown methods
        public bool IsCountDownStarted()
        {
            // ...
        }

        private void SetStartTime()
        {
            // ...
        }

        public void SetStartTime(int _startTime)
        {
            // ...
        }
    }
}

```

### Overview

The `MatchmakingManager` class manages the matchmaking process in the game. It is responsible for creating or joining matchmaking rooms, handling player entries and exits, and initiating the countdown to start the match.

### Key Methods and Functions

1. **SetupMatchmaking()**: Sets up matchmaking based on game settings, including the number of players required to start a match.

2. **ResetMatchmakingStatus()**: Resets the matchmaking status and countdown timer.

3. **StartMatch()**: Starts the match if the current player is the master client.

4. **JoinMatchmaking(string[] _expectedFriends = null)**: Initiates the matchmaking process, allowing players to join with specified expected friends.

5. **JoinOrCreateMatchmakingRoom(string[] _expectedUsers)**: Joins or creates a matchmaking room with the given expected users.

6. **UpdateMatchmakingState()**: Updates the matchmaking state based on the number of players in the room.

7. **MatchmakingCoroutine()**: Main coroutine responsible for the countdown and state transitions.

8. **MatchmakingTextAnimationCoroutine()**: Coroutine for animating matchmaking countdown text.

9. **OnPlayerEnteredRoom(Player newPlayer)**: Callback when a new player enters the room.

10. **OnPlayerLeftRoom(Player otherPlayer)**: Callback when a player leaves the room.

11. **OnJoinedRoom()**: Callback when the local player joins the room.

12. **OnLeftRoom()**: Callback when the local player leaves the room.

13. **IsInMatchmaking()**: Checks if the player is currently in matchmaking.

14. **RequiredPlayersToStartMatch()**: Gets the number of players required to start the match.

15. **IsCountDownStarted()**: Checks if the countdown to start the match has started.

16. **SetStartTime()**: Sets the start time for the countdown and raises a custom event.

17. **SetStartTime(int _startTime)**: Sets the start time for the countdown based on the provided value.

### Usage

The `MatchmakingManager` class can be used to manage the matchmaking process in a game. It handles room creation, player joining, and countdown to start the match based on game settings and player interactions. You can call its methods to initiate matchmaking and manage the matchmaking state in your game.

Note: This documentation assumes familiarity with Photon Unity Networking (PUN) and certain game-specific terminology.


## Custom Game

The `CustomGameManager` class is responsible for managing custom game settings, including map selection, game mode selection, and starting the match countdown.

### Fields

- `ReptileIndexes.LevelsIndexes selectedMap`: The currently selected map.
- `ReptileIndexes.GameModeIndexes selectedGamemode`: The currently selected game mode.
- `TMP_Text countdownInfoText`: Text element to display the countdown information.
- `bool isCountdownStarted`: Flag to check if the countdown has started.
- `Coroutine countdownCoroutine`: Coroutine reference for the countdown.
- `float countdownTimer`: Countdown duration in seconds.

### Methods

#### `Awake()`

- **Description:** Initializes the class instance and ensures that there is only one `CustomGameManager` instance. Also resets the custom game status.

#### `Start()`

- **Description:** Initializes the `countdownInfoText` field when the game starts.

#### `Update()`

- **Description:** Updates the visibility of the countdown text based on whether the countdown is active.

#### `ChangeMap(ReptileIndexes.LevelsIndexes _newMap)`

- **Parameters:**
  - `_newMap`: The new map selection.

- **Description:** Changes the selected map and updates the room's custom properties.

#### `ChangeGameMode(ReptileIndexes.GameModeIndexes _newGameMode)`

- **Parameters:**
  - `_newGameMode`: The new game mode selection.

- **Description:** Changes the selected game mode and updates the room's custom properties.

#### `UpdateRoomCustomProperties(ExitGames.Client.Photon.Hashtable _customPropreties)`

- **Parameters:**
  - `_customProperties`: Custom room properties to update.

- **Description:** Updates the room's custom properties if the local player is the master client.

#### `StartMatch()`

- **Description:** Starts the match by loading the appropriate scene and resets the custom game status.

#### `StartGame()`

- **Description:** Initiates the start of the custom game. Sends an event to all players to start the countdown.

#### `StopCountdown()`

- **Description:** Stops the countdown and resets the custom game status.

#### `StartCountdownCoroutine()`

- **Description:** Coroutine for handling the countdown before the match starts.

#### `GoBack()`

- **Description:** Handles going back, either by stopping the countdown or leaving the custom game room.

#### `ResetCustomGameStatus()`

- **Description:** Resets the custom game status and countdown.

## Map View

This **UI component** helps us to have a preview of the selected map in both matchmaking and custom game modes.

:::info
**MAP VIEW:**

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


:::

This element is updated every time the room properties are updated. Using this PhotonCallback:

``` c=
public override void OnRoomPropertiesUpdate(ExitGames.Client.Photon.Hashtable propertiesThatChanged)
```

Basically the only thing you would have to do for this element to update would be to change the **room custom properties**.

And this updates for all the map views of the game. Including the local splitscreen gamemode.

### ReptileUIMapView Class
The `ReptileUIMapView` class manages the map view UI, displaying map information and game mode.

#### Fields

- `RawImage mapViewPicture`: The `RawImage` component to display the map picture.
- `TMP_Text mapName`: The `TMP_Text` component to display the map name.
- `TMP_Text gameModeLabel`: The `TMP_Text` component to display the game mode label.

#### Methods

#### `OnEnable()`

- **Description:** Called when the GameObject becomes enabled and active. Updates the map view based on room custom properties if the player is in a room.

#### `UpdateMapView(ExitGames.Client.Photon.Hashtable _properties)`

- **Parameters:**
  - `_properties`: The room custom properties to extract map and game mode information from.

- **Description:** Updates the map view based on the provided room custom properties.

#### `OnRoomPropertiesUpdate(ExitGames.Client.Photon.Hashtable propertiesThatChanged)`

- **Parameters:**
  - `propertiesThatChanged`: The room custom properties that have changed.

- **Description:** Called when room properties are updated. Updates the map view based on the changed properties.


# LOADING SCREEN

Every game needs a loading screen when changing between scenes... This loading screen will be displayed automatically every time you change scenes.

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

This loading screen has a property that allows you to set a minimum loading time in case your game takes extremely little time to load...



### ReptileLoadingScreenHandler Class

The `ReptileLoadingScreenHandler` class handles the loading screen functionality, including a progress bar and minimum loading time.

### Fields

- `Canvas loadingScreen`: The loading screen canvas.
- `Image progressBar`: The progress bar image.
- `float minimumTimeToLoad`: If your game loads extremely fast, use this to fake the loading screen progress. The number you put here is the minimum time the game will take to load.
- `float timeLoading`: A variable to track the loading time.
- `Coroutine loadCoroutine`: A coroutine to handle the loading process.

### Methods

#### `Awake()`

- **Description:** Called when the GameObject is created. Initializes the `loadingScreen` and makes the GameObject persistent across scenes.

#### `Update()`

- **Description:** Checks if a level is loading and starts the loading coroutine if not already started.

#### `PhotonLoadLevelAsync()`

- **Description:** Asynchronously loads a Photon level with a progress bar and minimum loading time. Returns an `IEnumerator` for yielding during the loading process.

#### `ResetLoadingStatus()`

- **Description:** Resets loading status, including the loading timer and coroutine.
