Files
bansonic_beta_main/Assets/scripts/rendering/GlobalAfterimageRuntimeController.cs

126 lines
3.5 KiB
C#

using UnityEngine;
public class GlobalAfterimageRuntimeController : MonoBehaviour
{
public static GlobalAfterimageRuntimeController Instance { get; private set; }
[Header("Runtime Afterimage Defaults")]
public float defaultStartOpacity = 0.5f;
public float defaultFadeDuration = 0.22f;
public float defaultEndScale = 1.12f;
public bool useUnscaledTime = true;
public bool triggerOnEnable = false;
private static float sRuntimeOpacity;
private static float sRuntimeScale = 1f;
private static bool sCaptureRequested;
private float activeStartOpacity;
private float activeFadeDuration;
private float activeEndScale = 1f;
private float activeElapsed;
private bool activeAfterimage;
public static float RuntimeOpacity => sRuntimeOpacity;
public static float RuntimeScale => sRuntimeScale;
public static bool HasActiveAfterimage => sRuntimeOpacity > 0.0001f;
private void Awake()
{
if (Instance == null)
{
Instance = this;
return;
}
if (Instance != this)
Destroy(gameObject);
}
private void OnEnable()
{
if (triggerOnEnable)
TriggerAfterimage();
}
private void Update()
{
float delta = useUnscaledTime ? Time.unscaledDeltaTime : Time.deltaTime;
UpdateAfterimage(delta);
}
public void TriggerAfterimage()
{
TriggerAfterimage(defaultStartOpacity, defaultFadeDuration, defaultEndScale);
}
public void TriggerAfterimage(float startOpacity, float fadeDuration, float endScale)
{
activeStartOpacity = Mathf.Clamp01(startOpacity);
activeFadeDuration = Mathf.Max(0.0001f, fadeDuration);
activeEndScale = Mathf.Max(1f, endScale);
activeElapsed = 0f;
activeAfterimage = activeStartOpacity > 0.0001f;
sRuntimeOpacity = activeStartOpacity;
sRuntimeScale = 1f;
sCaptureRequested = activeAfterimage;
}
private void UpdateAfterimage(float delta)
{
if (!activeAfterimage)
{
sRuntimeOpacity = 0f;
sRuntimeScale = 1f;
return;
}
activeElapsed += delta;
float normalized = Mathf.Clamp01(activeElapsed / activeFadeDuration);
sRuntimeOpacity = Mathf.Lerp(activeStartOpacity, 0f, normalized);
sRuntimeScale = Mathf.Lerp(1f, activeEndScale, normalized);
if (normalized < 1f)
return;
activeAfterimage = false;
sRuntimeOpacity = 0f;
sRuntimeScale = 1f;
}
public static bool ConsumeCaptureRequest()
{
bool requested = sCaptureRequested;
sCaptureRequested = false;
return requested;
}
public static GlobalAfterimageRuntimeController EnsureInstance()
{
if (Instance != null)
return Instance;
GlobalAfterimageRuntimeController existing = SceneObjectLookupCache.FindFirst<GlobalAfterimageRuntimeController>();
if (existing != null)
{
Instance = existing;
return existing;
}
GameObject runtimeObject = new GameObject("__global_afterimage_runtime");
Instance = runtimeObject.AddComponent<GlobalAfterimageRuntimeController>();
return Instance;
}
public static void Trigger(float startOpacity, float fadeDuration, float endScale)
{
EnsureInstance().TriggerAfterimage(startOpacity, fadeDuration, endScale);
}
public static void TriggerDefault()
{
EnsureInstance().TriggerAfterimage();
}
}