using System; using System.Collections.Generic; using System.Linq; using UnityEngine; using UnityEngine.Rendering.Universal; namespace PhxhSDK { public class CameraManager : Singlenton, IInitable { private Camera _mainCamera; private Stack _usedMainCameraStack = new(); private RenderTexture _defaultRenderTarget; public RenderTexture DefaultRenderTarget { get => _defaultRenderTarget; set { if (_defaultRenderTarget != value) { _defaultRenderTarget = value; _mainCamera.targetTexture = _defaultRenderTarget; } } } public event Action AfterSwitchMainCamera; public Camera MainCamera => _mainCamera; public Camera UICamera { get { return UIRoot.Instance.UICamera; } } public Camera SkillCamera { get; private set; } public Camera CreateCamera(string name, string tag = null) { var go = new GameObject(name); var camera = go.AddComponent(); if (tag != null) { camera.tag = tag; } return camera; } public void DestroyCamera(Camera camera) { if (camera != null) { GameObject.Destroy(camera.gameObject); } } public void ReRenderAll() { foreach (var c in Camera.allCameras) { var oldEnabled = c.enabled; c.enabled = true; c.Render(); c.enabled = oldEnabled; } } public void Init() { _mainCamera = Camera.main; if (_mainCamera == null) { CreateCamera("Main Camera", "MainCamera"); } if (_mainCamera != null) { GameObject.DontDestroyOnLoad(MainCamera.gameObject); } SkillCamera = GameObject.Find("SkillCamera").GetComponent(); } public void SetMainCameraActive(bool isActive) { _mainCamera?.gameObject.SetActive(isActive); } public void SwitchMainCamera(Camera camera) { // DebugUtil.LogError("切换相机"); if (camera == null || camera == _mainCamera) return; _usedMainCameraStack.Push(_mainCamera); _SwitchCameraPurely(camera); } public void RevertMainCamera() { // DebugUtil.LogError("还原相机"); if (_usedMainCameraStack.Count == 0) { DebugUtil.LogError($"_usedMainCameraStack count is 0"); return; } var _lastMainCamera = GetOutMostCameraInStack(); if (_lastMainCamera == null) { DebugUtil.LogError($"相机栈中找不到旧的使用过的主相机"); return; } _SwitchCameraPurely(_lastMainCamera); } private void _SwitchCameraPurely(Camera camera) { if (camera == null || _mainCamera == camera) return; var currCamera = _mainCamera; if (currCamera != null) { DeActiveMainCamera(currCamera); } _mainCamera = camera; ActiveMainCamera(_mainCamera); AfterSwitchMainCamera?.Invoke(_mainCamera); } private Camera GetOutMostCameraInStack() { Camera result = null; int popCount = 1; foreach (var camera in _usedMainCameraStack) { //可能会出现之前使用过的相机已经销毁的情况 if (camera == null) popCount++; else { result = camera; break; } } popCount = popCount > _usedMainCameraStack.Count ? _usedMainCameraStack.Count : popCount; for (int i = 0; i < popCount; i++) { _usedMainCameraStack.Pop(); } return result; } private void ActiveMainCamera(Camera cam) { cam.gameObject.SetActive(true); cam.targetTexture = DefaultRenderTarget; } private void DeActiveMainCamera(Camera cam) { cam.gameObject.SetActive(false); } public void Release() { _usedMainCameraStack.Clear(); } } }