304 lines
8.5 KiB
C#
304 lines
8.5 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.IO;
|
|
using System.Reflection;
|
|
using System.Threading.Tasks;
|
|
using log4net;
|
|
using log4net.Config;
|
|
using UnityEngine;
|
|
using UnityEngine.Events;
|
|
using UnityEngine.SceneManagement;
|
|
|
|
/// <summary>
|
|
/// The available scenes in the order they are in the build settings.
|
|
/// </summary>
|
|
public enum Scenes
|
|
{
|
|
GameMangement,
|
|
MenuUserInterface,
|
|
GameplayUserInterface,
|
|
Arena,
|
|
}
|
|
|
|
namespace Managers
|
|
{
|
|
|
|
/// <summary>
|
|
/// Starts up the game and it's managers.
|
|
/// Provides methods for loading additional scenes and triggering custom events when loaded.
|
|
/// Orchestrates the managers for starting local and online matches.
|
|
/// </summary>
|
|
public class GameManager : MonoBehaviour
|
|
{
|
|
private static ILog Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
|
|
|
/// <summary>
|
|
/// Globally accessible member to use manager with.
|
|
/// </summary>
|
|
public static GameManager G { get; private set; }
|
|
|
|
[SerializeField]
|
|
private UIManager UIManager;
|
|
[SerializeField]
|
|
private CharacterManager CharacterManager;
|
|
[SerializeField]
|
|
private ControlsManager ControlsManager;
|
|
[SerializeField]
|
|
private MatchManager MatchManager;
|
|
[SerializeField]
|
|
private StatisticsManager StatisticsManager;
|
|
[SerializeField]
|
|
private PlayerManager PlayerManager;
|
|
[SerializeField]
|
|
private AudioManager AudioManager;
|
|
|
|
[SerializeField]
|
|
private GameObject startCamera;
|
|
|
|
public bool IsTestRun = false;
|
|
public Scenes TestScene = Scenes.Arena;
|
|
|
|
public event EventHandler<SceneLoadEventArgs> CustomSceneLoaded;
|
|
|
|
void Awake()
|
|
{
|
|
G = this;
|
|
if (!IsTestRun) ShowStartScreen();
|
|
ConfigureLog4Net();
|
|
Log.Info("Awake");
|
|
}
|
|
|
|
void Start()
|
|
{
|
|
InstantiateBaseManagers();
|
|
Log.Info("Space Smash Out is starting.");
|
|
if (!IsTestRun)
|
|
{
|
|
LoadMainMenu();
|
|
}
|
|
else
|
|
{
|
|
// Coroutine for waiting a frame and letting the managers run their Start methods
|
|
StartCoroutine(SetupTestMatch(TestScene));
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Configuration of log 4 net, before the game starts.
|
|
/// </summary>
|
|
void ConfigureLog4Net()
|
|
{
|
|
log4net.GlobalContext.Properties["LogFileName"] = $"{Application.dataPath}" +
|
|
"\\Logging\\SSOLog";
|
|
var fi = new FileInfo($"{Application.dataPath}" +
|
|
"\\Logging\\Log4NetConfiguration.xml");
|
|
XmlConfigurator.Configure(fi);
|
|
Log.Debug("Log4Net configured.");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Instantiates the managers needed to play the game.
|
|
/// </summary>
|
|
void InstantiateBaseManagers()
|
|
{
|
|
if (UIManager != null)
|
|
{
|
|
UIManager = Instantiate(UIManager);
|
|
Log.Info("User Interface Manager instantiated.");
|
|
}
|
|
else
|
|
{
|
|
Log.Error("User Interface Manager Prefab missing.");
|
|
}
|
|
if (ControlsManager != null)
|
|
{
|
|
ControlsManager = Instantiate(ControlsManager);
|
|
Log.Info("Controls Manager instantiated.");
|
|
}
|
|
else
|
|
{
|
|
Log.Error("Controls Manager Prefab missing.");
|
|
}
|
|
if (MatchManager != null)
|
|
{
|
|
MatchManager = Instantiate(MatchManager);
|
|
Log.Info("Match Manager instantiated.");
|
|
}
|
|
else
|
|
{
|
|
Log.Error("User Interface Manager Prefab missing.");
|
|
}
|
|
if (CharacterManager != null)
|
|
{
|
|
CharacterManager = Instantiate(CharacterManager);
|
|
Log.Info("Character Manager instantiated.");
|
|
}
|
|
else
|
|
{
|
|
Log.Error("Character Manager Prefab missing.");
|
|
}
|
|
if (PlayerManager != null)
|
|
{
|
|
PlayerManager = Instantiate(PlayerManager);
|
|
Log.Info("PlayerManager Manager instantiated.");
|
|
}
|
|
else
|
|
{
|
|
Log.Error("PlayerManager Manager Prefab missing.");
|
|
}
|
|
if (AudioManager != null)
|
|
{
|
|
AudioManager = Instantiate(AudioManager);
|
|
Log.Info("PlayerManager Manager instantiated.");
|
|
}
|
|
else
|
|
{
|
|
Log.Error("PlayerManager Manager Prefab missing.");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Starts the camera, for showing an image before the main menu is loaded.
|
|
/// </summary>
|
|
void ShowStartScreen()
|
|
{
|
|
startCamera.SetActive(true);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets up switching cameras once the menu is loaded
|
|
/// and starts the async scene loading.
|
|
/// </summary>
|
|
void LoadMainMenu()
|
|
{
|
|
SingleUseSceneLoadedMethodCaller((args) =>
|
|
{
|
|
SceneManager.SetActiveScene(args.SceneRef);
|
|
startCamera.SetActive(false);
|
|
}, Scenes.MenuUserInterface);
|
|
SceneManager.LoadSceneAsync((int)Scenes.MenuUserInterface, LoadSceneMode.Additive);
|
|
Log.Info("Main menu scene loaded.");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Initiates a local battle by giving relavant information to the responsible managers
|
|
/// and starting their appropriate processes.
|
|
/// </summary>
|
|
/// <param name="sceneId">Scene id of the chosen arena.</param>
|
|
public IEnumerator SetupLocalMatchFromMainMenu()
|
|
{
|
|
MatchManager.LoadMatchRules(0);
|
|
MatchManager.LoadArenaProperties(0);
|
|
PlayerManager.LocalMatchJoinPlayers(MatchManager.arenaProperties.minPlayerCount);
|
|
// TODO: This is in place of a character choosing menu etc.
|
|
foreach (Player p in PlayerManager.localPlayers)
|
|
{
|
|
CharacterManager.AssignShipFixed(p);
|
|
Log.Debug($"Ship: {p.character.name} assigned to player: {p.playerNumber}.");
|
|
}
|
|
|
|
MatchManager.StartCharacterSelect();
|
|
MatchManager.SpawnCharacters(PlayerManager.localPlayers);
|
|
|
|
UIManager.StartManagingMatchUI();
|
|
UIManager.AssignHUDElementsToPlayers(PlayerManager.localPlayers);
|
|
|
|
ControlsManager.AssignControlsToPlayers(PlayerManager.localPlayers);
|
|
|
|
UIManager.StartInputPrompt(ControlsManager.unassignedPlayers);
|
|
|
|
// Waits with starting the match until every player has controls
|
|
while (ControlsManager.unassignedPlayers.Count > 0)
|
|
{
|
|
yield return null;
|
|
}
|
|
MatchManager.StartMatch();
|
|
}
|
|
|
|
public IEnumerator SetupTestMatch(Scenes scene)
|
|
{
|
|
yield return null;
|
|
SceneManager.LoadScene((int)scene, LoadSceneMode.Additive);
|
|
yield return null;
|
|
SceneManager.LoadScene((int)Scenes.GameplayUserInterface, LoadSceneMode.Additive);
|
|
yield return null;
|
|
SceneManager.SetActiveScene(SceneManager.GetSceneByBuildIndex((int)scene));
|
|
yield return null;
|
|
MatchManager.LoadMatchRules(0);
|
|
MatchManager.LoadArenaProperties(0);
|
|
PlayerManager.LocalMatchJoinPlayers(MatchManager.arenaProperties.minPlayerCount);
|
|
// TODO: This is in place of a character choosing menu etc.
|
|
foreach (Player p in PlayerManager.localPlayers)
|
|
{
|
|
CharacterManager.AssignShipFixed(p);
|
|
Log.Debug($"Ship: {p.character.name} assigned to player: {p.playerNumber}.");
|
|
}
|
|
MatchManager.StartCharacterSelect();
|
|
MatchManager.SpawnCharacters(PlayerManager.localPlayers);
|
|
UIManager.StartManagingMatchUI();
|
|
UIManager.AssignHUDElementsToPlayers(PlayerManager.localPlayers);
|
|
ControlsManager.AssignControlsToPlayers(PlayerManager.localPlayers);
|
|
MatchManager.StartTestMatch();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Triggers a method once, when a specific scene was loaded.
|
|
/// </summary>
|
|
/// <param name="func">The method which will be executed
|
|
/// once the scene is loaded.</param>
|
|
/// <param name="sceneEnum">The scene which will trigger the method when loaded.</param>
|
|
public void SingleUseSceneLoadedMethodCaller(CustomOnSceneLoaded method, Scenes sceneEnum)
|
|
{
|
|
// This is used because SceneManager.sceneLoaded only passes ref and loadMode.
|
|
// I want add the sceneEnum to this, to check if the the sceneLoaded event
|
|
// refers to the same scene as passed to this method.
|
|
UnityAction<Scene, LoadSceneMode> OnSceneLoaded = (sceneRef, loadMode) =>
|
|
{
|
|
CustomSceneLoaded.Invoke(null, new SceneLoadEventArgs(sceneEnum, sceneRef));
|
|
};
|
|
|
|
EventHandler<SceneLoadEventArgs> handler = null;
|
|
|
|
handler = (invoker, args) =>
|
|
{
|
|
// Thanks to the CustomSceneLoaded event I can check this here.
|
|
if (args.SceneRef.buildIndex == (int)args.SceneEnum)
|
|
{
|
|
method(args);
|
|
}
|
|
else
|
|
{
|
|
Log.Warn("Should have loaded scene: " + args.SceneEnum.ToString() +
|
|
" but the most recently loaded scene is: " + args.SceneRef.name +
|
|
". Be careful of loading many scenes at once from different scripts!");
|
|
}
|
|
CustomSceneLoaded -= handler;
|
|
SceneManager.sceneLoaded -= OnSceneLoaded;
|
|
};
|
|
|
|
CustomSceneLoaded += handler;
|
|
|
|
SceneManager.sceneLoaded += OnSceneLoaded;
|
|
}
|
|
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// Custom delegate which can be executed after scene load.
|
|
/// </summary>
|
|
/// <param name="args">Data of the loaded scene</param>
|
|
public delegate void CustomOnSceneLoaded(SceneLoadEventArgs args);
|
|
|
|
public class SceneLoadEventArgs : EventArgs
|
|
{
|
|
public SceneLoadEventArgs(Scenes sceneEnum, Scene sceneRef)
|
|
{
|
|
SceneEnum = sceneEnum;
|
|
SceneRef = sceneRef;
|
|
}
|
|
public Scenes SceneEnum { get; set; }
|
|
public Scene SceneRef { get; set; }
|
|
}
|
|
|
|
} |