241 lines
5.7 KiB
C#
241 lines
5.7 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using UnityEngine;
|
|
using UnityEngine.Events;
|
|
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, Tuple<string, int>> playerControlSchemes = new Dictionary<int, Tuple<string, int>>();
|
|
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("Choose your control schemes \n Each player press a button \n to start the match \n (see description for controls)");
|
|
}
|
|
|
|
void StartMatch()
|
|
{
|
|
if (zone != null)
|
|
{
|
|
zone.onPlayZoneExited += CheckLosingCondition;
|
|
}
|
|
if (announcements != null)
|
|
{
|
|
announcements.StopAnnouncement();
|
|
announcements.QueueAnnounceText("Match Start", 1.6f);
|
|
}
|
|
}
|
|
|
|
private void CheckLosingCondition(GameObject go)
|
|
{
|
|
if (!go.CompareTag("Player") || currentState == GameState.End)
|
|
return;
|
|
PlayerController pc = go.GetComponent<PlayerController>();
|
|
currentState = GameState.End;
|
|
zone.onPlayZoneExited -= CheckLosingCondition;
|
|
announcements.AnnounceText(pc.playerName + " has lost the match", 2f);
|
|
Destroy(go);
|
|
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, new Tuple<string, int>("New Player", 0));
|
|
}
|
|
|
|
private void DetectPlayerControls(object eventCauser, Tuple<string, int> controlScheme)
|
|
{
|
|
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(Tuple<string, int> controlScheme)
|
|
{
|
|
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.Item1.Contains("Keyboard"))
|
|
{
|
|
pc.playerInput.SwitchCurrentControlScheme(controlScheme.Item1, InputSystem.GetDeviceById(controlScheme.Item2));
|
|
}
|
|
else if (controlScheme.Item1.Contains("Controller"))
|
|
{
|
|
pc.playerInput.SwitchCurrentControlScheme(controlScheme.Item1, InputSystem.GetDeviceById(controlScheme.Item2));
|
|
}
|
|
if (controlScheme.Item1 != "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<Tuple<string, int>> 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, new Tuple<string, int>(controlScheme, context.control.device.deviceId));
|
|
}
|
|
} |