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