126 lines
3.5 KiB
C#
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();
|
|
}
|
|
}
|