Every sound in the game is now a ManageableAudio prefab. The prefabs are picked up in an audio library automatically and other game objects can get the sound they need from the AudioManager. They obtain a ManageableAudio instance which offers various methods to interact with the AudioSource. Depending on how they request the ManageableAudio, the AudioSource is attached to the requesting GameObject, to the Scene or the global management Scene. This provides options to play sounds spatially, globally and scene independent. The prefabs are identified by a tag and an ID, so it is easy to swap out sounds globally, by just replacing the prefab.
267 lines
7.1 KiB
C#
267 lines
7.1 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 event EventHandler<SceneLoadEventArgs> CustomSceneLoaded;
|
|
|
|
void Awake()
|
|
{
|
|
G = this;
|
|
ShowStartScreen();
|
|
ConfigureLog4Net();
|
|
Log.Info("Awake");
|
|
}
|
|
|
|
void Start()
|
|
{
|
|
InstantiateBaseManagers();
|
|
Log.Info("Space Smash Out is starting.");
|
|
LoadMainMenu();
|
|
}
|
|
|
|
/// <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();
|
|
}
|
|
|
|
/// <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; }
|
|
}
|
|
|
|
} |