Skip to content

Instantly share code, notes, and snippets.

@MarGamaDev
Created January 23, 2024 12:30
Show Gist options
  • Save MarGamaDev/704d8115729b5ba1e6ad9be2e0dce757 to your computer and use it in GitHub Desktop.
Save MarGamaDev/704d8115729b5ba1e6ad9be2e0dce757 to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.SceneManagement;
public class RoundManager : MonoBehaviour
{
public static RoundManager instance;
[SerializeField] private int roundsToWin = 3;
[SerializeField] private float secondsBetweenRounds = 5;
[SerializeField] private float secondsBeforeReturningToLobby = 10;
private GameObject[] players = new GameObject[4];
private int playerCount = 0;
private Dictionary<GameObject, PlayerController> controllerDictionary = new Dictionary<GameObject, PlayerController>();
private List<GameObject> alivePlayers = new List<GameObject>();
private Dictionary<GameObject, int> roundsWon = new Dictionary<GameObject, int>();
private Transform[] playerSpawnpoints;
public GameState GameState { get { return gameState; } }
private GameState gameState;
public bool PlayedCinematicIntro { get { return playedCinematicIntro; } set { playedCinematicIntro = value; } }
private bool playedCinematicIntro = false;
private void Awake()
{
if (instance != null)
Destroy(this);
instance = this;
DontDestroyOnLoad(gameObject);
}
/// <summary>
/// adds a player to the known player list.
/// </summary>
/// <param name="playerObject"> the player added to the list </param>
public void JoinGame(GameObject playerObject)
{
if (players.Contains(playerObject))
{
Debug.LogError("Player has already joined");
return;
}
for (int i = 0; i < players.Length; i++)
{
if (players[i] == null)
{
players[i] = playerObject;
playerCount++;
return;
}
}
}
/// <summary>
/// removes player from the known player list.
/// </summary>
/// <param name="playerObject"> the player to be removed </param>
public void LeaveGame(GameObject playerObject)
{
for (int i = 0; i < players.Length; i++)
{
if (players[i] == playerObject)
{
players[i] = null;
playerCount--;
return;
}
}
}
/// <summary>
/// initializes all the lists and dictionaries based on playerlist.
/// </summary>
public void Initialize()
{
gameState = GameState.Initlializing;
GameUIManager.instance.InitializeUI(players);
for (int i = 0; i < players.Length; i++)
{
if (players[i] != null)
{
controllerDictionary.Add(players[i], players[i].GetComponent<PlayerController>());
alivePlayers.Add(players[i]);
roundsWon.Add(players[i], 0);
}
}
playerSpawnpoints = ArenaManager.instance.GetPlayerSpawnpoints(playerCount);
ResetGameField();
}
/// <summary>
/// calls the arenamanager to reset and lock the terrain.
/// locks all players and puts them at the right spawnpoints.
/// </summary>
private void ResetGameField()
{
gameState = GameState.Resetting;
alivePlayers.Clear();
// lock and reset the terrain
ArenaManager.instance.LockTerrain(true);
ArenaManager.instance.ResetTerrain();
// reset the players on the right position
int playerSpawnpointIndex = 0;
for (int i = 0; i < players.Length; i++)
{
if (players[i] == null)
{
continue;
}
controllerDictionary[players[i]].IsAlive = false;
controllerDictionary[players[i]].RigidBody.isKinematic = true;
controllerDictionary[players[i]].RigidBody.velocity = Vector3.zero;
controllerDictionary[players[i]].RigidBody.angularVelocity = Vector3.zero;
//put player in the right position and reset its rotation
controllerDictionary[players[i]].transform.position = playerSpawnpoints[playerSpawnpointIndex].position;
controllerDictionary[players[i]].transform.rotation = playerSpawnpoints[playerSpawnpointIndex].rotation;
controllerDictionary[players[i]].LockRotation.resetSoftbody();
controllerDictionary[players[i]].LockRotation.SetRotation(playerSpawnpoints[playerSpawnpointIndex].rotation);
playerSpawnpointIndex++;
GameUIManager.instance.SetPlayerPortraitState(players[i], PlayerGameUI.PortraitState.neutral);
CameraManager.instance.AddToGroup(players[i]);
}
GameUIManager.instance.ClearAnnouncement();
CameraManager.instance.ZoomOutCamera();
if (!playedCinematicIntro)
{
FindObjectOfType<CinematicIntro>().PlayCinematicIntro();
}
else
{
StartCountdown();
}
}
private void DropPlayers()
{
for (int i = 0; i < players.Length; i++)
{
if (players[i] == null)
{
continue;
}
controllerDictionary[players[i]].RigidBody.isKinematic = false;
}
}
/// <summary>
/// unlocks players.
/// unlocks the terrain and start its intensifier.
/// </summary>
private void UnlockGameField()
{
//unlock players
for (int i = 0; i < players.Length; i++)
{
if (players[i] == null)
{
continue;
}
controllerDictionary[players[i]].IsAlive = true;
alivePlayers.Add(players[i]);
}
// unlock terrain
ArenaManager.instance.LockTerrain(false);
ArenaManager.instance.StartIntensifier();
}
public void StartCountdown()
{
gameState = GameState.Starting;
DropPlayers();
CountdownManager.instance.StartCountdown();
}
public void StartRound()
{
gameState = GameState.Playing;
UnlockGameField();
}
/// <summary>
/// called when a player falls off the arena.
/// turns the player off and updates lists.
/// end the round if only one player is left.
/// </summary>
/// <param name="playerObject"> the player that has fallen off </param>
public void HandlePlayerDeath(GameObject playerObject)
{
if (!alivePlayers.Contains(playerObject))
{
return;
}
if (alivePlayers.Count > 1)
{
GameUIManager.instance.SetPlayerPortraitState(playerObject, PlayerGameUI.PortraitState.dead);
}
controllerDictionary[playerObject].IsAlive = false;
alivePlayers.Remove(playerObject);
CameraManager.instance.RemoveFromGroup(playerObject);
if (alivePlayers.Count == 1)
{
EndRound(alivePlayers[0]);
}
}
/// <summary>
/// adds a point to the winner and checks if they have enough points to win.
/// if the player has won the game, end the game and declare the winner.
/// otherwise, restart the round.
/// </summary>
/// <param name="winner"> the last player alive in the round </param>
private void EndRound(GameObject winner)
{
gameState = GameState.Ending;
roundsWon[winner] += 1;
GameUIManager.instance.SetPlayerPortraitState(winner, PlayerGameUI.PortraitState.happy);
GameUIManager.instance.UpdatePoints(winner, roundsWon[winner]);
CameraManager.instance.ZoomInCamera();
if (roundsWon[winner] == roundsToWin)
{
EndGame(winner);
return;
}
GameUIManager.instance.AnnounceRoundWinner(controllerDictionary[winner].PlayerNumber);
Invoke("ResetGameField", secondsBetweenRounds);
}
private void EndGame(GameObject winner)
{
GameUIManager.instance.AnnounceGameWinner(controllerDictionary[winner].PlayerNumber);
GameUIManager.instance.LowerVictorySign();
Invoke("LoadLocalLobbyMenu", secondsBeforeReturningToLobby);
}
private void LoadLocalLobbyMenu()
{
for (int i = 0; i < players.Length; i++)
{
if (players[i] != null)
{
Destroy(players[i]);
}
}
SceneManager.LoadScene(ScenesByName.LocalLobbyMenu);
Destroy(gameObject);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment