狗屎Minimax坏我代码

This commit is contained in:
SoulliesOfficial
2026-04-18 13:57:19 -04:00
parent 41140a2017
commit 7379583165
473 changed files with 34480 additions and 8069 deletions

View File

@@ -0,0 +1,226 @@
using System.Collections.Generic;
using SLSUtilities.Feedback;
using SLSUtilities.Rendering.PostProcessing;
using UnityEngine;
namespace Cielonos.MainGame.Effects.Feedback
{
/// <summary>
/// Anime ACES 震动事件。
/// </summary>
public struct AnimeACESShakeEvent
{
private static event ShakeDelegate OnEvent;
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
private static void RuntimeInitialization() { OnEvent = null; }
public delegate void ShakeDelegate(
FeedbackContext feedbackContext,
FloatCurveChannel exposureCurve,
FloatCurveChannel contrastCurve,
FloatCurveChannel saturationCurve,
FloatCurveChannel hueCurve,
ColorCurveChannel colorFilterCurve,
bool stop
);
public static void Register(ShakeDelegate callback) { OnEvent += callback; }
public static void Unregister(ShakeDelegate callback) { OnEvent -= callback; }
public static void Trigger(
FeedbackContext feedbackContext,
FloatCurveChannel exposureCurve = default,
FloatCurveChannel contrastCurve = default,
FloatCurveChannel saturationCurve = default,
FloatCurveChannel hueCurve = default,
ColorCurveChannel colorFilterCurve = default,
bool stop = false)
{
OnEvent?.Invoke(feedbackContext, exposureCurve, contrastCurve, saturationCurve, hueCurve, colorFilterCurve, stop);
}
}
/// <summary>
/// Anime ACES 震动实例。
/// </summary>
public class AnimeACESShakeInstance : ShakeInstanceBase
{
public readonly FloatCurveChannel ExposureCurve;
public readonly FloatCurveChannel ContrastCurve;
public readonly FloatCurveChannel SaturationCurve;
public readonly FloatCurveChannel HueCurve;
public readonly ColorCurveChannel ColorFilterCurve;
public AnimeACESShakeInstance(
FeedbackContext feedbackContext,
FloatCurveChannel exposureCurve,
FloatCurveChannel contrastCurve,
FloatCurveChannel saturationCurve,
FloatCurveChannel hueCurve,
ColorCurveChannel colorFilterCurve)
: base(feedbackContext.timeSettings, feedbackContext.player.TimeProvider, feedbackContext.duration)
{
ExposureCurve = exposureCurve;
ContrastCurve = contrastCurve;
SaturationCurve = saturationCurve;
HueCurve = hueCurve;
ColorFilterCurve = colorFilterCurve;
}
}
/// <summary>
/// AnimeACES 的震动聚合器。
/// </summary>
[AddComponentMenu("SLS Utilities/Feedback Shakers/Anime ACES Shaker")]
public class AnimeACESShaker : MonoBehaviour
{
private AnimeACES _component;
private float _initExposure;
private float _initContrast;
private float _initSaturation;
private float _initHue;
private Color _initColorFilter;
private bool _resolved;
private readonly List<AnimeACESShakeInstance> _activeShakes = new List<AnimeACESShakeInstance>();
private void Awake()
{
_resolved = TryResolve();
}
private void OnEnable()
{
AnimeACESShakeEvent.Register(OnShakeEvent);
}
private void OnDisable()
{
AnimeACESShakeEvent.Unregister(OnShakeEvent);
StopAll();
}
private void Update()
{
if (!_resolved || _activeShakes.Count == 0) return;
float additiveExposure = 0f;
float additiveContrast = 0f;
float additiveSaturation = 0f;
float additiveHue = 0f;
Color colorFilterAccum = Color.white;
bool hasColorFilter = false;
for (int i = _activeShakes.Count - 1; i >= 0; i--)
{
AnimeACESShakeInstance shake = _activeShakes[i];
shake.timer += shake.timeProvider.GetDeltaTime(shake.timeSettings);
float normalizedTime = shake.timer / shake.duration;
// Exposure
if (shake.ExposureCurve.active)
{
additiveExposure += shake.ExposureCurve.Evaluate(normalizedTime);
}
// Contrast
if (shake.ContrastCurve.active)
{
additiveContrast += shake.ContrastCurve.Evaluate(normalizedTime);
}
// Saturation
if (shake.SaturationCurve.active)
{
additiveSaturation += shake.SaturationCurve.Evaluate(normalizedTime);
}
// Hue
if (shake.HueCurve.active)
{
additiveHue += shake.HueCurve.Evaluate(normalizedTime);
}
// Color Filter
if (shake.ColorFilterCurve.active)
{
colorFilterAccum = shake.ColorFilterCurve.Evaluate(normalizedTime);
hasColorFilter = true;
}
if (shake.IsFinished)
{
_activeShakes.RemoveAt(i);
}
}
_component.exposure.value = _initExposure + additiveExposure;
_component.contrast.value = _initContrast + additiveContrast;
_component.saturation.value = _initSaturation + additiveSaturation;
_component.huePreservation.value = _initHue + additiveHue;
if (hasColorFilter) _component.colorFilter.value = colorFilterAccum;
if (_activeShakes.Count == 0)
{
Restore();
}
}
private void OnShakeEvent(
FeedbackContext feedbackContext,
FloatCurveChannel exposureCurve,
FloatCurveChannel contrastCurve,
FloatCurveChannel saturationCurve,
FloatCurveChannel hueCurve,
ColorCurveChannel colorFilterCurve,
bool stop)
{
if (stop) { StopAll(); return; }
if (!_resolved) _resolved = TryResolve();
if (!_resolved) return;
var instance = new AnimeACESShakeInstance(
feedbackContext,
exposureCurve,
contrastCurve,
saturationCurve,
hueCurve,
colorFilterCurve
);
_activeShakes.Add(instance);
}
private bool TryResolve()
{
if (_component != null) return true;
if (PostProcessingManager.Instance == null) return false;
if (!PostProcessingManager.Instance.GetVolumeComponent(out _component)) return false;
_initExposure = _component.exposure.value;
_initContrast = _component.contrast.value;
_initSaturation = _component.saturation.value;
_initHue = _component.huePreservation.value;
_initColorFilter = _component.colorFilter.value;
return true;
}
private void Restore()
{
if (!_resolved) return;
_component.exposure.value = _initExposure;
_component.contrast.value = _initContrast;
_component.saturation.value = _initSaturation;
_component.huePreservation.value = _initHue;
_component.colorFilter.value = _initColorFilter;
}
private void StopAll()
{
_activeShakes.Clear();
Restore();
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: fc3cd16e5556b7a4eb66e5385e4f4e60

View File

@@ -0,0 +1,209 @@
using System.Collections.Generic;
using SLSUtilities.Feedback;
using SLSUtilities.Rendering.PostProcessing;
using UnityEngine;
namespace Cielonos.MainGame.Effects.Feedback
{
/// <summary>
/// 色散震动事件。
/// </summary>
public struct ChromaticAberrationShakeEvent
{
private static event ShakeDelegate OnEvent;
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
private static void RuntimeInitialization() { OnEvent = null; }
public delegate void ShakeDelegate(
FeedbackContext feedbackContext,
FloatCurveChannel intensityCurve,
bool modifyCenter,
Vector2CurveChannel center,
bool modifyJitter,
FloatCurveChannel jitterCurve,
bool stop
);
public static void Register(ShakeDelegate callback) { OnEvent += callback; }
public static void Unregister(ShakeDelegate callback) { OnEvent -= callback; }
public static void Trigger(
FeedbackContext feedbackContext,
FloatCurveChannel intensityCurve,
bool modifyCenter = false,
Vector2CurveChannel center = default,
bool modifyJitter = false,
FloatCurveChannel jitterCurve = default,
bool stop = false)
{
OnEvent?.Invoke(feedbackContext, intensityCurve, modifyCenter, center, modifyJitter, jitterCurve, stop);
}
}
/// <summary>
/// 色散震动实例。
/// </summary>
public class ChromaticAberrationShakeInstance : ShakeInstanceBase
{
public readonly FloatCurveChannel intensityCurve;
public readonly bool modifyCenter;
public readonly Vector2CurveChannel center;
public readonly bool modifyJitter;
public readonly FloatCurveChannel jitterCurve;
public ChromaticAberrationShakeInstance(
FeedbackContext feedbackContext,
FloatCurveChannel intensityCurve,
bool modifyCenter,
Vector2CurveChannel center,
bool modifyJitter,
FloatCurveChannel jitterCurve)
: base(feedbackContext.timeSettings, feedbackContext.player.TimeProvider, feedbackContext.duration)
{
this.intensityCurve = intensityCurve;
this.modifyCenter = modifyCenter;
this.center = center;
this.modifyJitter = modifyJitter;
this.jitterCurve = jitterCurve;
}
}
/// <summary>
/// AdvancedChromaticAberration 的震动聚合器。
/// </summary>
[AddComponentMenu("SLS Utilities/Feedback Shakers/Chromatic Aberration Shaker")]
public class ChromaticAberrationShaker : MonoBehaviour
{
private AdvancedChromaticAberration _component;
private float _initialIntensity;
private Vector2 _initialCenter;
private float _initialJitter;
private bool _resolved;
private readonly List<ChromaticAberrationShakeInstance> _activeShakes = new List<ChromaticAberrationShakeInstance>();
private void Awake()
{
_resolved = TryResolve();
}
private void OnEnable()
{
ChromaticAberrationShakeEvent.Register(OnShakeEvent);
}
private void OnDisable()
{
ChromaticAberrationShakeEvent.Unregister(OnShakeEvent);
StopAll();
}
private void Update()
{
if (!_resolved || _activeShakes.Count == 0) return;
float additiveIntensity = 0f;
float absoluteIntensity = 0f;
bool hasAbsolute = false;
float additiveJitter = 0f;
Vector2 latestCenter = _initialCenter;
bool hasCenter = false;
for (int i = _activeShakes.Count - 1; i >= 0; i--)
{
ChromaticAberrationShakeInstance shake = _activeShakes[i];
shake.timer += shake.timeProvider.GetDeltaTime(shake.timeSettings);
float normalizedTime = shake.timer / shake.duration;
if (shake.intensityCurve.active)
{
float curveValue = shake.intensityCurve.Evaluate(normalizedTime);
if (shake.intensityCurve.relativeToInitial)
{
additiveIntensity += curveValue;
}
else
{
absoluteIntensity = curveValue;
hasAbsolute = true;
}
}
if (shake.modifyJitter && shake.jitterCurve.active)
{
additiveJitter += shake.jitterCurve.Evaluate(normalizedTime);
}
if (shake.modifyCenter)
{
latestCenter = shake.center.Evaluate(normalizedTime, _initialCenter);
hasCenter = true;
}
if (shake.IsFinished)
{
_activeShakes.RemoveAt(i);
}
}
float finalIntensity = hasAbsolute ? absoluteIntensity : _initialIntensity + additiveIntensity;
_component.intensity.value = finalIntensity;
_component.jitterIntensity.value = _initialJitter + additiveJitter;
if (hasCenter) _component.center.value = latestCenter;
if (_activeShakes.Count == 0)
{
Restore();
}
}
private void OnShakeEvent(
FeedbackContext feedbackContext,
FloatCurveChannel intensityCurve,
bool modifyCenter,
Vector2CurveChannel center,
bool modifyJitter,
FloatCurveChannel jitterCurve,
bool stop)
{
if (stop) { StopAll(); return; }
if (!_resolved) _resolved = TryResolve();
if (!_resolved) return;
var instance = new ChromaticAberrationShakeInstance(
feedbackContext, intensityCurve, modifyCenter, center, modifyJitter, jitterCurve
);
_activeShakes.Add(instance);
}
private bool TryResolve()
{
if (_component != null) return true;
if (PostProcessingManager.Instance == null) return false;
if (!PostProcessingManager.Instance.GetVolumeComponent(out _component)) return false;
_initialIntensity = _component.intensity.value;
_initialCenter = _component.center.value;
_initialJitter = _component.jitterIntensity.value;
return true;
}
private void Restore()
{
if (!_resolved) return;
_component.intensity.value = _initialIntensity;
_component.center.value = _initialCenter;
_component.jitterIntensity.value = _initialJitter;
}
private void StopAll()
{
_activeShakes.Clear();
Restore();
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: c15f7649d43e18b448c0acb1f9163f2c

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: d812b009316d71f4fbfc8abb6e76bc18
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,151 @@
using System.Collections.Generic;
using SLSUtilities.Feedback;
using Unity.Cinemachine;
using UnityEngine;
namespace Cielonos.MainGame.Effects.Feedback
{
/// <summary>
/// 单个FOV震动实例的运行时状态。
/// </summary>
public class CameraFovShakeInstance : ShakeInstanceBase
{
public FloatCurveChannel fovCurve;
public CameraFovShakeInstance(FeedbackTimeSettings timeSettings, IFeedbackTimeProvider timeProvider,
FloatCurveChannel fovCurve, float duration) : base(timeSettings, timeProvider, duration)
{
this.fovCurve = fovCurve;
}
}
/// <summary>
/// 摄像机视野角(FOV)震动事件,用于解耦 Action 与 Shaker。
/// </summary>
public struct CameraFovShakeEvent
{
private static event ShakeDelegate OnEvent;
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
private static void RuntimeInitialization() { OnEvent = null; }
public delegate void ShakeDelegate(
FeedbackContext feedbackContext,
FloatCurveChannel fovCurve,
bool stop
);
public static void Register(ShakeDelegate callback) { OnEvent += callback; }
public static void Unregister(ShakeDelegate callback) { OnEvent -= callback; }
public static void Trigger(
FeedbackContext feedbackContext,
FloatCurveChannel fovCurve,
bool stop = false)
{
OnEvent?.Invoke(feedbackContext, fovCurve, stop);
}
}
/// <summary>
/// CinemachineCamera FOV 震动聚合器。挂载于 CinemachineCamera 上,
/// 监听 CameraFovShakeEvent叠加驱动 Lens.FieldOfView。
/// </summary>
[AddComponentMenu("Cielonos/Feedback Shakers/Camera FOV Shaker")]
[RequireComponent(typeof(CinemachineCamera))]
public class CameraFovShaker : MonoBehaviour
{
private CinemachineCamera _camera;
private float _initialFov;
private readonly List<CameraFovShakeInstance> _activeShakes = new List<CameraFovShakeInstance>();
private void Awake()
{
_camera = GetComponent<CinemachineCamera>();
_initialFov = _camera.Lens.FieldOfView;
}
private void OnEnable()
{
CameraFovShakeEvent.Register(OnShakeEvent);
}
private void OnDisable()
{
CameraFovShakeEvent.Unregister(OnShakeEvent);
StopAll();
}
private void Update()
{
if (_camera == null) return;
if (_activeShakes.Count == 0)
{
SetFov(_initialFov);
return;
}
float additiveFov = 0f;
float absoluteFov = 0f;
bool hasAbsolute = false;
for (int i = _activeShakes.Count - 1; i >= 0; i--)
{
CameraFovShakeInstance shake = _activeShakes[i];
shake.Tick();
float normalizedTime = shake.timer / shake.duration;
if (shake.fovCurve.relativeToInitial)
{
additiveFov += shake.fovCurve.Evaluate(normalizedTime);
}
else
{
absoluteFov = shake.fovCurve.Evaluate(normalizedTime);
hasAbsolute = true;
}
if (shake.IsFinished)
{
_activeShakes.RemoveAt(i);
}
}
float finalFov = hasAbsolute ? absoluteFov : _initialFov + additiveFov;
SetFov(finalFov);
}
private void OnShakeEvent(
FeedbackContext feedbackContext,
FloatCurveChannel fovCurve,
bool stop)
{
if (stop) { StopAll(); return; }
var instance = new CameraFovShakeInstance(
feedbackContext.timeSettings,
feedbackContext.player.TimeProvider,
fovCurve,
feedbackContext.duration
);
_activeShakes.Add(instance);
}
private void SetFov(float fov)
{
LensSettings lens = _camera.Lens;
lens.FieldOfView = fov;
_camera.Lens = lens;
}
private void StopAll()
{
_activeShakes.Clear();
if (_camera != null)
{
SetFov(_initialFov);
}
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: dbbfef1d7cc479c47837ff154e4a7c5e

View File

@@ -0,0 +1,153 @@
using System.Collections.Generic;
using SLSUtilities.Feedback;
using Unity.Cinemachine;
using UnityEngine;
namespace Cielonos.MainGame.Effects.Feedback
{
/// <summary>
/// 单个位移震动实例的运行时状态。
/// </summary>
public class CameraPositionShakeInstance : ShakeInstanceBase
{
public FloatCurveChannel intensityCurve;
public Vector3 amplitude;
public CameraPositionShakeInstance(
FeedbackTimeSettings timeSettings,
IFeedbackTimeProvider timeProvider,
FloatCurveChannel intensityCurve,
Vector3 amplitude,
float duration)
: base(timeSettings, timeProvider, duration)
{
this.intensityCurve = intensityCurve;
this.amplitude = amplitude;
}
/// <summary>
/// 计算当前帧的偏移量。
/// </summary>
public Vector3 Evaluate()
{
float normalizedTime = duration > 0 ? timer / duration : 1f;
float curveValue = intensityCurve.Evaluate(normalizedTime);
return amplitude * curveValue;
}
}
/// <summary>
/// 摄像机位移震动事件,用于解耦 Action 与 Shaker。
/// </summary>
public struct CameraPositionShakeEvent
{
private static event ShakeDelegate OnEvent;
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
private static void RuntimeInitialization() { OnEvent = null; }
public delegate void ShakeDelegate(
FeedbackContext feedbackContext,
FloatCurveChannel intensityCurve,
Vector3 amplitude,
bool stop
);
public static void Register(ShakeDelegate callback) { OnEvent += callback; }
public static void Unregister(ShakeDelegate callback) { OnEvent -= callback; }
public static void Trigger(
FeedbackContext feedbackContext,
FloatCurveChannel intensityCurve,
Vector3 amplitude,
bool stop = false)
{
OnEvent?.Invoke(feedbackContext, intensityCurve, amplitude, stop);
}
}
/// <summary>
/// Cinemachine 位移震动器。挂载于 CinemachineCamera 上,
/// 监听 CameraPositionShakeEvent驱动 CinemachineCameraOffset 实现叠加震动。
/// </summary>
[AddComponentMenu("Cielonos/Feedback Shakers/Camera Position Shaker")]
[RequireComponent(typeof(CinemachineCamera))]
[RequireComponent(typeof(CinemachineCameraOffset))]
public class CinemachinePositionShaker : MonoBehaviour
{
private CinemachineCameraOffset _offsetComponent;
private Vector3 _initialOffset;
private readonly List<CameraPositionShakeInstance> _activeShakes = new List<CameraPositionShakeInstance>();
private void Awake()
{
_offsetComponent = GetComponent<CinemachineCameraOffset>();
_initialOffset = _offsetComponent.Offset;
}
private void OnEnable()
{
CameraPositionShakeEvent.Register(OnShakeEvent);
}
private void OnDisable()
{
CameraPositionShakeEvent.Unregister(OnShakeEvent);
StopAll();
}
private void Update()
{
if (_offsetComponent == null) return;
if (_activeShakes.Count == 0)
{
_offsetComponent.Offset = _initialOffset;
return;
}
Vector3 totalOffset = Vector3.zero;
for (int i = _activeShakes.Count - 1; i >= 0; i--)
{
CameraPositionShakeInstance shake = _activeShakes[i];
shake.Tick();
totalOffset += shake.Evaluate();
if (shake.IsFinished)
{
_activeShakes.RemoveAt(i);
}
}
_offsetComponent.Offset = _initialOffset + totalOffset;
}
private void OnShakeEvent(
FeedbackContext feedbackContext,
FloatCurveChannel intensityCurve,
Vector3 amplitude,
bool stop)
{
if (stop) { StopAll(); return; }
var instance = new CameraPositionShakeInstance(
feedbackContext.timeSettings,
feedbackContext.player.TimeProvider,
intensityCurve,
amplitude,
feedbackContext.duration
);
_activeShakes.Add(instance);
}
private void StopAll()
{
_activeShakes.Clear();
if (_offsetComponent != null)
{
_offsetComponent.Offset = _initialOffset;
}
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 08a7d10a0525af448902b60235ecf4fc

View File

@@ -0,0 +1,153 @@
using System.Collections.Generic;
using SLSUtilities.Cinemachine;
using SLSUtilities.Feedback;
using Unity.Cinemachine;
using UnityEngine;
namespace Cielonos.MainGame.Effects.Feedback
{
/// <summary>
/// 单个旋转震动实例的运行时状态。
/// </summary>
public class CameraRotationShakeInstance : ShakeInstanceBase
{
public FloatCurveChannel intensityCurve;
public Vector3 amplitude;
public CameraRotationShakeInstance(
FeedbackTimeSettings timeSettings,
IFeedbackTimeProvider timeProvider,
FloatCurveChannel intensityCurve,
Vector3 amplitude,
float duration)
: base(timeSettings, timeProvider, duration)
{
this.intensityCurve = intensityCurve;
this.amplitude = amplitude;
}
/// <summary>
/// 计算当前帧的偏移量。
/// </summary>
public Vector3 Evaluate()
{
float normalizedTime = duration > 0 ? timer / duration : 1f;
float curveValue = intensityCurve.Evaluate(normalizedTime);
return amplitude * curveValue;
}
}
/// <summary>
/// 摄像机旋转震动事件,用于解耦 Action 与 Shaker。
/// </summary>
public struct CameraRotationShakeEvent
{
private static event ShakeDelegate OnEvent;
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
private static void RuntimeInitialization() { OnEvent = null; }
public delegate void ShakeDelegate(
FeedbackContext feedbackContext,
FloatCurveChannel intensityCurve,
Vector3 amplitude,
bool stop
);
public static void Register(ShakeDelegate callback) { OnEvent += callback; }
public static void Unregister(ShakeDelegate callback) { OnEvent -= callback; }
public static void Trigger(
FeedbackContext feedbackContext,
FloatCurveChannel intensityCurve,
Vector3 amplitude,
bool stop = false)
{
OnEvent?.Invoke(feedbackContext, intensityCurve, amplitude, stop);
}
}
/// <summary>
/// Cinemachine 旋转震动器。挂载于 CinemachineCamera 上,
/// 监听 CameraRotationShakeEvent驱动 CinemachineRotationOffset 实现叠加震动。
/// X/Y 作用于 FollowTarget 旋转Z 作用于 Dutch 倾斜。
/// </summary>
[AddComponentMenu("Cielonos/Feedback Shakers/Camera Rotation Shaker")]
[RequireComponent(typeof(CinemachineCamera))]
[RequireComponent(typeof(CinemachineRotationOffset))]
public class CinemachineRotationShaker : MonoBehaviour
{
private CinemachineRotationOffset _rotationOffset;
private Vector3 _initialRotation;
private readonly List<CameraRotationShakeInstance> _activeShakes = new List<CameraRotationShakeInstance>();
private void Awake()
{
_rotationOffset = GetComponent<CinemachineRotationOffset>();
_initialRotation = _rotationOffset.rotationOffset;
}
private void OnEnable()
{
CameraRotationShakeEvent.Register(OnShakeEvent);
}
private void OnDisable()
{
CameraRotationShakeEvent.Unregister(OnShakeEvent);
StopAll();
}
private void Update()
{
if (_rotationOffset == null) return;
if (_activeShakes.Count == 0)
{
_rotationOffset.rotationOffset = _initialRotation;
return;
}
Vector3 totalOffset = Vector3.zero;
for (int i = _activeShakes.Count - 1; i >= 0; i--)
{
CameraRotationShakeInstance shake = _activeShakes[i];
shake.Tick();
totalOffset += shake.Evaluate();
if (shake.IsFinished)
{
_activeShakes.RemoveAt(i);
}
}
_rotationOffset.rotationOffset = _initialRotation + totalOffset;
}
private void OnShakeEvent(
FeedbackContext feedbackContext,
FloatCurveChannel intensityCurve,
Vector3 amplitude,
bool stop)
{
if (stop) { StopAll(); return; }
_activeShakes.Add(new CameraRotationShakeInstance(
feedbackContext.timeSettings,
feedbackContext.player.TimeProvider,
intensityCurve,
amplitude,
feedbackContext.duration
));
}
private void StopAll()
{
_activeShakes.Clear();
if (_rotationOffset != null)
{
_rotationOffset.rotationOffset = _initialRotation;
}
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 5c54de88d6cf4304180fbd641401b1b6

View File

@@ -0,0 +1,175 @@
using System.Collections.Generic;
using SLSUtilities.Feedback;
using SLSUtilities.Rendering.PostProcessing;
using UnityEngine;
namespace Cielonos.MainGame.Effects.Feedback
{
/// <summary>
/// 径向模糊震动事件。
/// </summary>
public struct RadialBlurShakeEvent
{
private static event ShakeDelegate OnEvent;
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
private static void RuntimeInitialization() { OnEvent = null; }
public delegate void ShakeDelegate(FeedbackContext feedbackContext, FloatCurveChannel intensityCurve,
bool modifyCenter, Vector2 center, bool stop);
public static void Register(ShakeDelegate callback) { OnEvent += callback; }
public static void Unregister(ShakeDelegate callback) { OnEvent -= callback; }
public static void Trigger(
FeedbackContext feedbackContext, FloatCurveChannel intensityCurve,
bool modifyCenter = false, Vector2 center = default, bool stop = false)
{
OnEvent?.Invoke(feedbackContext, intensityCurve, modifyCenter, center, stop);
}
}
/// <summary>
/// 径向模糊震动实例。
/// </summary>
public class RadialBlurShakeInstance : ShakeInstanceBase
{
public readonly FloatCurveChannel intensityCurve;
public readonly bool modifyCenter;
public readonly Vector2 center;
public RadialBlurShakeInstance(
FeedbackContext feedbackContext, FloatCurveChannel intensityCurve, bool modifyCenter, Vector2 center) :
base(feedbackContext.timeSettings, feedbackContext.player.TimeProvider, feedbackContext.duration)
{
this.intensityCurve = intensityCurve;
this.modifyCenter = modifyCenter;
this.center = center;
}
}
/// <summary>
/// RadialBlur 的震动聚合器。
/// </summary>
[AddComponentMenu("SLS Utilities/Feedback Shakers/Radial Blur Shaker")]
public class RadialBlurShaker : MonoBehaviour
{
private RadialBlur _component;
private float _initialBlurRadius;
private float _initialCenterX;
private float _initialCenterY;
private bool _resolved;
private readonly List<RadialBlurShakeInstance> _activeShakes = new List<RadialBlurShakeInstance>();
private void Awake()
{
_resolved = TryResolve();
}
private void OnEnable()
{
RadialBlurShakeEvent.Register(OnShakeEvent);
}
private void OnDisable()
{
RadialBlurShakeEvent.Unregister(OnShakeEvent);
StopAll();
}
private void Update()
{
if (!_resolved || _activeShakes.Count == 0) return;
float additiveDelta = 0f;
float absoluteTarget = 0f;
bool hasAbsolute = false;
Vector2 latestCenter = new Vector2(_initialCenterX, _initialCenterY);
bool hasCenter = false;
for (int i = _activeShakes.Count - 1; i >= 0; i--)
{
RadialBlurShakeInstance shake = _activeShakes[i];
shake.Tick();
float normalizedTime = shake.timer / shake.duration;
if (shake.intensityCurve.relativeToInitial)
{
// 相对模式:累加曲线值
additiveDelta += shake.intensityCurve.Evaluate(normalizedTime);
}
else
{
// 绝对模式:使用曲线值作为目标值
absoluteTarget = shake.intensityCurve.Evaluate(normalizedTime);
hasAbsolute = true;
}
if (shake.modifyCenter)
{
latestCenter = shake.center;
hasCenter = true;
}
if (shake.IsFinished)
{
_activeShakes.RemoveAt(i);
}
}
float finalRadius = hasAbsolute ? absoluteTarget : _initialBlurRadius + additiveDelta;
_component.blurRadius.value = finalRadius;
if (hasCenter)
{
_component.radialCenterX.value = latestCenter.x;
_component.radialCenterY.value = latestCenter.y;
}
if (_activeShakes.Count == 0)
{
Restore();
}
}
private void OnShakeEvent( FeedbackContext feedbackContext, FloatCurveChannel intensityCurve,
bool modifyCenter, Vector2 center, bool stop)
{
if (stop) { StopAll(); return; }
if (!_resolved) _resolved = TryResolve();
if (!_resolved) return;
var instance = new RadialBlurShakeInstance(feedbackContext, intensityCurve, modifyCenter, center);
_activeShakes.Add(instance);
}
private bool TryResolve()
{
if (_component != null) return true;
if (PostProcessingManager.Instance == null) return false;
if (!PostProcessingManager.Instance.GetVolumeComponent(out _component)) return false;
_initialBlurRadius = _component.blurRadius.value;
_initialCenterX = _component.radialCenterX.value;
_initialCenterY = _component.radialCenterY.value;
return true;
}
private void Restore()
{
if (!_resolved) return;
_component.blurRadius.value = _initialBlurRadius;
_component.radialCenterX.value = _initialCenterX;
_component.radialCenterY.value = _initialCenterY;
}
private void StopAll()
{
_activeShakes.Clear();
Restore();
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 569f4a4691c95ba448cf7309993ca9a9

View File

@@ -0,0 +1,190 @@
using System.Collections.Generic;
using SLSUtilities.Feedback;
using SLSUtilities.Rendering.PostProcessing;
using UnityEngine;
namespace Cielonos.MainGame.Effects.Feedback
{
/// <summary>
/// 黑白闪震动事件。
/// </summary>
public struct StrobeFlashShakeEvent
{
private static event ShakeDelegate OnEvent;
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
private static void RuntimeInitialization() { OnEvent = null; }
public delegate void ShakeDelegate(
FeedbackContext feedbackContext,
float duration,
bool modifyExtra,
FloatCurveChannel frequencyCurve,
ColorCurveChannel colorHigh,
ColorCurveChannel colorLow,
bool stop
);
public static void Register(ShakeDelegate callback) { OnEvent += callback; }
public static void Unregister(ShakeDelegate callback) { OnEvent -= callback; }
public static void Trigger(
FeedbackContext feedbackContext,
float duration,
bool modifyExtra = false,
FloatCurveChannel frequencyCurve = default,
ColorCurveChannel colorHigh = default,
ColorCurveChannel colorLow = default,
bool stop = false)
{
OnEvent?.Invoke(feedbackContext, duration, modifyExtra, frequencyCurve, colorHigh, colorLow, stop);
}
}
/// <summary>
/// 黑白闪震动实例。
/// </summary>
public class StrobeFlashShakeInstance : ShakeInstanceBase
{
public readonly bool modifyExtra;
public readonly FloatCurveChannel frequencyCurve;
public readonly ColorCurveChannel colorHigh;
public readonly ColorCurveChannel colorLow;
public StrobeFlashShakeInstance(
FeedbackContext feedbackContext,
bool modifyExtra,
FloatCurveChannel frequencyCurve,
ColorCurveChannel colorHigh,
ColorCurveChannel colorLow)
: base(feedbackContext.timeSettings, feedbackContext.player.TimeProvider, feedbackContext.duration)
{
this.modifyExtra = modifyExtra;
this.frequencyCurve = frequencyCurve;
this.colorHigh = colorHigh;
this.colorLow = colorLow;
}
}
/// <summary>
/// StrobeFlash 的震动聚合器。
/// </summary>
[AddComponentMenu("SLS Utilities/Feedback Shakers/Strobe Flash Shaker")]
public class StrobeFlashShaker : MonoBehaviour
{
private StrobeFlash _component;
private float _initialFrequency;
private Color _initialColorHigh;
private Color _initialColorLow;
private bool _resolved;
private readonly List<StrobeFlashShakeInstance> _activeShakes = new List<StrobeFlashShakeInstance>();
private void Awake()
{
_resolved = TryResolve();
}
private void OnEnable()
{
StrobeFlashShakeEvent.Register(OnShakeEvent);
}
private void OnDisable()
{
StrobeFlashShakeEvent.Unregister(OnShakeEvent);
StopAll();
}
private void Update()
{
if (!_resolved || _activeShakes.Count == 0) return;
float latestFrequency = _initialFrequency;
Color latestColorHigh = _initialColorHigh;
Color latestColorLow = _initialColorLow;
bool hasExtra = false;
for (int i = _activeShakes.Count - 1; i >= 0; i--)
{
StrobeFlashShakeInstance shake = _activeShakes[i];
shake.timer += shake.timeProvider.GetDeltaTime(shake.timeSettings);
float normalizedTime = shake.timer / shake.duration;
if (shake.modifyExtra && !shake.IsFinished)
{
latestFrequency = shake.frequencyCurve.Evaluate(normalizedTime);
latestColorHigh = shake.colorHigh.Evaluate(normalizedTime);
latestColorLow = shake.colorLow.Evaluate(normalizedTime);
hasExtra = true;
}
if (shake.IsFinished)
{
_activeShakes.RemoveAt(i);
}
}
_component.enableEffect.value = true;
_component.autoFlash.value = true;
if (hasExtra)
{
_component.frequency.value = latestFrequency;
_component.colorHigh.value = latestColorHigh;
_component.colorLow.value = latestColorLow;
}
if (_activeShakes.Count == 0)
{
Restore();
}
}
private void OnShakeEvent(
FeedbackContext feedbackContext,
float duration,
bool modifyExtra,
FloatCurveChannel frequencyCurve,
ColorCurveChannel colorHigh,
ColorCurveChannel colorLow,
bool stop)
{
if (stop) { StopAll(); return; }
if (!_resolved) _resolved = TryResolve();
if (!_resolved) return;
var instance = new StrobeFlashShakeInstance(
feedbackContext, modifyExtra, frequencyCurve, colorHigh, colorLow
);
_activeShakes.Add(instance);
}
private bool TryResolve()
{
if (_component != null) return true;
if (PostProcessingManager.Instance == null) return false;
if (!PostProcessingManager.Instance.GetVolumeComponent(out _component)) return false;
_initialFrequency = _component.frequency.value;
_initialColorHigh = _component.colorHigh.value;
_initialColorLow = _component.colorLow.value;
return true;
}
private void Restore()
{
if (!_resolved) return;
_component.frequency.value = _initialFrequency;
_component.colorHigh.value = _initialColorHigh;
_component.colorLow.value = _initialColorLow;
}
private void StopAll()
{
_activeShakes.Clear();
Restore();
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 588e6dd88aea55748adfb8b9aa48a518

View File

@@ -0,0 +1,252 @@
using System;
using System.Collections.Generic;
using Cielonos.MainGame;
using UnityEngine;
namespace Cielonos.MainGame.Effects.Feedback
{
/// <summary>
/// 时间缩放通道数据,用于事件传输。
/// </summary>
[Serializable]
public struct TimeScaleChannelData
{
public bool active;
public TimeScaleMode mode;
public float fixedValue;
public AnimationCurve curve;
public float remapZero;
public float remapOne;
/// <summary>
/// 根据归一化进度计算当前通道的时间缩放值。
/// </summary>
public float Evaluate(float normalizedTime)
{
if (!active) return 1f;
if (mode == TimeScaleMode.Fixed)
{
return fixedValue;
}
float curveValue = curve != null ? curve.Evaluate(normalizedTime) : 0f;
return Mathf.LerpUnclamped(remapZero, remapOne, curveValue);
}
}
/// <summary>
/// 时间缩放震动事件。
/// </summary>
public struct TimeScaleShakeEvent
{
private static event ShakeDelegate OnEvent;
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
private static void RuntimeInitialization() { OnEvent = null; }
public delegate void ShakeDelegate(
float duration,
TimeScaleChannelData global,
TimeScaleChannelData player,
TimeScaleChannelData enemy,
TimeScaleChannelData allied,
TimeScaleChannelData nonPlayer,
bool stop
);
/// <summary>
/// 注册震动监听。
/// </summary>
public static void Register(ShakeDelegate callback) { OnEvent += callback; }
/// <summary>
/// 取消震动监听。
/// </summary>
public static void Unregister(ShakeDelegate callback) { OnEvent -= callback; }
/// <summary>
/// 触发时间缩放震动事件。
/// </summary>
public static void Trigger(
float duration,
TimeScaleChannelData global = default,
TimeScaleChannelData player = default,
TimeScaleChannelData enemy = default,
TimeScaleChannelData allied = default,
TimeScaleChannelData nonPlayer = default,
bool stop = false)
{
OnEvent?.Invoke(duration, global, player, enemy, allied, nonPlayer, stop);
}
}
/// <summary>
/// 时间缩放震动实例。
/// </summary>
public class TimeScaleShakeInstance
{
public readonly float Duration;
public readonly TimeScaleChannelData Global;
public readonly TimeScaleChannelData Player;
public readonly TimeScaleChannelData Enemy;
public readonly TimeScaleChannelData Allied;
public readonly TimeScaleChannelData NonPlayer;
public float Timer;
public TimeScaleShakeInstance(
float duration,
TimeScaleChannelData global,
TimeScaleChannelData player,
TimeScaleChannelData enemy,
TimeScaleChannelData allied,
TimeScaleChannelData nonPlayer)
{
Duration = duration;
Global = global;
Player = player;
Enemy = enemy;
Allied = allied;
NonPlayer = nonPlayer;
Timer = 0f;
}
public bool IsFinished => Timer >= Duration;
}
/// <summary>
/// TimeManager 的时间缩放震动聚合器。
/// 管理多个并发时间缩放实例。
/// 当有活跃实例时,各通道取"最后激活"实例的值last wins
/// 全部结束后恢复初始值。
/// </summary>
[AddComponentMenu("SLS Utilities/Feedback Shakers/Time Scale Shaker")]
public class TimeScaleShaker : MonoBehaviour
{
private float _initGlobal;
private float _initPlayer;
private float _initEnemy;
private float _initAllied;
private float _initNonPlayer;
private bool _resolved;
private readonly List<TimeScaleShakeInstance> _activeShakes =
new List<TimeScaleShakeInstance>();
private void Awake()
{
_resolved = TryResolve();
}
private void OnEnable()
{
TimeScaleShakeEvent.Register(OnShakeEvent);
}
private void OnDisable()
{
TimeScaleShakeEvent.Unregister(OnShakeEvent);
StopAll();
}
private void Update()
{
if (!_resolved || _activeShakes.Count == 0) return;
if (TimeManager.Instance == null) return;
float dt = Time.deltaTime;
// 各通道取最后激活实例的值
float globalVal = _initGlobal;
float playerVal = _initPlayer;
float enemyVal = _initEnemy;
float alliedVal = _initAllied;
float nonPlayerVal = _initNonPlayer;
bool hasGlobal = false, hasPlayer = false, hasEnemy = false;
bool hasAllied = false, hasNonPlayer = false;
for (int i = _activeShakes.Count - 1; i >= 0; i--)
{
TimeScaleShakeInstance shake = _activeShakes[i];
shake.Timer += dt;
float t = Mathf.Clamp01(shake.Timer / shake.Duration);
if (shake.Global.active) { globalVal = shake.Global.Evaluate(t); hasGlobal = true; }
if (shake.Player.active) { playerVal = shake.Player.Evaluate(t); hasPlayer = true; }
if (shake.Enemy.active) { enemyVal = shake.Enemy.Evaluate(t); hasEnemy = true; }
if (shake.Allied.active) { alliedVal = shake.Allied.Evaluate(t); hasAllied = true; }
if (shake.NonPlayer.active) { nonPlayerVal = shake.NonPlayer.Evaluate(t); hasNonPlayer = true; }
if (shake.IsFinished)
{
_activeShakes.RemoveAt(i);
}
}
if (hasGlobal) TimeManager.Instance.globalTimeScale.Value = globalVal;
if (hasPlayer) TimeManager.Instance.playerTimeScale.Value = playerVal;
if (hasEnemy) TimeManager.Instance.enemyTimeScale.Value = enemyVal;
if (hasAllied) TimeManager.Instance.alliedMinionTimeScale.Value = alliedVal;
if (hasNonPlayer) TimeManager.Instance.nonPlayerTimeScale.Value = nonPlayerVal;
if (_activeShakes.Count == 0)
{
Restore();
}
}
private void OnShakeEvent(
float duration,
TimeScaleChannelData global,
TimeScaleChannelData player,
TimeScaleChannelData enemy,
TimeScaleChannelData allied,
TimeScaleChannelData nonPlayer,
bool stop)
{
if (stop)
{
StopAll();
return;
}
if (!_resolved) _resolved = TryResolve();
if (!_resolved) return;
_activeShakes.Add(new TimeScaleShakeInstance(
duration, global, player, enemy, allied, nonPlayer
));
}
private bool TryResolve()
{
if (TimeManager.Instance == null) return false;
_initGlobal = TimeManager.Instance.globalTimeScale.Value;
_initPlayer = TimeManager.Instance.playerTimeScale.Value;
_initEnemy = TimeManager.Instance.enemyTimeScale.Value;
_initAllied = TimeManager.Instance.alliedMinionTimeScale.Value;
_initNonPlayer = TimeManager.Instance.nonPlayerTimeScale.Value;
return true;
}
private void Restore()
{
if (TimeManager.Instance == null) return;
TimeManager.Instance.globalTimeScale.Value = _initGlobal;
TimeManager.Instance.playerTimeScale.Value = _initPlayer;
TimeManager.Instance.enemyTimeScale.Value = _initEnemy;
TimeManager.Instance.alliedMinionTimeScale.Value = _initAllied;
TimeManager.Instance.nonPlayerTimeScale.Value = _initNonPlayer;
}
private void StopAll()
{
_activeShakes.Clear();
Restore();
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 33bd71b84e3b907468514ad946229fbc

View File

@@ -0,0 +1,269 @@
using System.Collections.Generic;
using SLSUtilities.Feedback;
using SLSUtilities.Rendering.PostProcessing;
using UnityEngine;
namespace Cielonos.MainGame.Effects.Feedback
{
/// <summary>
/// 暗角震动事件。
/// </summary>
public struct VignetteShakeEvent
{
private static event ShakeDelegate OnEvent;
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
private static void RuntimeInitialization() { OnEvent = null; }
public delegate void ShakeDelegate(
FeedbackContext feedbackContext,
FloatCurveChannel intensityCurve,
bool modifyCenter,
Vector2 center,
bool modifyColors,
ColorCurveChannel colorOuter,
ColorCurveChannel colorInner,
bool modifyShape,
FloatCurveChannel smoothnessCurve,
FloatCurveChannel roundnessCurve,
bool stop
);
public static void Register(ShakeDelegate callback) { OnEvent += callback; }
public static void Unregister(ShakeDelegate callback) { OnEvent -= callback; }
public static void Trigger(
FeedbackContext feedbackContext,
FloatCurveChannel intensityCurve,
bool modifyCenter = false,
Vector2 center = default,
bool modifyColors = false,
ColorCurveChannel colorOuter = default,
ColorCurveChannel colorInner = default,
bool modifyShape = false,
FloatCurveChannel smoothnessCurve = default,
FloatCurveChannel roundnessCurve = default,
bool stop = false)
{
OnEvent?.Invoke(feedbackContext, intensityCurve, modifyCenter, center,
modifyColors, colorOuter, colorInner, modifyShape,
smoothnessCurve, roundnessCurve, stop);
}
}
/// <summary>
/// 暗角震动实例。
/// </summary>
public class VignetteShakeInstance : ShakeInstanceBase
{
public readonly FloatCurveChannel intensityCurve;
public readonly bool modifyCenter;
public readonly Vector2 center;
public readonly bool modifyColors;
public readonly ColorCurveChannel colorOuter;
public readonly ColorCurveChannel colorInner;
public readonly bool modifyShape;
public readonly FloatCurveChannel smoothnessCurve;
public readonly FloatCurveChannel roundnessCurve;
public VignetteShakeInstance(
FeedbackContext feedbackContext,
FloatCurveChannel intensityCurve,
bool modifyCenter,
Vector2 center,
bool modifyColors,
ColorCurveChannel colorOuter,
ColorCurveChannel colorInner,
bool modifyShape,
FloatCurveChannel smoothnessCurve,
FloatCurveChannel roundnessCurve)
: base(feedbackContext.timeSettings, feedbackContext.player.TimeProvider, feedbackContext.duration)
{
this.intensityCurve = intensityCurve;
this.modifyCenter = modifyCenter;
this.center = center;
this.modifyColors = modifyColors;
this.colorOuter = colorOuter;
this.colorInner = colorInner;
this.modifyShape = modifyShape;
this.smoothnessCurve = smoothnessCurve;
this.roundnessCurve = roundnessCurve;
}
}
/// <summary>
/// AdvancedVignette 的震动聚合器。
/// </summary>
[AddComponentMenu("SLS Utilities/Feedback Shakers/Vignette Shaker")]
public class VignetteShaker : MonoBehaviour
{
private AdvancedVignette _component;
private float _initialIntensity;
private Vector2 _initialCenter;
private Color _initialColorOuter;
private Color _initialColorInner;
private float _initialSmoothness;
private float _initialRoundness;
private bool _resolved;
private readonly List<VignetteShakeInstance> _activeShakes = new List<VignetteShakeInstance>();
private void Awake()
{
_resolved = TryResolve();
}
private void OnEnable()
{
VignetteShakeEvent.Register(OnShakeEvent);
}
private void OnDisable()
{
VignetteShakeEvent.Unregister(OnShakeEvent);
StopAll();
}
private void Update()
{
if (!_resolved || _activeShakes.Count == 0) return;
float additiveIntensity = 0f;
float absoluteIntensity = 0f;
bool hasAbsolute = false;
Vector2 latestCenter = _initialCenter;
Color latestColorOuter = _initialColorOuter;
Color latestColorInner = _initialColorInner;
float latestSmoothness = _initialSmoothness;
float latestRoundness = _initialRoundness;
bool hasCenter = false;
bool hasColors = false;
bool hasShape = false;
for (int i = _activeShakes.Count - 1; i >= 0; i--)
{
VignetteShakeInstance shake = _activeShakes[i];
shake.timer += shake.timeProvider.GetDeltaTime(shake.timeSettings);
float normalizedTime = shake.timer / shake.duration;
if (shake.intensityCurve.active)
{
float curveValue = shake.intensityCurve.Evaluate(normalizedTime);
if (shake.intensityCurve.relativeToInitial)
{
additiveIntensity += curveValue;
}
else
{
absoluteIntensity = curveValue;
hasAbsolute = true;
}
}
if (shake.modifyCenter)
{
latestCenter = shake.center;
hasCenter = true;
}
if (shake.modifyColors)
{
latestColorOuter = shake.colorOuter.Evaluate(normalizedTime);
latestColorInner = shake.colorInner.Evaluate(normalizedTime);
hasColors = true;
}
if (shake.modifyShape)
{
latestSmoothness = shake.smoothnessCurve.Evaluate(normalizedTime);
latestRoundness = shake.roundnessCurve.Evaluate(normalizedTime);
hasShape = true;
}
if (shake.IsFinished)
{
_activeShakes.RemoveAt(i);
}
}
float finalIntensity = hasAbsolute ? absoluteIntensity : _initialIntensity + additiveIntensity;
_component.intensity.value = finalIntensity;
if (hasCenter) _component.center.value = latestCenter;
if (hasColors)
{
_component.colorOuter.value = latestColorOuter;
_component.colorInner.value = latestColorInner;
}
if (hasShape)
{
_component.smoothness.value = latestSmoothness;
_component.roundness.value = latestRoundness;
}
if (_activeShakes.Count == 0)
{
Restore();
}
}
private void OnShakeEvent(
FeedbackContext feedbackContext,
FloatCurveChannel intensityCurve,
bool modifyCenter,
Vector2 center,
bool modifyColors,
ColorCurveChannel colorOuter,
ColorCurveChannel colorInner,
bool modifyShape,
FloatCurveChannel smoothnessCurve,
FloatCurveChannel roundnessCurve,
bool stop)
{
if (stop) { StopAll(); return; }
if (!_resolved) _resolved = TryResolve();
if (!_resolved) return;
var instance = new VignetteShakeInstance(
feedbackContext, intensityCurve, modifyCenter, center,
modifyColors, colorOuter, colorInner, modifyShape,
smoothnessCurve, roundnessCurve
);
_activeShakes.Add(instance);
}
private bool TryResolve()
{
if (_component != null) return true;
if (PostProcessingManager.Instance == null) return false;
if (!PostProcessingManager.Instance.GetVolumeComponent(out _component)) return false;
_initialIntensity = _component.intensity.value;
_initialCenter = _component.center.value;
_initialColorOuter = _component.colorOuter.value;
_initialColorInner = _component.colorInner.value;
_initialSmoothness = _component.smoothness.value;
_initialRoundness = _component.roundness.value;
return true;
}
private void Restore()
{
if (!_resolved) return;
_component.intensity.value = _initialIntensity;
_component.center.value = _initialCenter;
_component.colorOuter.value = _initialColorOuter;
_component.colorInner.value = _initialColorInner;
_component.smoothness.value = _initialSmoothness;
_component.roundness.value = _initialRoundness;
}
private void StopAll()
{
_activeShakes.Clear();
Restore();
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 129b8b0330a4e5741a1f3121f9d01d22