Files
Cielonos/Assets/Scripts/MainGame/Characters/Base/Subcontrollers/Render/MeshEffectUnit.cs
SoulliesOfficial f26f9fd374 爆更
2026-03-20 12:07:44 -04:00

151 lines
4.8 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using DG.Tweening;
using Lean.Pool;
using UnityEngine;
namespace Cielonos.MainGame.Characters
{
public partial class MeshEffectUnit
{
public bool isEnabling;
private RenderSubcontrollerBase renderSc;
private string name;
private bool hasMaterialEffect;
private bool hasParticleEffect;
private Sequence materialEffectOnTween;
private Sequence materialEffectOffTween;
private List<MeshEffect> particleEffects;
public MeshEffectUnit(RenderSubcontrollerBase renderSc, string name, bool hasMaterialEffect = true, bool hasParticleEffect = true)
{
this.renderSc = renderSc;
this.isEnabling = false;
this.name = name;
this.hasMaterialEffect = hasMaterialEffect;
this.hasParticleEffect = hasParticleEffect;
}
public void EffectOn(float endValue = 1f, float duration = 0.25f, Func<Material, float, Tweener> tweenBuilder = null)
{
if(isEnabling) return;
isEnabling = true;
renderSc.activeEffectCount.Value++;
if (hasMaterialEffect)
{
materialEffectOffTween?.Kill(true);
materialEffectOnTween?.Kill(true);
materialEffectOnTween = DOTween.Sequence();
materialEffectOnTween.OnPlay(() =>
{
if (hasParticleEffect)
{
GenerateParticleEffects();
}
});
foreach (Material mat in renderSc.effectRenderMaterials[name])
{
Tweener matTween = tweenBuilder == null
? mat.DOFloat(endValue, "_AlphaScale", duration).From(0.0f).SetEase(Ease.OutQuad)
: tweenBuilder(mat, duration);
materialEffectOnTween.Join(matTween);
}
materialEffectOnTween.Play();
}
else
{
GenerateParticleEffects();
}
}
public void EffectOff(float duration = 0.25f, Func<Material, float, Tweener> tweenBuilder = null)
{
if(!isEnabling) return;
isEnabling = false;
if (hasMaterialEffect)
{
materialEffectOnTween?.Kill(true);
materialEffectOffTween?.Kill(true);
materialEffectOffTween = DOTween.Sequence();
foreach (Material mat in renderSc.effectRenderMaterials[name])
{
Tweener matTween = tweenBuilder == null
? mat.DOFloat(0.0f, "_AlphaScale", duration).SetEase(Ease.OutQuad)
: tweenBuilder(mat, duration);
materialEffectOffTween.Join(matTween);
}
materialEffectOffTween.OnStart(() =>
{
if (hasParticleEffect)
{
StopParticleEffects();
}
});
materialEffectOffTween.OnComplete(() =>
{
renderSc.activeEffectCount.Value--;
if (hasParticleEffect)
{
DespawnParticleEffects();
}
});
materialEffectOffTween.Play();
}
else
{
StopParticleEffects();
renderSc.owner.selfTimeSm.AddGlobalTimer(duration, ()=>
{
DespawnParticleEffects();
renderSc.activeEffectCount.Value--;
});
}
}
}
public partial class MeshEffectUnit
{
private void GenerateParticleEffects()
{
particleEffects = new List<MeshEffect>();
GameObject prefab = MainGameManager.BaseCollection.meshEffectCollection[name].gameObject;
foreach (MeshEffectRendererInfo part in renderSc.meshEffectRenderers)
{
MeshEffect meshEffect = LeanPool.Spawn(prefab, renderSc.transform).GetComponent<MeshEffect>();
particleEffects.Add(meshEffect);
meshEffect.AttachTo(part);
}
}
private void StopParticleEffects()
{
foreach (var meshEffect in particleEffects)
{
meshEffect.StopAllParticles();
}
}
private void DespawnParticleEffects()
{
foreach (var meshEffect in particleEffects)
{
LeanPool.Despawn(meshEffect.gameObject);
}
particleEffects.Clear();
}
}
}