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; [Tooltip("初始 alpha")] public float initialAlpha = 0f; private List cachedMaterials = new List(); private int fadeAlphaPropertyID; private void Awake() { fadeAlphaPropertyID = Shader.PropertyToID(fadeAlphaPropertyName); CacheMaterials(); ApplyFadeAlpha(initialAlpha); } private void Start() { if (autoPlay) { Play(); } } private void Update() { if (isPlaying) { currentTime += Time.deltaTime; float normalizedTime = Mathf.Clamp01(currentTime / duration); float fadeValue = fadeCurve.Evaluate(normalizedTime); ApplyFadeAlpha(fadeValue); if (currentTime >= duration) { if (loop) { currentTime = 0f; } else { isPlaying = false; currentTime = duration; } } } } private void CacheMaterials() { cachedMaterials.Clear(); SkinnedMeshRenderer[] skinnedRenderers = GetComponentsInChildren(true); foreach (SkinnedMeshRenderer renderer in skinnedRenderers) { if (renderer != null && renderer.sharedMaterials != null) { foreach (Material mat in renderer.sharedMaterials) { if (mat != null && mat.HasProperty(fadeAlphaPropertyID)) { cachedMaterials.Add(mat); } } } } MeshRenderer[] meshRenderers = GetComponentsInChildren(true); foreach (MeshRenderer renderer in meshRenderers) { if (renderer != null && renderer.sharedMaterials != null) { foreach (Material mat in renderer.sharedMaterials) { if (mat != null && mat.HasProperty(fadeAlphaPropertyID)) { cachedMaterials.Add(mat); } } } } Debug.Log($"[FadeAlphaController] Cached {cachedMaterials.Count} materials with {fadeAlphaPropertyName} property"); } private void ApplyFadeAlpha(float alpha) { foreach (Material mat in cachedMaterials) { if (mat != null) { mat.SetFloat(fadeAlphaPropertyID, alpha); } } } 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(); } 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() { cachedMaterials.Clear(); } }