using System.Reflection; using Framework.RenderFeature; using Framework.Timer; using Framework.Utils.SingletonTemplate; using Game.Component; using Unity.Mathematics; using UnityEngine; using UnityEngine.Rendering; using UnityEngine.Rendering.Universal; namespace System { [System.Flags , Serializable] public enum BlurEffectType { Blur = 1 << 1, Gray = 1 << 2 } public class CameraEffectUtils : MgrBase { private UniversalRendererData _gameRendererData; private UniversalRendererData _uiRendererData; private BlurAnim _gameBlurAnim; private VolumeEffectUtils _volumeEffectUtils; public VolumeEffectUtils VolumeEffectUtils { get { if (this._volumeEffectUtils == null) { this._volumeEffectUtils = UnityEngine.Object.FindObjectOfType(); } return this._volumeEffectUtils; } } protected override void OnCreateMge() { // return; var allConfiguredRenderPipelines = (UniversalRenderPipelineAsset) GraphicsSettings.currentRenderPipeline; var universalRendererData = GetRenderData(allConfiguredRenderPipelines); this._gameRendererData = (UniversalRendererData) universalRendererData[0]; this._uiRendererData = (UniversalRendererData) universalRendererData[1]; this._gameBlurAnim = new BlurAnim(); // SetGameCamBlur(0, 0, null); } public static ScriptableRendererData[] GetRenderData(UniversalRenderPipelineAsset asset) { var type = asset.GetType(); var propertyInfo = type.GetField("m_RendererDataList", BindingFlags.Instance | BindingFlags.NonPublic); if (propertyInfo == null) { return null; } var scriptableRenderData = (ScriptableRendererData[]) propertyInfo.GetValue(asset); return scriptableRenderData; } public void SetGameGray(bool isGray) { if (this._gameBlurAnim != null) { this._gameBlurAnim.Setting.isGray = isGray; } foreach (var rendererFeature in this._gameRendererData.rendererFeatures) { if (rendererFeature.name.Equals("GaussBlurFeature")) { if (rendererFeature is GaussBlurFeature gaussBlurFeature) { gaussBlurFeature.setting.isGray = isGray; } return; } } } public void SetGameCamBlur(float target, float time, Action callback , BlurEffectType blurEffectType = BlurEffectType.Blur | BlurEffectType.Gray) { // return; foreach (var rendererFeature in this._gameRendererData.rendererFeatures) { if (rendererFeature.name.Equals("GaussBlurFeature")) { if (rendererFeature is GaussBlurFeature gaussBlurFeature) { gaussBlurFeature.setting.isGray = blurEffectType.HasFlag(BlurEffectType.Gray); gaussBlurFeature.setting.isBlur = blurEffectType.HasFlag(BlurEffectType.Blur); this._gameBlurAnim.PlayAnim(() => { callback?.Invoke(); }, gaussBlurFeature, target, time); } return; } } } /// /// 设置色差效果 /// /// 色差强度 /// 过度时间 public void SetAberration(float intensity, float time) { if (VolumeEffectUtils != null) { VolumeEffectUtils.SetAberration(intensity , time); } } private class BlurAnim { private float _startValue; private float _targetValue; private TimeHandler _timeHandler; private GaussBlurFeature _feature; private GaussBlurFeature.Setting _setting; private Action _action; public GaussBlurFeature.Setting Setting => this._setting; public void PlayAnim(Action callback, GaussBlurFeature feature, float target, float time) { this._feature = feature; this._setting = feature.setting; this._startValue = _setting.blurProgress; this._targetValue = target; this._action = callback; // this._setting.enable = true; this._feature.SetActive(true); if (time <= 0) { this.OnComplete (); return; } this._timeHandler = GameUpdateMgr.Instance.CreateTimer(time, this.OnComplete, this.OnProgress); } public void Stop() { this._timeHandler?.Kill(); this._action = null; this._feature.SetActive(this._setting.blurProgress > 0); } void OnProgress(float progress) { this._setting.blurProgress = math.lerp(this._startValue, this._targetValue, progress); } void OnComplete() { this._setting.blurProgress = this._targetValue; this._action?.Invoke(); this.Stop(); } } } }