NLDClient-yudde/ProjectNLD/Assets/Code/Scripts/Framework/CameraManager.cs

180 lines
4.8 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.Rendering.Universal;
namespace PhxhSDK
{
public class CameraManager : Singlenton<CameraManager>, IInitable
{
private Camera _mainCamera;
private Stack<Camera> _usedMainCameraStack = new();
private RenderTexture _defaultRenderTarget;
public RenderTexture DefaultRenderTarget
{
get => _defaultRenderTarget;
set
{
if (_defaultRenderTarget != value)
{
_defaultRenderTarget = value;
_mainCamera.targetTexture = _defaultRenderTarget;
}
}
}
public event Action<Camera> 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<Camera>();
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<Camera>();
SkillCamera.gameObject.SetActive(false);
}
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();
}
}
}