Files
aibis-dream/Assets/Scripts/Framework/OtherKit/CameraKit.cs
T
2025-01-08 22:57:58 +08:00

220 lines
7.4 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using AibisDream.FixSystem;
using AibisDream.Kit;
using Cinemachine;
using DG.Tweening;
using DG.Tweening.Core;
using DG.Tweening.Plugins.Options;
using UnityEngine;
using Yarn.Unity;
namespace AibisDream.Framework
{
public class CameraKit : SingletonBase<CameraKit>
{
private const int LowPriority = 1;
private const int HighPriority = 10;
#region 相机组件
private CinemachineBrain _cameraBrain;
private readonly Dictionary<FixState, ICinemachineCamera> _virtualCameraDict = new();
private readonly Dictionary<FixState, CamState> _camInitStateDict = new();
private FixState _curFixState;
private CamState _curInitState;
private struct CamState
{
public Vector3 pos;
public float initOrthoSize;
}
#endregion
private CameraKit()
{
}
public override void OnSingletonInit()
{
_cameraBrain = Camera.main?.GetComponent<CinemachineBrain>();
_curFixState = FixState.Default;
}
#region 相机信息注册
public void RegisterCamera(FixState camType, ICinemachineCamera virtualCamera)
{
_virtualCameraDict[camType] = virtualCamera;
var initState = new CamState
{
pos = virtualCamera.VirtualCameraGameObject.transform.localPosition,
initOrthoSize = virtualCamera.VirtualCameraGameObject.gameObject
.GetComponent<CinemachineVirtualCamera>().m_Lens.OrthographicSize
};
_camInitStateDict[camType] = initState;
}
public void UnRegisterCamera(FixState camType, ICinemachineCamera virtualCamera)
{
if (!_virtualCameraDict.TryGetValue(camType, out var curCam)) return;
if (virtualCamera == curCam)
{
_virtualCameraDict.Remove(camType);
_camInitStateDict.Remove(camType);
}
}
public void UnRegisterCamera(FixState camType)
{
_virtualCameraDict.Remove(camType);
_camInitStateDict.Remove(camType);
}
public void RemoveAllCam()
{
_virtualCameraDict.Clear();
_camInitStateDict.Clear();
}
#endregion
/// <summary>
/// 切换相机
/// </summary>
/// <param name="camType"></param>
public IEnumerator SwitchCamera(FixState camType)
{
if (_curFixState == camType)
{
yield break;
}
if (!_virtualCameraDict.ContainsKey(camType))
{
Debug.Log($"{camType.ToString()}相机未注册");
yield break;
}
foreach (var camPair in _virtualCameraDict)
{
if (camPair.Key == camType) camPair.Value.Priority = HighPriority;
if (camPair.Key != camType) camPair.Value.Priority = LowPriority;
}
_curInitState = _camInitStateDict[camType];
yield return new WaitForSeconds(_cameraBrain.m_DefaultBlend.BlendTime);
}
public Tween TransCamera(Vector3 targetPos, float targetOrthographicSize, float duration)
{
// 寻找现在正在激活的相机
var curCamera = _cameraBrain.ActiveVirtualCamera;
var sq = DOTween.Sequence();
// 移动
sq.Join(curCamera.DOLocalMove(targetPos, duration));
// 缩放
sq.Join(curCamera.DOOrthoSize(targetOrthographicSize, duration));
return sq;
}
public Tween ReturnInitCamera(float duration)
{
return TransCamera(_curInitState.pos, _curInitState.initOrthoSize, duration);
}
public IEnumerator TransCameraAsync(Vector3 targetPos, float duration)
{
var curCamera = _cameraBrain.ActiveVirtualCamera;
yield return curCamera.DOLocalMove(targetPos, duration).WaitForCompletion();
}
public IEnumerator TransCameraAsync(Vector3 targetPos, float targetOrthographicSize, float duration)
{
yield return TransCamera(targetPos, targetOrthographicSize, duration).WaitForCompletion();
}
public IEnumerator ReturnInitCameraAsync(float duration)
{
yield return ReturnInitCamera(duration).WaitForCompletion();
}
// 方法已废弃,后面改成用Cinemachine的Shake
[Obsolete]
public IEnumerator ShakeCamera(float duration, float strength, int vibrate)
{
var curCamera = _cameraBrain.ActiveVirtualCamera;
yield return curCamera.VirtualCameraGameObject.transform
.DOShakePosition(duration, strength, vibrate, 90, false, false)
.WaitForCompletion();
}
}
public static class CinemachineExtension
{
public static TweenerCore<Vector3, Vector3, VectorOptions> DOLocalMove(this ICinemachineCamera camera,
Vector3 targetPos, float duration)
{
var transform = camera.VirtualCameraGameObject.gameObject.transform;
return transform.DOLocalMove(targetPos, duration);
}
public static TweenerCore<float, float, FloatOptions> DOOrthoSize(this ICinemachineCamera camera,
float endValue, float duration)
{
var virtualCamera = camera.VirtualCameraGameObject.gameObject.GetComponent<CinemachineVirtualCamera>();
var currentOrthoSize = virtualCamera.m_Lens.OrthographicSize;
return DOTween.To(() => currentOrthoSize, x => currentOrthoSize = x, endValue, duration)
.OnUpdate(() => virtualCamera.m_Lens.OrthographicSize = currentOrthoSize);
}
}
public static class CameraCommand
{
[YarnCommand("return_init_camera")]
public static IEnumerator ReturnInitCamera(float duration = 1f)
{
return CameraKit.Instance.ReturnInitCameraAsync(duration);
}
[YarnCommand("trans_camera")]
public static IEnumerator TransCameraAsync(float x, float y, float targetOrthographicSize, float duration)
{
Vector3 targetPos = new Vector3(x, y, -10);
return CameraKit.Instance.TransCameraAsync(targetPos, targetOrthographicSize, duration);
}
[YarnCommand("trans_camera_pos")]
public static IEnumerator TransCameraAsync(float x, float y, float duration)
{
Vector3 targetPos = new Vector3(x, y, -10);
return CameraKit.Instance.TransCameraAsync(targetPos, duration);
}
[YarnCommand("shake_camera")]
public static IEnumerator ShakeCamera(float duration, float strength, int vibrate = 10)
{
return CameraKit.Instance.ShakeCamera(duration, strength, vibrate);
}
[YarnCommand("switch_camera")]
public static IEnumerator SwitchCamera(string targetStateStr)
{
// 字符串转枚举
if (!Enum.TryParse<FixState>(targetStateStr, out var targetState))
{
Debug.Log($"{targetStateStr}不在FixState枚举中");
yield break;
}
yield return CameraKit.Instance.SwitchCamera(targetState);
}
}
}