using System.Collections.Generic; using UnityEngine.Rendering.PostProcessing; using UnityEngine; //用于表现的全局效果 timescale 后处理参数等 namespace Game { public delegate void GlobalEffectHandler(float scale); public enum EGlobalEffectType { Timescale, Aberration, Fov, Max, } public class GlobalEffectInfo { public float MFrom; public float MTo; public float MTimeDuration; public float MTimeLeft; public float MTimeDelay; } public class GlobalEffectManager : ManagerBase { private Dictionary> _mGlobalEffectDict = new Dictionary>(); private Dictionary _mGlobalEffectHandlerDict; public GlobalEffectManager() { } public override void OnCreate() { for (int i = 0; i < (int)EGlobalEffectType.Max; i++) { _mGlobalEffectDict[(EGlobalEffectType)i] = new Queue(); } _mGlobalEffectHandlerDict = new Dictionary(){ {EGlobalEffectType.Timescale,SetTimeScale}, {EGlobalEffectType.Aberration,SetAberration}, {EGlobalEffectType.Fov,SetFov}, }; } public override void Update() { foreach (var item in _mGlobalEffectDict) { var type = item.Key; var infoQueue = item.Value; if (infoQueue.Count == 0) { continue; } var info = infoQueue.Peek(); if (info.MTimeLeft <= 0) { continue; } if (info.MTimeDelay > 0) { info.MTimeDelay -= Time.unscaledDeltaTime; continue; } info.MTimeDelay = 0; var pastRate = (info.MTimeDuration - info.MTimeLeft) / info.MTimeDuration; var scaleRate = pastRate * pastRate;//y=x^2曲线 var scaleDir = info.MTo - info.MFrom; var targetScale = info.MFrom + scaleDir * scaleRate; info.MTimeLeft -= Time.unscaledDeltaTime; if (info.MTimeLeft <= 0) { info.MTimeLeft = 0; targetScale = info.MTo; infoQueue.Dequeue(); } SetScale(type, targetScale); } } public override void OnDestroy() { } public void SetEffect(EGlobalEffectType type, float scale) { SetEffectLerp(type, scale, scale, 0); } public void SetEffectLerp(EGlobalEffectType type, float scaleFrom, float scaleTo, float duration, float delay = 0) { //清空队列 并且设置当前值 SetScale(type, scaleFrom); var infoQueue = _mGlobalEffectDict[type]; infoQueue.Clear(); var info = new GlobalEffectInfo(); info.MFrom = scaleFrom; info.MTo = scaleTo; info.MTimeDuration = duration; info.MTimeLeft = duration; info.MTimeDelay = delay; infoQueue.Enqueue(info); } public void AppendEffectLerp(EGlobalEffectType type, float scaleFrom, float scaleTo, float duration, float delay = 0) { //加入队列 var infoQueue = _mGlobalEffectDict[type]; var info = new GlobalEffectInfo(); info.MFrom = scaleFrom; info.MTo = scaleTo; info.MTimeDuration = duration; info.MTimeLeft = duration; info.MTimeDelay = delay; infoQueue.Enqueue(info); } private void SetScale(EGlobalEffectType type, float scale) { _mGlobalEffectHandlerDict[type](scale); } private void SetTimeScale(float scale) { Time.timeScale = scale; } private void SetAberration(float scale) { var setting = Util.GetPostProcessSetting(); setting.intensity.value = scale; } private void SetFov(float scale) { var virtualCamera = Util.GetVirtualCamera(); var normalFOV = 25;//TODO 跟随相机设置 virtualCamera.m_Lens.FieldOfView = scale * normalFOV; } } public abstract partial class Util { public static void SetTimeScale(float scale) { GlobalEffectManager.Instance.SetEffect(EGlobalEffectType.Timescale, scale); } public static void SetGlobalEffect(EGlobalEffectType type, float scaleFrom, float scaleTo, float duration) { GlobalEffectManager.Instance.SetEffectLerp(type, scaleFrom, scaleTo, duration); } public static void AppendGlobalEffect(EGlobalEffectType type, float scaleFrom, float scaleTo, float duration) { GlobalEffectManager.Instance.AppendEffectLerp(type, scaleFrom, scaleTo, duration); } public static void SetTimeScaleEffect(float scaleFrom, float scaleTo, float duration) { SetGlobalEffect(EGlobalEffectType.Timescale, scaleFrom, scaleTo, duration); } public static void SetAberrationEffect(float scaleFrom, float scaleTo, float duration) { SetGlobalEffect(EGlobalEffectType.Aberration, scaleFrom, scaleTo, duration); } public static void SetFovEffect(float scaleFrom, float scaleTo, float duration) { SetGlobalEffect(EGlobalEffectType.Fov, scaleFrom, scaleTo, duration); } public static void AppendTimeScaleEffect(float scaleFrom, float scaleTo, float duration) { AppendGlobalEffect(EGlobalEffectType.Timescale, scaleFrom, scaleTo, duration); } public static void AppendAberrationEffect(float scaleFrom, float scaleTo, float duration) { AppendGlobalEffect(EGlobalEffectType.Aberration, scaleFrom, scaleTo, duration); } public static void AppendFovEffect(float scaleFrom, float scaleTo, float duration) { AppendGlobalEffect(EGlobalEffectType.Fov, scaleFrom, scaleTo, duration); } } }