Files
monde-usage-unity/Assets/Scripts/CameraManager.cs
2024-10-06 14:09:34 +02:00

362 lines
9.2 KiBLFS
C#

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<Animator>();
videoPlayer = GetComponent<VideoPlayer>();
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<string> 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();
}
}