2
0
Fork 0
You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

166 lines
6.5 KiB
C#

using UnityEngine;
using UnityEngine.Rendering.PostProcessing;
using Cinemachine;
namespace Game
{
/// <summary>
/// 主相机及后处理在此管理
/// </summary>
public class CameraManager : ManagerBase<CameraManager>
{
public GameCamera MGameCamera;
private PostProcessVolume _mPostProcessVolume;
private Camera _mMainCamera;
private CinemachineVirtualCamera _mMainCameraVirtual;
private CinemachineTargetGroup _mMainCameraGroup;
private CinemachineImpulseSource _mMainCollisionImpulseSource;
private Transform[] _mTargets = new Transform[2];//TODO 可扩展性
private Transform[] _mTargetsAgent = new Transform[2];//TODO 可扩展性
public CameraManager()
{
}
public override void OnCreate()
{
var cameraRoot = GameObject.Find("CameraRoot");
Object.DontDestroyOnLoad(cameraRoot);
_mMainCamera = cameraRoot.transform.Find("Camera_Main").GetComponent<Camera>();
_mMainCameraVirtual = cameraRoot.transform.Find("Camera_Virtual").GetComponent<CinemachineVirtualCamera>();
_mMainCollisionImpulseSource = cameraRoot.transform.Find("Camera_Virtual").GetComponent<CinemachineImpulseSource>();
_mMainCameraGroup = cameraRoot.transform.Find("Camera_Group").GetComponent<CinemachineTargetGroup>();
_mMainCameraGroup.m_Targets = new CinemachineTargetGroup.Target[2];
MGameCamera = _mMainCamera.GetComponent<GameCamera>();
MGameCamera.material.SetVector("_ScreenSize", new Vector4(Screen.width, Screen.height, 0, 0));
_mPostProcessVolume = _mMainCamera.GetComponent<PostProcessVolume>();
//TODO 有两个以上锁定目标时优化
var newTargt0 = PrefabManager.Instance.CreateGo("CameraTarget");
var newTargt1 = PrefabManager.Instance.CreateGo("CameraTarget");
newTargt0.transform.parent = cameraRoot.transform;
newTargt1.transform.parent = cameraRoot.transform;
_mTargetsAgent[0] = newTargt0.transform;
_mTargetsAgent[1] = newTargt1.transform;
_mMainCameraGroup.m_Targets[0].target = _mTargetsAgent[0];
_mMainCameraGroup.m_Targets[0].weight = 1;
_mMainCameraGroup.m_Targets[0].radius = 2.5f;
_mMainCameraGroup.m_Targets[1].target = _mTargetsAgent[1];
_mMainCameraGroup.m_Targets[1].weight = 1;
_mMainCameraGroup.m_Targets[1].radius = 2.5f;
//默认设置 TODO 好像没有用
// var brain = m_MainCamera.GetComponent<CinemachineBrain>();
// CinemachineImpulseManager.Instance.IgnoreTimeScale = true;
// brain.m_UpdateMethod = CinemachineBrain.UpdateMethod.LateUpdate;
// brain.m_IgnoreTimeScale = true;
}
public override void Update()
{
UpdateCameraTarget();//更新相机锁定目标
}
public override void FixedUpdate()
{
if (Util.IsLevelLoading())
{
return;
}
// UpdataBackground();//更新差速滚轴
}
public override void OnDestroy() { }
public void SetMainTarget(Transform target)
{
_mTargets[0] = target;
}
public void SetSubTarget(Transform target)
{
_mTargets[1] = target;
}
public void Shake()
{
_mMainCollisionImpulseSource.GenerateImpulse();
}
public Vector3 GetScreenPos(Vector3 pos)
{
var ret = _mMainCamera.WorldToScreenPoint(pos);
ret = new Vector3(ret.x, Screen.height - ret.y, ret.z);
return ret;
}
public T GetPostProcessSetting<T>() where T : PostProcessEffectSettings
{
return _mPostProcessVolume.profile.GetSetting<T>();
}
public CinemachineVirtualCamera GetVirtualCamera()
{
return _mMainCameraVirtual;
}
private void UpdateCameraTarget()
{
if (_mTargets[0] == null)
{
return;
}
if (_mTargets[1] == null)
{
_mTargets[1] = _mTargets[0];
}
_mTargetsAgent[0].position = _mTargets[0].position;
_mTargetsAgent[1].position = _mTargets[1].position;
ClampToLevel(_mTargetsAgent[0]);
ClampToLevel(_mTargetsAgent[1]);
}
private void ClampToLevel(Transform transform)
{
var pos = transform.position;
var start = pos + Vector3.up;
var x = pos.x;
var z = pos.z;
RaycastHit hitInfo;
if (Physics.Raycast(start, Vector3.back, out hitInfo, GameConst.LevelCameraOffsetZ, UtilPhysics.LayerMaskWall))
{
z = Mathf.Max(z, hitInfo.point.z + GameConst.LevelCameraOffsetZ);
}
if (Physics.Raycast(start, Vector3.left, out hitInfo, GameConst.LevelCameraOffsetX, UtilPhysics.LayerMaskWall))
{
x = Mathf.Max(x, hitInfo.point.x + GameConst.LevelCameraOffsetX);
}
else if (Physics.Raycast(start, Vector3.right, out hitInfo, GameConst.LevelCameraOffsetX, UtilPhysics.LayerMaskWall))
{
x = Mathf.Min(x, hitInfo.point.x - GameConst.LevelCameraOffsetX);
}
transform.position = new Vector3(x, 0, z);
}
}
public abstract partial class Util
{
public static void SetMainTarget(Transform target)
{
CameraManager.Instance.SetMainTarget(target);
}
public static void SetSubTarget(Transform target)
{
CameraManager.Instance.SetSubTarget(target);
}
public static void Shake()
{
CameraManager.Instance.Shake();
}
public static Vector3 GetScreenPos(Vector3 pos)
{
return CameraManager.Instance.GetScreenPos(pos);
}
public static T GetPostProcessSetting<T>() where T : PostProcessEffectSettings
{
return CameraManager.Instance.GetPostProcessSetting<T>();
}
public static CinemachineVirtualCamera GetVirtualCamera()
{
return CameraManager.Instance.GetVirtualCamera();
}
}
}