Files

402 lines
12 KiB
C#

using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Video;
using UnityEngine.SceneManagement;
public enum GameMode
{
SinglePlayer,
LocalMultiplayer,
CashSystem
}
public class GameManager : MonoBehaviour
{ //Game Mode
public GameMode currentGameMode;
//Single Player
public GameObject inScenePlayer;
//Local Multiplayer
public GameObject playerPrefab;
public GameObject homeScreen;
public GameObject splashScreen;
public int numberOfPlayers;
public Transform spawnRingCenter;
public float spawnRingRadius;
//Spawned Players
private bool isPaused;
public static GameManager Instance;
public ModeSelection modeSelection;
public WaitingSceneManager waitingSceneManager;
private int enemiesDefeated = 0;
public AudioSource audioSource;
public AudioSource sfxSource;
///this should carry the value of the selected players from the modeselection script and make it available in another scene(game scene)
public Dictionary<string, PlayerInfo> selectedPlayerDevice;
[SerializeField]
private Slider progressBar;
public RawImage rawImage;
public VideoPlayer videoPlayer;
private bool isVideoFinished = false;
public event Action SplashSequenceCompleted;
public GameObject loadingUI; // Reference to the Loading UI Canvas
// private GameSettings gameSettings;
// void OnEnable(){
// //If Key is present, then load
// if (PlayerPrefs.HasKey(GameSettingsKey))
// {
// gameSettings = LoadGameSettings(); //Load
// }
// // else{
// // DefaultSettings(); //Set Volume and Controls Settings
// // // SaveGameSettings();
// // }
// }
private GameSettings gameSettings;
void LoadAudioSetings(){
if (PlayerPrefs.HasKey(GameSettingsKey))
{
gameSettings = LoadGameSettings(); //Load
}
else
{
gameSettings = new GameSettings(); // Create default settings if none exist
}
}
private void Awake()
{
if (Instance != null && Instance != this)
{
Destroy(gameObject);
return; // prevent duplicate initialization
}
Instance = this;
DontDestroyOnLoad(gameObject);
if (sfxSource == null)
{
sfxSource = gameObject.AddComponent<AudioSource>();
sfxSource.playOnAwake = false;
}
if (selectedPlayerDevice == null)
selectedPlayerDevice = new Dictionary<string, PlayerInfo>();
audioSource = GetComponent<AudioSource>();
}
void Start()
{
isPaused = false;
//SetupBasedOnGameState();
//SetupUI();
// Set the video player's target texture to the raw image's texture
videoPlayer.targetTexture = new RenderTexture(Screen.width, Screen.height, 24);
rawImage.texture = videoPlayer.targetTexture;
// Record when splash started for minimum duration check
splashStartTime = Time.realtimeSinceStartup;
// Subscribe to the videoPlayer's completion event
videoPlayer.loopPointReached += OnVideoFinished;
}
//BG Music
public void PlayBackgroundMusic()
{
//audio play
LoadAudioSetings();
Debug.Log($"BG MUSIC PLAYING {gameSettings.GameplayVolume_value}");
audioSource.volume = gameSettings.GameplayVolume_value;
audioSource.Play();
}
//UI click
public void PlaySound(AudioClip sfxClip)
{
if (sfxClip == null)
{
Debug.LogWarning("Attempted to play null audio clip");
return;
}
if (sfxSource == null)
{
Debug.LogWarning("sfxSource is null, attempting to recreate");
sfxSource = gameObject.AddComponent<AudioSource>();
sfxSource.playOnAwake = false;
}
LoadAudioSetings();
sfxSource.clip = sfxClip;
sfxSource.volume = gameSettings != null ? gameSettings.UIVolume_value : 1f;
sfxSource.Play();
}
public void ActivateHomeScreen()
{
// Perform actions to activate the home screen here
homeScreen.SetActive(true);
}
// Minimum time (seconds) the splash should display before transitioning
private float splashStartTime;
private const float MIN_SPLASH_DURATION = 2.0f; // At least 2 seconds
// Method called when the video finishes playing
private void OnVideoFinished(VideoPlayer player)
{
// Set the flag to true to indicate that the video has finished playing
if (isVideoFinished)
{
return;
}
// Check if the video actually played for a reasonable duration
float timeSinceSplashStart = Time.realtimeSinceStartup - splashStartTime;
double videoLength = player != null && player.length > 0 ? player.length : 0;
Debug.Log($"[GameManager] loopPointReached triggered. Time since start: {timeSinceSplashStart:F2}s, Video length: {videoLength:F2}s, IsPlaying: {player?.isPlaying}");
// If the event fired too quickly (video didn't actually play), wait for it
if (timeSinceSplashStart < MIN_SPLASH_DURATION && timeSinceSplashStart < videoLength * 0.5f)
{
Debug.LogWarning($"[GameManager] Video finished too quickly ({timeSinceSplashStart:F2}s). Starting fallback wait...");
StartCoroutine(WaitForMinimumSplashDuration());
return;
}
isVideoFinished = true;
Debug.Log("[GameManager] Splash video finished. Starting scene load coroutine to avoid blocking main thread.");
// Start coroutine to avoid blocking the VideoPlayer callback thread
StartCoroutine(LoadMenuAfterSplash());
}
private System.Collections.IEnumerator WaitForMinimumSplashDuration()
{
// Wait until minimum duration has passed
float remainingTime = MIN_SPLASH_DURATION - (Time.realtimeSinceStartup - splashStartTime);
if (remainingTime > 0)
{
Debug.Log($"[GameManager] Waiting {remainingTime:F2}s for minimum splash duration...");
yield return new WaitForSeconds(remainingTime);
}
if (!isVideoFinished)
{
isVideoFinished = true;
Debug.Log("[GameManager] Minimum splash duration reached. Starting scene load.");
StartCoroutine(LoadMenuAfterSplash());
}
}
private System.Collections.IEnumerator LoadMenuAfterSplash()
{
ShowLoadingUI();
// Invoke the event - GameInitialize will handle scene loading if subscribed
// This prevents duplicate scene load attempts
bool hasSubscribers = SplashSequenceCompleted != null;
SplashSequenceCompleted?.Invoke();
// Wait one frame to ensure UI updates before potentially heavy operations
yield return null;
// Only load scene directly if no subscribers handled it
// (GameInitialize subscribes when forceMenuDuringDevelopment is true)
if (!hasSubscribers)
{
const string forcedScene = "MenuScene";
Debug.Log("[GameManager] Loading '" + forcedScene + "' via LoadingScreen (no external subscribers).");
LoadSceneWithLoading(forcedScene);
}
else
{
Debug.Log("[GameManager] Splash finished - scene loading handled by subscriber.");
}
}
private void ActivateLoadingBar()
{
// Show the loading bar or perform any other loading-related actions here
//SceneManager.LoadScene("MenuScene", LoadSceneMode.Single);
SceneManager.sceneLoaded += OnSceneLoaded;
}
public void OnSceneLoaded(Scene scene, LoadSceneMode mode){
SceneManager.sceneLoaded -= OnSceneLoaded; // Unregister event handler
if (scene.name != "MenuScene")
{
return;
}
// Debug.Log("XT Loading Bar");
//Find GameObject with name "UI"
GameObject uiObject = GameObject.Find("UI");
if (uiObject != null){
/*foreach (Transform child in uiObject.transform){
if ((child.name != "ModeSelection")){
child.gameObject.SetActive(false);
}
}*/
//Check if Announcements have been shown or not, if shown, go to Loading_Screen UI, but if not yet shown, then go to Announcements UI
// Check if the "announcement" key exists in PlayerPrefs
// Get the value of the "announcement" key
string announcementValue = PlayerPrefs.GetString("announcementStatus");
// Check if the value is "0", Announcements have not happened
if (announcementValue == "0"){
GameObject announcements_to_show = uiObject.transform.Find("Announcements")?.gameObject;
if (announcements_to_show != null){
announcements_to_show.SetActive(true); //When the Menu scene is activated, show this UI
}else{
Debug.Log("No Announcements screen");
}
}
else{ //Announcements already happened
//LoadingScreen loadingscript = GetComponent<LoadingScreen>();
//ActivateHomeScreen();
//GameManager.Instance.gameObject.GetComponent<LoadingScreen>().UI_to_show_AfterLoading(2, "Home");
}
}
else{
Debug.LogError("UI GameObject not found in MenuScene!");
}
}
public void IncrementEnemiesDefeated()
{
enemiesDefeated++;
}
public int GetEnemiesDefeated()
{
return enemiesDefeated;
}
void SetupLocalMultiplayer()
{
if (inScenePlayer == true)
{
Destroy(inScenePlayer);
}
}
public void HideLoadingUI()
{
loadingUI.SetActive(false);
}
public bool HasSplashFinished => isVideoFinished;
public void ShowLoadingUI()
{
if (loadingUI == null)
{
if (gameObject.transform.childCount > 0)
{
loadingUI = gameObject.transform.GetChild(0).gameObject;
}
else
{
Debug.LogError("ShowLoadingUI: No child GameObject found. Please ensure the hierarchy is set up correctly.");
return;
}
}
loadingUI.SetActive(true);
}
public void LoadSceneWithLoading(string sceneName)
{
if (string.IsNullOrEmpty(sceneName))
{
Debug.LogError("LoadSceneWithLoading: sceneName is null or empty");
return;
}
var loadingScreen = GetComponentInChildren<LoadingScreen>(true);
if (loadingScreen != null)
{
loadingScreen.UI_to_show_AfterLoading(1, sceneName);
ShowLoadingUI();
}
else
{
Debug.LogWarning("LoadSceneWithLoading: LoadingScreen component not found. Falling back to direct scene load.");
SceneManager.LoadScene(sceneName, LoadSceneMode.Single);
}
}
//Saving and Loading Game Settings
#region
private const string GameSettingsKey = "GameSettings";
public static void SaveGameSettings(GameSettings settings){
string json = JsonUtility.ToJson(settings);
PlayerPrefs.SetString(GameSettingsKey, json);
PlayerPrefs.Save();
}
public static GameSettings LoadGameSettings(){
if (PlayerPrefs.HasKey(GameSettingsKey))
{
string json = PlayerPrefs.GetString(GameSettingsKey);
return JsonUtility.FromJson<GameSettings>(json);
}
return new GameSettings(); // Return default settings if none are saved
}
#endregion
}