NLDClient-yudde/ProjectNLD/Assets/Code/Scripts/GameWrapper/FadeAlphaController.cs

185 lines
4.4 KiB
C#

using UnityEngine;
using System.Collections.Generic;
public class FadeAlphaController : MonoBehaviour
{
[Header("Fade Settings")]
[Tooltip("Animation curve to control fade alpha over time (0-1)")]
public AnimationCurve fadeCurve = AnimationCurve.Linear(0f, 1f, 1f, 0f);
[Tooltip("Duration of the fade animation in seconds")]
[Range(0.1f, 10f)]
public float duration = 1f;
[Tooltip("Auto play on start")]
public bool autoPlay = false;
[Tooltip("Loop the animation")]
public bool loop = false;
[Header("Material Settings")]
[Tooltip("Shader property name for fade alpha")]
public string fadeAlphaPropertyName = "_fadeAlpha";
[Header("Runtime Info")]
[SerializeField]
[Tooltip("Current time in the animation")]
private float currentTime = 0f;
[SerializeField]
[Tooltip("Is the animation currently playing")]
private bool isPlaying = false;
private List<Renderer> cachedRenderers = new List<Renderer>();
private Dictionary<Renderer, MaterialPropertyBlock> propertyBlocks = new Dictionary<Renderer, MaterialPropertyBlock>();
private int fadeAlphaPropertyID;
private void Awake()
{
fadeAlphaPropertyID = Shader.PropertyToID(fadeAlphaPropertyName);
CacheMaterials();
}
private void Start()
{
if (autoPlay)
{
Play();
}
}
private void Update()
{
if (!isPlaying)
return;
currentTime += Time.deltaTime;
float normalizedTime = Mathf.Clamp01(currentTime / duration);
ApplyFadeAlpha(fadeCurve.Evaluate(normalizedTime));
if (currentTime >= duration)
{
currentTime = 0f;
isPlaying = loop;
}
}
private void CacheMaterials()
{
cachedRenderers.Clear();
propertyBlocks.Clear();
Renderer[] allRenderers = GetComponentsInChildren<Renderer>(true);
foreach (Renderer renderer in allRenderers)
{
if (renderer != null && HasFadeAlphaProperty(renderer))
{
cachedRenderers.Add(renderer);
MaterialPropertyBlock mpb = new MaterialPropertyBlock();
renderer.GetPropertyBlock(mpb);
propertyBlocks[renderer] = mpb;
}
}
Debug.Log($"[FadeAlphaController] Cached {cachedRenderers.Count} renderers with {fadeAlphaPropertyName} property");
}
private bool HasFadeAlphaProperty(Renderer renderer)
{
if (renderer.sharedMaterials == null)
return false;
foreach (Material mat in renderer.sharedMaterials)
{
if (mat != null && mat.HasProperty(fadeAlphaPropertyID))
{
return true;
}
}
return false;
}
public void ApplyFadeAlpha(float alpha)
{
foreach (Renderer renderer in cachedRenderers)
{
if (renderer != null && propertyBlocks.TryGetValue(renderer, out MaterialPropertyBlock mpb))
{
mpb.SetFloat(fadeAlphaPropertyID, alpha);
renderer.SetPropertyBlock(mpb);
}
}
}
public void Toggle()
{
if (isPlaying)
Stop();
else
Play();
}
public void Play()
{
currentTime = 0f;
ApplyFadeAlpha(fadeCurve.Evaluate(currentTime));
isPlaying = true;
}
public void Pause()
{
isPlaying = false;
}
public void Resume()
{
isPlaying = true;
}
public void Stop()
{
isPlaying = false;
currentTime = 0f;
ApplyFadeAlpha(fadeCurve.Evaluate(0f));
}
public void SetFadeAlpha(float alpha)
{
ApplyFadeAlpha(Mathf.Clamp01(alpha));
}
public void RefreshMaterials()
{
CacheMaterials();
if (isPlaying)
{
float normalizedTime = Mathf.Clamp01(currentTime / duration);
ApplyFadeAlpha(fadeCurve.Evaluate(normalizedTime));
}
}
public float GetCurrentFadeAlpha()
{
float normalizedTime = Mathf.Clamp01(currentTime / duration);
return fadeCurve.Evaluate(normalizedTime);
}
private void OnValidate()
{
if (duration <= 0f)
{
duration = 0.1f;
}
}
private void OnDestroy()
{
cachedRenderers.Clear();
propertyBlocks.Clear();
}
}