c1_unity/Assets/Scripts/Component/Effects/ParticleUVAnimation.cs
2023-04-03 11:04:31 +08:00

124 lines
3.1 KiB
C#

using System;
using System.Collections.Generic;
using UnityEngine;
[ExecuteInEditMode]
public class ParticleUVAnimation : MonoBehaviour
{
public ParticleSystem particle;
private ParticleSystemRenderer particleRender;
private MaterialPropertyBlock materialProperty;
private Action animFunc;
[Header("[textST.xy : tile, textST.zw : offset]")]
public Vector4 texST;
public bool running = false;
public float fps;
private float fpsStep;
private Func<float> calcuateTime;
private bool init = false;
private int frameCount;
private int frameIndex;
private int tilesX;
private float wStart;
void Init()
{
if (particle == null)
particle = GetComponent<ParticleSystem>();
particleRender = GetComponent<ParticleSystemRenderer>();
materialProperty = new MaterialPropertyBlock();
particleRender.GetPropertyBlock(materialProperty);
var sheetAnim = particle.textureSheetAnimation;
if (sheetAnim.animation == ParticleSystemAnimationType.SingleRow)
animFunc = SingleRowUpdate;
else
animFunc = WholeSheetUpdate;
switch (sheetAnim.timeMode)
{
case ParticleSystemAnimationTimeMode.FPS:
fps = sheetAnim.fps;
fpsStep = 1.0f / fps;
break;
case ParticleSystemAnimationTimeMode.Lifetime: //临时写一下
fps = sheetAnim.fps;
fpsStep = 1.0f / fps;
break;
case ParticleSystemAnimationTimeMode.Speed:
fps = sheetAnim.fps;
fpsStep = 1.0f / fps;
break;
}
frameCount = sheetAnim.numTilesX * sheetAnim.numTilesY;
frameIndex = 0;
tilesX = sheetAnim.numTilesX;
texST.x = 1.0f / sheetAnim.numTilesX;
texST.y = 1.0f / sheetAnim.numTilesY;
texST.z = 0;
texST.w = wStart = 1 - texST.y;
materialProperty.SetVector("_MainTex_ST", texST);
particleRender.SetPropertyBlock(materialProperty);
lastTime = 0f;
init = true;
}
public void Play()
{
running = true;
//lastTime = Time.time;
}
void Awake()
{
Init();
}
void Update()
{
if (!running)
return;
if (!init)
Init();
animFunc();
}
private void WholeSheetUpdate()
{
CalculateOffset();
materialProperty.SetVector("_MainTex_ST", texST);
particleRender.SetPropertyBlock(materialProperty);
}
float lastTime;
private void SingleRowUpdate()
{
//texST.z = CalculateXOffset(texST.z);
}
private void CalculateOffset()
{
if (Time.time > lastTime)
{
if (lastTime == 0)
lastTime = Time.time + fpsStep;
else
lastTime += fpsStep;
++frameIndex;
if (frameIndex >= frameCount)
frameIndex -= frameCount;
texST.z = (frameIndex % tilesX) * texST.x;
texST.w = wStart - (frameIndex / tilesX) * texST.y;
}
}
}