239 lines
5.4 KiB
C#
239 lines
5.4 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using UnityEngine;
|
|
using UnityEngine.InputSystem;
|
|
using UnityEngine.Rendering;
|
|
using UnityEngine.SceneManagement;
|
|
using static InputActionMaps;
|
|
|
|
public enum GameState { Starting, Match, End, Paused }
|
|
public class GameManager : MonoBehaviour
|
|
{
|
|
public static GameManager GM { get; private set; }
|
|
[SerializeField] ZoneRules zone;
|
|
[SerializeField] Announcments announcements;
|
|
[SerializeField] int minPlayerCount = 2;
|
|
public GameState currentState { get; private set; }
|
|
private Dictionary<int, PlayerController> players = new Dictionary<int, PlayerController>();
|
|
private Dictionary<int, string> playerControlSchemes = new Dictionary<int, string>();
|
|
private float restartMatchTime = 0;
|
|
private ControlSchemeDetection controlSchemeDetector;
|
|
|
|
void Awake()
|
|
{
|
|
if (GM != null)
|
|
{
|
|
GM.zone = zone;
|
|
GM.announcements = announcements;
|
|
Destroy(gameObject);
|
|
}
|
|
else
|
|
{
|
|
GM = this;
|
|
DontDestroyOnLoad(gameObject);
|
|
}
|
|
}
|
|
|
|
// void OnEnable()
|
|
// {
|
|
// SceneManager.sceneLoaded += OnSceneLoaded;
|
|
// }
|
|
|
|
// void OnDisable()
|
|
// {
|
|
// SceneManager.sceneLoaded -= OnSceneLoaded;
|
|
// }
|
|
|
|
// void OnSceneLoaded(Scene scene, LoadSceneMode mode)
|
|
// {
|
|
// StartControlAssignment();
|
|
// }
|
|
|
|
void Update()
|
|
{
|
|
if (restartMatchTime > 0)
|
|
{
|
|
restartMatchTime -= Time.deltaTime;
|
|
}
|
|
else if (currentState == GameState.End)
|
|
{
|
|
restartMatchTime = 0;
|
|
StartNewMatch();
|
|
enabled = false;
|
|
}
|
|
}
|
|
|
|
// Start is called before the first frame update
|
|
void Start()
|
|
{
|
|
if (currentState == GameState.End)
|
|
{
|
|
return;
|
|
}
|
|
currentState = GameState.Starting;
|
|
controlSchemeDetector = new ControlSchemeDetection();
|
|
controlSchemeDetector.ControlSchemeDetected += DetectPlayerControls;
|
|
controlSchemeDetector.EnableDetection();
|
|
announcements.AnnounceText("You both press a key \n on your control scheme of choice \n to start the match");
|
|
}
|
|
|
|
void StartMatch()
|
|
{
|
|
if (zone != null)
|
|
{
|
|
zone.onPlayZoneExited += CheckLosingCondition;
|
|
}
|
|
if (announcements != null)
|
|
{
|
|
announcements.StopAnnouncement();
|
|
announcements.AnnounceText("Match Start", 1.6f);
|
|
}
|
|
}
|
|
|
|
private void CheckLosingCondition(GameObject go)
|
|
{
|
|
if (!go.CompareTag("Player") || currentState == GameState.End)
|
|
return;
|
|
currentState = GameState.End;
|
|
zone.onPlayZoneExited -= CheckLosingCondition;
|
|
Destroy(go);
|
|
announcements.AnnounceText(go.name + " has lost the match", 2f);
|
|
restartMatchTime = 2.2f;
|
|
enabled = true;
|
|
}
|
|
|
|
private void StartNewMatch()
|
|
{
|
|
string currentSceneName = SceneManager.GetActiveScene().name;
|
|
players.Clear();
|
|
SceneManager.LoadScene(currentSceneName);
|
|
currentState = GameState.Starting;
|
|
}
|
|
|
|
public void RegisterPlayer(PlayerController pc)
|
|
{
|
|
if (!players.ContainsKey(pc.playerId))
|
|
{
|
|
players[pc.playerId] = pc;
|
|
}
|
|
DetectPlayerControls(this);
|
|
}
|
|
|
|
private void DetectPlayerControls(object sender, string controlScheme = "New Player")
|
|
{
|
|
if (players.Count < minPlayerCount)
|
|
{
|
|
return;
|
|
}
|
|
AssignPlayerControls(controlScheme);
|
|
if (players.Count <= playerControlSchemes.Count)
|
|
{
|
|
if (players.All(pc => PlayerHasActiveControls(pc.Value)))
|
|
{
|
|
controlSchemeDetector.DisableDetection();
|
|
currentState = GameState.Match;
|
|
StartMatch();
|
|
}
|
|
}
|
|
}
|
|
|
|
private void AssignPlayerControls(string controlScheme = "New Player")
|
|
{
|
|
foreach (int playerId in players.Keys)
|
|
{
|
|
PlayerController pc = players[playerId];
|
|
if (PlayerHasActiveControls(pc))
|
|
{
|
|
continue;
|
|
}
|
|
if (playerControlSchemes.ContainsKey(playerId))
|
|
{
|
|
controlScheme = playerControlSchemes[playerId];
|
|
}
|
|
else if (playerControlSchemes.ContainsValue(controlScheme))
|
|
{
|
|
return;
|
|
}
|
|
if (controlScheme.Contains("Keyboard"))
|
|
{
|
|
pc.playerInput.SwitchCurrentControlScheme(controlScheme, Keyboard.current);
|
|
}
|
|
else if (controlScheme.Contains("Controller"))
|
|
{
|
|
pc.playerInput.SwitchCurrentControlScheme(controlScheme, Gamepad.current);
|
|
}
|
|
if (controlScheme != "New Player")
|
|
{
|
|
playerControlSchemes[playerId] = controlScheme;
|
|
}
|
|
}
|
|
}
|
|
|
|
private bool PlayerHasActiveControls(PlayerController pc)
|
|
{
|
|
if (pc == null)
|
|
{
|
|
return false;
|
|
}
|
|
string currentScheme = pc.playerInput.currentControlScheme;
|
|
if (currentScheme != null && currentScheme != "New Player")
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public class ControlSchemeDetection : IPlayerActions
|
|
{
|
|
InputActionMaps actionMaps;
|
|
public event EventHandler<string> ControlSchemeDetected;
|
|
|
|
public ControlSchemeDetection()
|
|
{
|
|
actionMaps = new InputActionMaps();
|
|
actionMaps.Player.SetCallbacks(this);
|
|
}
|
|
|
|
public void EnableDetection()
|
|
{
|
|
actionMaps.Player.Enable();
|
|
}
|
|
public void DisableDetection()
|
|
{
|
|
actionMaps.Player.Disable();
|
|
}
|
|
|
|
public void OnBoost(InputAction.CallbackContext context)
|
|
{
|
|
readControlScheme(context);
|
|
}
|
|
|
|
public void OnReset(InputAction.CallbackContext context)
|
|
{
|
|
readControlScheme(context);
|
|
}
|
|
|
|
public void OnSteer(InputAction.CallbackContext context)
|
|
{
|
|
readControlScheme(context);
|
|
}
|
|
|
|
public void OnThrust(InputAction.CallbackContext context)
|
|
{
|
|
readControlScheme(context);
|
|
}
|
|
|
|
public void readControlScheme(InputAction.CallbackContext context)
|
|
{
|
|
if (!context.canceled || context.performed)
|
|
{
|
|
return;
|
|
}
|
|
int bindingIndex = context.action.GetBindingIndexForControl(context.control);
|
|
InputBinding binding = context.action.bindings[bindingIndex];
|
|
string controlScheme = binding.groups.Split(';')[0];
|
|
ControlSchemeDetected.Invoke(this, controlScheme);
|
|
}
|
|
} |