using System; using System.Collections.Generic; using UnityEngine; using UnityEngine.Video; [Serializable] public class SubScene { public string name; public Camera camera; public Clickable exterior; public SchoolManager sceneManager; } public class CameraManager : MonoBehaviour { #region Singleton public static CameraManager singleton; private void Awake() { if (singleton == null) { singleton = this; } else if (singleton != this) { Destroy(gameObject); } } #endregion public string[] allScenes = new string[] { "Ag", "Legumes", "Lake", "Singe Debout", "Brutus et rufius", }; public string[] scenes = new string[] { // "Ag", // "Legumes", "Lake", "Singe Debout", "Brutus et rufius", }; [SerializeField] private string currentSceneName = "Lake"; [SerializeField] private Camera mainCamera; [SerializeField] private SubScene[] subScenes; [SerializeField] private int currentSubSceneIndex = -1; public SubScene CurrentSubScene => currentSubSceneIndex >= 0 ? subScenes[currentSubSceneIndex] : null; [SerializeField] private MusicManager musicManager; private Animator animator; [SerializeField] private VideoPlayer videoPlayer; private string currentVideoClipName; [SerializeField] private Texture2D hoverTexture, defaultTexture, loadingTexture; [SerializeField] private bool disableCursor = false; public bool isPlayingVideo => currentVideoClipName != null && videoPlayer.isPlaying; public bool CanSkipVideo = true; private Action onVideoEnd; public Action OnVideoStart; void Start() { animator = GetComponent(); videoPlayer = GetComponent(); videoPlayer.renderMode = VideoRenderMode.RenderTexture; videoPlayer.loopPointReached += OnStopVideo; videoPlayer.prepareCompleted += OnPrepareCompleted; foreach (var scene in subScenes) { scene.camera.gameObject.SetActive(false); scene.exterior.AssociatedSubScene = scene; } ShowDefaultTexture(); } #region Cursor [SerializeField] private Vector2 hotSpotHover = new(25, 20); public void ShowHoverTexture() { if (disableCursor) return; Cursor.visible = true; Cursor.SetCursor(hoverTexture, hotSpotHover, CursorMode.ForceSoftware); } public void ShowDefaultTexture() { if (disableCursor) return; Cursor.visible = true; Cursor.SetCursor(defaultTexture, hotSpotHover, CursorMode.ForceSoftware); } void ShowLoadingCursor() { if (disableCursor) return; Cursor.visible = true; Cursor.SetCursor(loadingTexture, Vector2.zero, CursorMode.ForceSoftware); } #endregion private Camera GetCurrentCamera() { return CurrentSubScene?.camera != null ? CurrentSubScene.camera : mainCamera; } #region Navigation public void UpdateArrows() { int currentSceneIndex = Array.FindIndex(scenes, s => s == currentSceneName); musicManager.GoToScene(currentSceneName); CanvasManager.singleton.ShowArrows(); bool inSubScene = currentSubSceneIndex >= 0; CanvasManager.singleton.leftArrow.SetActive(!inSubScene && currentSceneIndex > 0); CanvasManager.singleton.rightArrow.SetActive(!inSubScene && currentSceneIndex < scenes.Length - 1); CanvasManager.singleton.goBackArrow.SetActive(inSubScene); } public void MoveLeft(bool updateArrows = true) { GameManager.singleton.soundManager.PlaySwishSound(); int currentSceneIndex = Array.FindIndex(scenes, s => s == currentSceneName); currentSceneIndex--; if (currentSceneIndex < 0) { currentSceneIndex = 0; } currentSceneName = scenes[currentSceneIndex]; animator.SetTrigger(scenes[currentSceneIndex]); if (updateArrows) UpdateArrows(); } public void MoveRight(bool updateArrows = true) { GameManager.singleton.soundManager.PlaySwishSound(); int currentSceneIndex = Array.FindIndex(scenes, s => s == currentSceneName); currentSceneIndex++; if (currentSceneIndex >= scenes.Length) { currentSceneIndex = scenes.Length - 1; } currentSceneName = scenes[currentSceneIndex]; animator.SetTrigger(scenes[currentSceneIndex]); if (updateArrows) UpdateArrows(); } public void MoveToSubScene(string scene, Action onEnd = null) { SubScene currentSubScene = Array.Find(subScenes, s => s.name == scene); if (currentSubScene == null) { Debug.LogError("SubScene not found"); return; } currentSubSceneIndex = Array.IndexOf(subScenes, currentSubScene); currentSubScene.exterior.Enter(); musicManager.GoToScene(scene); Fader.Fade(() => { onEnd?.Invoke(); mainCamera.gameObject.SetActive(false); currentSubScene.camera.gameObject.SetActive(true); CanvasManager.singleton.EnterSubScene(); }); } public void MoveToMainScene(Action next = null) { Fader.Fade(() => { CurrentSubScene.exterior.Exit(); mainCamera.gameObject.SetActive(true); CurrentSubScene.camera.gameObject.SetActive(false); CanvasManager.singleton.ShowArrows(); currentSubSceneIndex = -1; UpdateArrows(); next?.Invoke(); }); } public void AddSceneLeft(string sceneName) { List scenesList = new(scenes); scenesList.Insert(0, sceneName); scenes = scenesList.ToArray(); } public void GoToEnding() { int endingIndex = Array.FindIndex(scenes, s => s == "Singe Debout"); int cur = Array.FindIndex(scenes, s => s == currentSceneName); GameManager.singleton.endingItem.SetActive(true); GameManager.singleton.mainScene.JumpToScene("Ending"); for (int i = 0; i < Math.Abs(endingIndex - cur); i++) { if (endingIndex > cur) MoveRight(false); else MoveLeft(false); } CanvasManager.singleton.HideArrows(); } #endregion #region Video private float skip = 0; public void PlayVideo( VideoAsset videoAsset, Action onEnd = null, float? skip = null ) { skip = skip ?? 0; if (videoAsset == null) { Debug.LogError("VideoAsset is null"); return; } if (isPlayingVideo) return; GameManager.singleton.soundManager.StopSound(); musicManager.PauseMusic(); if (onEnd != null) { onVideoEnd = onEnd; } videoPlayer.renderMode = VideoRenderMode.RenderTexture; videoPlayer.targetCamera = GetCurrentCamera(); currentVideoClipName = videoAsset.name; VideoPlayManager.RegisterPlay(videoAsset); videoAsset.Play(videoPlayer); videoPlayer.isLooping = false; videoPlayer.playbackSpeed = 1; ShowLoadingCursor(); videoPlayer.Prepare(); Fader.instance.SetFullBlack(); } private void OnPrepareCompleted(VideoPlayer source) { OnVideoStart?.Invoke(); CanvasManager.singleton.PlayVideo(); videoPlayer.Play(); videoPlayer.time = skip; ShowDefaultTexture(); // Cursor.visible = false; } public void IncreaseSpeed() { videoPlayer.playbackSpeed *= 1.3f; } public void StopVideo() { OnStopVideo(videoPlayer); } public void OnStopVideo(VideoPlayer source) { source.Stop(); Cursor.visible = true; CanvasManager.singleton.StopVideoUI(); musicManager.ResumeMusic(); currentVideoClipName = null; ShowDefaultTexture(); onVideoEnd?.Invoke(); Fader.instance.SetTransparent(); GameManager.singleton.OnEndVideo(); } public void ToggleEnding() { CanSkipVideo = false; } #endregion void Update() { // Handle input in video mode if (isPlayingVideo) { // if (Cursor.visible) Cursor.visible = false; if (!CanSkipVideo) return; // Leftclick if (Input.GetMouseButtonDown(0)) { CanvasManager.singleton.DisplaySkipButton(); return; } // Rightclick or escape if (Input.GetMouseButton(1) || Input.GetKeyDown(KeyCode.Escape)) { StopVideo(); return; } return; } // Handle input in main scene if (Input.GetKeyDown(KeyCode.LeftArrow)) { MoveLeft(); } else if (Input.GetKeyDown(KeyCode.RightArrow)) { MoveRight(); } else if (Input.GetKeyDown(KeyCode.Escape) && CurrentSubScene != null) { MoveToMainScene(); } } public void UnlockAll() { scenes = allScenes; UpdateArrows(); } }