using System; using System.Collections; using System.Collections.Generic; using UnityEngine; namespace BitStrap { public class TweenShader : MonoBehaviour { [Serializable] public class ShaderProperty { public enum Type { Color = 0, Float = 1 } public string name; public Color from = Color.white; public Color to = Color.white; public Type type = Type.Float; private int? id; public int Id { get { if (!id.HasValue) { id = Shader.PropertyToID(name); } return id.Value; } } public void Evaluate(MaterialPropertyBlock block, float t) { if (type == Type.Color) { block.SetColor(Id, Color.Lerp(from, to, t)); } else if (type == Type.Float) { block.SetFloat(Id, Mathf.Lerp(from.a, to.a, t)); } } } public AnimationCurve curve = AnimationCurve.Linear(0f, 0f, 1f, 1f); public float duration = 1f; public List shaderProperties; public Renderer targetRenderer; private MaterialPropertyBlock propertyBlock; public void Clear() { propertyBlock.Clear(); targetRenderer.SetPropertyBlock(propertyBlock); } public void Evaluate(float t) { propertyBlock.Clear(); t = curve.Evaluate(t); foreach (ShaderProperty shaderProperty in shaderProperties) { shaderProperty.Evaluate(propertyBlock, t); } targetRenderer.SetPropertyBlock(propertyBlock); } public void PlayBackward() { Stop(); StartCoroutine(PlayAsync(1f, 0f)); } public void PlayForward() { Stop(); StartCoroutine(PlayAsync(0f, 1f)); } public void Stop() { StopAllCoroutines(); } private void Awake() { propertyBlock = new MaterialPropertyBlock(); if (targetRenderer == null) { targetRenderer = GetComponent(); } } private IEnumerator PlayAsync(float from, float to) { for (float time = 0f; time < duration; time += Time.deltaTime) { float t = Mathf.Lerp(from, to, Mathf.InverseLerp(0f, duration, time)); Evaluate(t); yield return null; } Evaluate(to); } private void Reset() { targetRenderer = GetComponent(); } } }