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

301 lines
8.2 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using PhxhSDK.Res;
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace PhxhSDK
{
public class CameraManager : Singlenton<CameraManager>, IInitable
{
/// <summary>
/// 主相机
/// </summary>
private Camera _mainCamera;
/// <summary>
/// UI相机从UIRoot初始化
/// </summary>
private Camera _uiCamera;
/// <summary>
/// UI Top相机从UIRoot初始化
/// </summary>
private Camera _uiTopCamera;
/// <summary>
/// 主相机切换回调
/// </summary>
public event Action<Camera> AfterSwitchMainCamera;
/// <summary>
/// 主相机栈
/// </summary>
private Stack<Camera> _usedMainCameraStack = new();
/// <summary>
/// 默认的主相机RenderTexture
/// </summary>
private RenderTexture _defaultRenderTarget;
#region 属性
public RenderTexture DefaultRenderTarget
{
get => _defaultRenderTarget;
set
{
if (_defaultRenderTarget != value)
{
_defaultRenderTarget = value;
if (_mainCamera != null)
_mainCamera.targetTexture = _defaultRenderTarget;
}
}
}
/// <summary>
/// 主相机
/// </summary>
public Camera MainCamera => _mainCamera;
/// <summary>
/// UI相机
/// </summary>
public Camera UICamera => _uiCamera;
/// <summary>
/// UI Top相机
/// </summary>
public Camera UITopCamera => _uiTopCamera;
/// <summary>
/// 是否正在移动
/// </summary>
public static bool IsMainCameraMoving { get; set; }
#endregion
public void Init()
{
_mainCamera = Camera.main;
// 从UIRoot获取UI相机引用
if (UIRoot.Instance != null)
{
_uiCamera = UIRoot.Instance.UICamera;
_uiTopCamera = UIRoot.Instance.UITopCamera;
}
}
public void Release()
{
_usedMainCameraStack.Clear();
}
/// <summary>
/// 创建相机
/// </summary>
/// <param name="name"></param>
/// <param name="tag"></param>
/// <returns></returns>
public Camera CreateCamera(string name, string tag = null)
{
GameObject go = new(name);
Camera camera = go.AddComponent<Camera>();
if (null != tag)
camera.tag = tag;
return camera;
}
public void DestroyCamera(Camera camera)
{
if (null != camera)
UnityEngine.Object.Destroy(camera.gameObject);
}
/// <summary>
/// 获取场景中的相机
/// </summary>
/// <param name="sceneHandle"></param>
/// <param name="camera"></param>
/// <returns></returns>
public bool TryGetSceneCamera(SceneHandle sceneHandle, out Camera camera)
{
camera = null;
if (null == sceneHandle)
return false;
if (null != sceneHandle.SceneCameraRoot)
{
camera = sceneHandle.SceneCameraRoot.Camera;
if (null != camera)
return true;
}
GameObject[] rootGameObjects = sceneHandle.Scene.GetRootGameObjects();
if (null == rootGameObjects || 0 >= rootGameObjects.Length)
return false;
GameObject gameObject = rootGameObjects.FirstOrDefault(root => root.GetComponent<Camera>() != null);
if (null == gameObject)
return false;
camera = gameObject.GetComponent<Camera>();
return null != camera;
}
/// <summary>
/// 关闭所有相机(忽略UI相机)
/// </summary>
public void CloseAllCameraIgnoreUI()
{
SetMainCameraActive(false);
UITopCamera.gameObject.SetActive(false);
}
/// <summary>
/// 全部相机重新渲染
/// </summary>
public void ReRenderAll()
{
foreach (Camera c in Camera.allCameras)
{
bool oldEnabled = c.enabled;
c.enabled = true;
c.Render();
c.enabled = oldEnabled;
}
}
/// <summary>
/// 设置主相机的激活状态
/// </summary>
/// <param name="isActive"></param>
public void SetMainCameraActive(bool isActive)
{
if(null == _mainCamera || null == _mainCamera.gameObject)
return;
if (isActive)
_mainCamera.enabled = true;
_mainCamera.gameObject.SetActive(isActive);
}
/// <summary>
/// 设置UITop相机的激活状态
/// </summary>
/// <param name="isOpen"></param>
public void SetUITopCameraActive(bool isOpen)
{
if (_uiTopCamera != null)
{
_uiTopCamera.gameObject.SetActive(isOpen);
}
}
/// <summary>
/// 检查主相机是否激活
/// </summary>
/// <returns></returns>
public bool CheckMainCameraIsActive()
{
if (!_mainCamera)
return false;
return _mainCamera.gameObject.activeSelf;
}
/// <summary>
/// 切换主相机
/// </summary>
/// <param name="camera"></param>
public void SwitchMainCamera(Camera camera)
{
if (null == camera || camera == _mainCamera)
return;
_usedMainCameraStack.Push(_mainCamera);
_SwitchCameraPurely(camera);
}
/// <summary>
/// 还原主相机
/// </summary>
public void RevertMainCamera()
{
// DebugUtil.LogError("还原相机");
if (_usedMainCameraStack.Count == 0)
{
DebugUtil.LogError($"_usedMainCameraStack count is 0");
return;
}
Camera _lastMainCamera = GetOutMostCameraInStack();
if (_lastMainCamera == null)
{
DebugUtil.Log($"相机栈中找不到旧的使用过的主相机");
return;
}
_SwitchCameraPurely(_lastMainCamera);
}
private void _SwitchCameraPurely(Camera camera)
{
if (null == camera || _mainCamera == camera)
return;
Camera currCamera = _mainCamera;
if (null != currCamera)
DeActiveMainCamera(currCamera);
_mainCamera = camera;
ActiveMainCamera(_mainCamera);
AfterSwitchMainCamera?.Invoke(_mainCamera);
}
private Camera GetOutMostCameraInStack()
{
Camera result = null;
int popCount = 1;
foreach (Camera 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;
}
/// <summary>
/// 激活主相机
/// </summary>
/// <param name="cam"></param>
private void ActiveMainCamera(Camera cam)
{
cam.targetTexture = DefaultRenderTarget; // 一定先赋值rt再激活
cam.gameObject.SetActive(true);
}
/// <summary>
/// 禁用主相机
/// </summary>
/// <param name="cam"></param>
private void DeActiveMainCamera(Camera cam)
{
cam.gameObject.SetActive(false);
}
}
}