using System.Collections.Generic; using UnityEngine; using Unity.Cinemachine; public class CameraManager : MonoBehaviour { public static CameraManager Instance { get; private set; } [System.Serializable] public class CameraEntry { public string id; public CinemachineVirtualCameraBase camera; public int activePriority = 20; public int inactivePriority = 10; } [Header("Setup")] public bool dontDestroyOnLoad = true; public bool disableInactiveCameras = false; public CinemachineBrain brain; [Header("Cameras")] public List cameras = new List(); private readonly Dictionary cameraLookup = new Dictionary(); private CameraEntry current; private void Awake() { if (Instance != null && Instance != this) { Destroy(gameObject); return; } Instance = this; if (dontDestroyOnLoad) { DontDestroyOnLoad(gameObject); } RebuildLookup(); if (brain == null) { brain = FindAnyObjectByType(); } } private void OnValidate() { for (int i = 0; i < cameras.Count; i++) { CameraEntry entry = cameras[i]; if (entry != null && string.IsNullOrEmpty(entry.id) && entry.camera != null) { entry.id = entry.camera.name; } } } public void RebuildLookup() { cameraLookup.Clear(); foreach (CameraEntry entry in cameras) { if (entry == null || entry.camera == null || string.IsNullOrEmpty(entry.id)) { continue; } if (!cameraLookup.ContainsKey(entry.id)) { cameraLookup.Add(entry.id, entry); } } } public void SwitchTo(string id) { if (string.IsNullOrEmpty(id)) return; if (!cameraLookup.TryGetValue(id, out CameraEntry entry) || entry.camera == null) { Debug.LogWarning($"CameraManager: No camera registered with id '{id}'.", gameObject); return; } SwitchTo(entry.camera); } public void SwitchTo(CinemachineVirtualCameraBase targetCamera) { if (targetCamera == null) return; foreach (CameraEntry entry in cameras) { if (entry == null || entry.camera == null) continue; bool isActive = entry.camera == targetCamera; entry.camera.Priority = isActive ? entry.activePriority : entry.inactivePriority; if (disableInactiveCameras) { entry.camera.gameObject.SetActive(isActive); } if (isActive) { current = entry; } } } public CinemachineVirtualCameraBase GetActiveCamera() { return current != null ? current.camera : null; } public void SetFollow(Transform followTarget) { CinemachineVirtualCameraBase cam = GetActiveCamera(); if (cam != null) { cam.Follow = followTarget; } } public void SetLookAt(Transform lookTarget) { CinemachineVirtualCameraBase cam = GetActiveCamera(); if (cam != null) { cam.LookAt = lookTarget; } } public void SetDefaultBlend(string style, float time) { if (brain == null) { brain = FindAnyObjectByType(); } if (brain != null && System.Enum.TryParse(style, out var blendStyle)) { brain.DefaultBlend = new CinemachineBlendDefinition(blendStyle, time); } } public void RegisterCamera(string id, CinemachineVirtualCameraBase cam, int activePriority = 20, int inactivePriority = 10) { if (cam == null || string.IsNullOrEmpty(id)) return; CameraEntry entry = new CameraEntry { id = id, camera = cam, activePriority = activePriority, inactivePriority = inactivePriority }; cameras.Add(entry); RebuildLookup(); } public void UnregisterCamera(string id) { if (string.IsNullOrEmpty(id)) return; for (int i = cameras.Count - 1; i >= 0; i--) { if (cameras[i] != null && cameras[i].id == id) { cameras.RemoveAt(i); } } RebuildLookup(); } }