Files
2026-02-21 16:45:37 +08:00

124 lines
2.1 KiB
C#

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<ShaderProperty> 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<Renderer>();
}
}
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<Renderer>();
}
}
}