wip : critical path - flash hallu
This commit is contained in:
@@ -0,0 +1,121 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
|
||||
namespace Unheimlich.Features.Hallucination
|
||||
{
|
||||
/// <summary>
|
||||
/// Drives a persistent post-process weight targeting either a URP/HDRP <see cref="Volume"/>
|
||||
/// and/or a <see cref="Material"/> exposing a <c>_Weight</c> property, based on an
|
||||
/// internal sanity value [0, 1].
|
||||
/// Wire the Wrapper methods to any UnityEvent with no arguments.
|
||||
/// </summary>
|
||||
public class HallucinationPostProcess : MonoBehaviour
|
||||
{
|
||||
[Header("Targets")]
|
||||
[Tooltip("URP/HDRP Volume driven by the sanity weight.")]
|
||||
[SerializeField] private Volume _volume;
|
||||
[Tooltip("Optional material exposing a _Weight property.")]
|
||||
[SerializeField] private Material _shaderMaterial;
|
||||
|
||||
[Header("Sanity")]
|
||||
[SerializeField, Range(0f, 1f)] private float _initialSanity = 0f;
|
||||
[Tooltip("Sanity lost per second after each tween completes. 0 = no decay.")]
|
||||
[SerializeField, Min(0f)] private float _autoDecayRate = 0f;
|
||||
|
||||
[Header("Wrappers")]
|
||||
[Tooltip("Amount added when calling AddSanityWrapper().")]
|
||||
[SerializeField, Range(0f, 1f)] private float _wrapperAddAmount = 0.2f;
|
||||
[Tooltip("Amount removed when calling RemoveSanityWrapper().")]
|
||||
[SerializeField, Range(0f, 1f)] private float _wrapperRemoveAmount = 0.2f;
|
||||
[Tooltip("Transition duration used by all wrappers (seconds).")]
|
||||
[SerializeField, Min(0f)] private float _wrapperDuration = 1f;
|
||||
|
||||
// ─── State ─────────────────────────────────────────────────────────────
|
||||
|
||||
private float _sanity;
|
||||
private int _tweenId = -1;
|
||||
private bool _decaying = false;
|
||||
|
||||
// ─── Lifecycle ─────────────────────────────────────────────────────────
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
_sanity = Mathf.Clamp01(_initialSanity);
|
||||
Apply(_sanity);
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (!_decaying || _autoDecayRate <= 0f || _sanity <= 0f) return;
|
||||
|
||||
_sanity = Mathf.Max(0f, _sanity - _autoDecayRate * Time.deltaTime);
|
||||
Apply(_sanity);
|
||||
|
||||
if (_sanity <= 0f) _decaying = false;
|
||||
}
|
||||
|
||||
// ─── Wrappers ──────────────────────────────────────────────────────────
|
||||
|
||||
/// <summary>Adds <see cref="_wrapperAddAmount"/> sanity over <see cref="_wrapperDuration"/> seconds.
|
||||
/// Auto-decay starts when the tween completes, if <see cref="_autoDecayRate"/> is greater than 0.</summary>
|
||||
public void AddSanityWrapper() => TweenSanity(_sanity + _wrapperAddAmount, _wrapperDuration);
|
||||
|
||||
/// <summary>Removes <see cref="_wrapperRemoveAmount"/> sanity over <see cref="_wrapperDuration"/> seconds.</summary>
|
||||
public void RemoveSanityWrapper() => TweenSanity(_sanity - _wrapperRemoveAmount, _wrapperDuration);
|
||||
|
||||
/// <summary>Snaps sanity to 0 instantly and stops decay.</summary>
|
||||
public void ResetSanityWrapper()
|
||||
{
|
||||
CancelCurrent();
|
||||
_decaying = false;
|
||||
_sanity = 0f;
|
||||
Apply(0f);
|
||||
}
|
||||
|
||||
// ─── Private ───────────────────────────────────────────────────────────
|
||||
|
||||
private void TweenSanity(float target, float duration)
|
||||
{
|
||||
target = Mathf.Clamp01(target);
|
||||
_decaying = false;
|
||||
|
||||
if (duration <= 0f)
|
||||
{
|
||||
CancelCurrent();
|
||||
_sanity = target;
|
||||
Apply(target);
|
||||
if (_autoDecayRate > 0f) _decaying = true;
|
||||
return;
|
||||
}
|
||||
|
||||
CancelCurrent();
|
||||
|
||||
float from = _sanity;
|
||||
_tweenId = LeanTween.value(gameObject, from, target, duration)
|
||||
.setEase(LeanTweenType.easeInOutQuad)
|
||||
.setOnUpdate((float w) =>
|
||||
{
|
||||
_sanity = w;
|
||||
Apply(w);
|
||||
})
|
||||
.setOnComplete(() =>
|
||||
{
|
||||
// Start decay only after the tween has fully completed.
|
||||
if (_autoDecayRate > 0f) _decaying = true;
|
||||
}).id;
|
||||
}
|
||||
|
||||
private void Apply(float weight)
|
||||
{
|
||||
if (_volume != null) _volume.weight = weight;
|
||||
if (_shaderMaterial != null) _shaderMaterial.SetFloat("_Weight", weight);
|
||||
}
|
||||
|
||||
private void CancelCurrent()
|
||||
{
|
||||
if (_tweenId == -1) return;
|
||||
LeanTween.cancel(_tweenId);
|
||||
_tweenId = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user