Files
Click-PointRPG/Assets/Scripts/Managers/CameraManager.cs

181 lines
4.5 KiB
C#

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<CameraEntry> cameras = new List<CameraEntry>();
private readonly Dictionary<string, CameraEntry> cameraLookup = new Dictionary<string, CameraEntry>();
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<CinemachineBrain>();
}
}
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<CinemachineBrain>();
}
if (brain != null && System.Enum.TryParse<CinemachineBlendDefinition.Styles>(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();
}
}