using System; using System.Collections.Generic; using UnityEngine; using RuntimeData; using Animancer; using Logic; using NUnit.Framework; using TH1Resource; using TMPro; using TMPro.Examples; using Unity.IO.LowLevel.Unsafe; using Unity.VisualScripting; using Object = UnityEngine.Object; using PropertyAttribute = UnityEngine.PropertyAttribute; using Random = UnityEngine.Random; namespace TH1Renderer { public enum GridVFXType { Heal, Die, DieHint, CounterDieHint, Flag, Damage, Hurt, Treasure, Fog, Coin, Fire, ROYALFLAMES, TewiFrenchBuff, KaguyaFrenchBuff, CityConnect, RedMistCreate, }; public class GridVFXManager { public Dictionary GridVFXDict; public GridVFXManager(GameObject _effect) { GridVFXDict = new Dictionary(); if (!GridVFXRendererFactory.NewGridVFXDict(_effect, GridVFXDict)) Debug.LogError("Failed to create GridVFXDict"); } public bool SetStop(GridVFXType type) { if (!GridVFXDict.TryGetValue(type, out var renderer)) return false; renderer.SetStop(); return true; } public void Clear() { foreach (var obj in GridVFXDict) { obj.Value?.Clear(); } } public void Update() { foreach (var vfxPair in GridVFXDict) vfxPair.Value?.Update(); } public bool PlayVFX(GridVFXParams param,GridVFXPlayType playType) { if (!GridVFXDict.TryGetValue(param.Type, out var vfxRenderer)) return false; if (vfxRenderer == null) return false; if (playType is GridVFXPlayType.Play or GridVFXPlayType.PlayOnce) { vfxRenderer.UpdateSpecialParam(param); vfxRenderer.SetPlay(playType); } else vfxRenderer.SetStop(); return true; } } public static class GridVFXRendererFactory { public static GridVFXRenderer Create(GridVFXParams param) { return param.Type switch { GridVFXType.Flag => new FlagGridVFXRenderer(param), GridVFXType.Damage => new DamageGridVFXRenderer(param), GridVFXType.ROYALFLAMES => new ROYALFLAMESGridVFXRenderer(param), GridVFXType.Fog => new FogGridVFXRenderer(param), GridVFXType.TewiFrenchBuff => new TewiFrenchBuffGridVFXRenderer(param), GridVFXType.Coin => new CoinGridVFXRenderer(param), GridVFXType.KaguyaFrenchBuff => new KaguyaFrenchBuffGridVFXRenderer(param), GridVFXType.Treasure => new TreasureGridVFXRenderer(param), GridVFXType.Die => new DieGridVFXRenderer(param), GridVFXType.DieHint => new DieHintGridVFXRenderer(param), GridVFXType.Heal => new HealGridVFXRenderer(param), GridVFXType.Hurt => new HurtGridVFXRenderer(param), GridVFXType.CounterDieHint => new CounterDieHintGridVFXRenderer(param), GridVFXType.Fire => new FireGridVFXRenderer(param), GridVFXType.CityConnect => new CityConnectGridVFXRendererer(param), GridVFXType.RedMistCreate => new RedMistCreateVFXRenderer(param), _ => null }; } public static bool NewGridVFXDict(GameObject _effect,Dictionary dict) { if (_effect == null || dict == null) return false; //初始化VFXManagerDict TODO 全部通用 dict[GridVFXType.Flag] = Create(new GridVFXParams(GridVFXType.Flag,ResourceCache.Instance.AnimCache.GridVFXHeal,null,_effect.transform.Find("Flag")?.gameObject)); dict[GridVFXType.Damage] = Create(new GridVFXParams(GridVFXType.Damage,ResourceCache.Instance.AnimCache.GridVFXDamage,null,_effect.transform.Find("Damage")?.gameObject)); dict[GridVFXType.Fog] = Create(new GridVFXParams(GridVFXType.Fog,ResourceCache.Instance.AnimCache.GridVFXShowOut,null,_effect.transform.Find("Fog")?.gameObject)); dict[GridVFXType.Treasure] = Create(new GridVFXParams(GridVFXType.Treasure,ResourceCache.Instance.AnimCache.GridVFXTreasure,ResourceCache.Instance.SpriteCache.GridVFXTreasure,_effect.transform.Find("Treasure")?.gameObject)); dict[GridVFXType.Hurt] = Create(new GridVFXParams(GridVFXType.Hurt,ResourceCache.Instance.AnimCache.GridVFXHurt,null,_effect.transform.Find("Hurt")?.gameObject)); dict[GridVFXType.Heal] = Create(new GridVFXParams(GridVFXType.Heal,ResourceCache.Instance.AnimCache.GridVFXHeal,ResourceCache.Instance.SpriteCache.GridVFXHeal,_effect.transform.Find("CommonVFX")?.gameObject)); dict[GridVFXType.CityConnect] = Create(new GridVFXParams(GridVFXType.CityConnect,ResourceCache.Instance.AnimCache.GridVFXHeal,ResourceCache.Instance.SpriteCache.GridVFXConnect,_effect.transform.Find("CommonVFX")?.gameObject)); dict[GridVFXType.Fire] = Create(new GridVFXParams(GridVFXType.Fire,null,null,_effect.transform.Find("Fire")?.gameObject)); dict[GridVFXType.RedMistCreate] = Create(new GridVFXParams(GridVFXType.Treasure,ResourceCache.Instance.AnimCache.GridVFXTreasure,ResourceCache.Instance.SpriteCache.GridVFXRedMistCreate,_effect.transform.Find("Treasure")?.gameObject)); //Die相关 dict[GridVFXType.Die] = Create(new GridVFXParams(GridVFXType.Die,ResourceCache.Instance.AnimCache.GridVFXDie,ResourceCache.Instance.SpriteCache.GridVFXDie,_effect.transform.Find("Die")?.gameObject)); dict[GridVFXType.DieHint] = Create(new GridVFXParams(GridVFXType.DieHint,ResourceCache.Instance.AnimCache.GridVFXDieHint,ResourceCache.Instance.SpriteCache.GridVFXDie,_effect.transform.Find("Die")?.gameObject)); dict[GridVFXType.CounterDieHint] = Create(new GridVFXParams(GridVFXType.CounterDieHint,ResourceCache.Instance.AnimCache.GridVFXDieHint,ResourceCache.Instance.SpriteCache.GridVFXCounterDie,_effect.transform.Find("Die")?.gameObject)); //初始化Skill特效 dict[GridVFXType.ROYALFLAMES] = Create(new GridVFXParams(GridVFXType.ROYALFLAMES,ResourceCache.Instance.AnimCache.GridVFXShowUp,ResourceCache.Instance.SpriteCache.GridVFXROYALFLAMES,_effect.transform.Find("Skill")?.gameObject)); dict[GridVFXType.TewiFrenchBuff] = Create(new GridVFXParams(GridVFXType.TewiFrenchBuff,ResourceCache.Instance.AnimCache.GridVFXShowUp,ResourceCache.Instance.SpriteCache.GridVFXTEWI,_effect.transform.Find("Skill")?.gameObject)); dict[GridVFXType.Coin] = Create(new GridVFXParams(GridVFXType.TewiFrenchBuff,ResourceCache.Instance.AnimCache.GridVFXShowUp,ResourceCache.Instance.SpriteCache.GridVFXCoin,_effect.transform.Find("Skill")?.gameObject)); dict[GridVFXType.KaguyaFrenchBuff] = Create(new GridVFXParams(GridVFXType.KaguyaFrenchBuff,ResourceCache.Instance.AnimCache.GridVFXShowUp,ResourceCache.Instance.SpriteCache.GridVFXKAGUYA,_effect.transform.Find("Skill")?.gameObject)); return true; } } public enum GridVFXPlayType {Play,Stop,PlayOnce} public class GridVFXParams { // 通用 public GridVFXType Type; public GameObject VFXObject; public AnimationClip VFXAnim; public Sprite Sprite; // 特殊子类用 public uint CivId; public int Damage; //从gridData持有的GridVFXRenderMark结构,转化为GridVFXRenderer所需要的param结构 public GridVFXParams(GridVFXType type) { Type = type; } public GridVFXParams(GridVFXType type, int dmg) { if (type is GridVFXType.Damage) { Type = type; Damage = dmg; } else Debug.LogError("Wrong GridVFX Type"); } public GridVFXParams(GridVFXType gridVFXType, AnimationClip vfxAnim, Sprite sprite, GameObject vfxObject,GridVFXPlayType playType = GridVFXPlayType.PlayOnce) { Type = gridVFXType; VFXObject = vfxObject; Sprite = sprite; VFXAnim = vfxAnim; Damage = 0; CivId = 0; } } public abstract class GridVFXRenderer { public GridVFXType Type; public AnimationClip VFXAnim; public Sprite Sprite; public GameObject VFXObject; protected SpriteRenderer _renderer; protected Transform _transfrom; public bool IsPlaying; public GridVFXRenderer(GridVFXParams param) { Type = param.Type; VFXAnim = param.VFXAnim; Sprite = param.Sprite; VFXObject = param.VFXObject; IsPlaying = false; _renderer = VFXObject.GetComponent(); _transfrom = VFXObject.GetComponent(); } public virtual void SetPlay(GridVFXPlayType playType = GridVFXPlayType.PlayOnce) { if (IsPlaying) return; if (VFXObject == null) return; if (Sprite != null) _renderer.sprite = Sprite; Play(playType); } public virtual void Play(GridVFXPlayType playType = GridVFXPlayType.PlayOnce) { VFXObject.SetActive(true); IsPlaying = true; var animancer = VFXObject.GetComponent(); if (VFXAnim != null) { animancer.Play(VFXAnim); if(playType is GridVFXPlayType.PlayOnce) Timer.Instance.TimerRegister(VFXObject, () => { VFXObject.SetActive(false); IsPlaying = false; }, VFXAnim.length,"GridVFXRenderer_" + Type); } } public virtual void Clear() { IsPlaying = false; } public virtual void SetStop() { if (IsPlaying) Stop(); } public virtual void Stop() { IsPlaying = false; VFXObject.SetActive(false); } public virtual void Update() { } public virtual void UpdateSpecialParam(GridVFXParams param){} public virtual void SetIntParam(int param) { } }; public class FlagGridVFXRenderer : GridVFXRenderer { public uint CivId; public FlagGridVFXRenderer(GridVFXParams param):base(param) { CivId = param.CivId; } public override void SetPlay(GridVFXPlayType playType = GridVFXPlayType.PlayOnce) { if (IsPlaying) return; if (VFXObject == null) return; if (Table.Instance.PlayerDataAssets.GetPlayerInfoByCivId(CivId, CivId, out var playerInfo)) { Sprite = playerInfo.FlagIcon; VFXObject.transform.Find("FlagBG2").GetComponent().color = playerInfo.Color; } var t = VFXObject.transform.Find("FlagIcon").transform; if (t == null) return; t.GetComponent().sprite = Sprite; Play(playType); } public override void UpdateSpecialParam(GridVFXParams param) { CivId = param.CivId; } } public class DamageGridVFXRenderer : GridVFXRenderer { public int Damage; public DamageGridVFXRenderer(GridVFXParams param):base(param) { Damage = param.Damage; } public override void SetPlay(GridVFXPlayType playType = GridVFXPlayType.PlayOnce) { if (IsPlaying) return; if (VFXObject == null) return; var t = VFXObject.GetComponent(); if (t == null) return; t.text = Damage.ToString(); Play(playType); } public override void UpdateSpecialParam(GridVFXParams param) { Damage = param.Damage; } public override void SetIntParam(int param) { Damage = param; } } public class ROYALFLAMESGridVFXRenderer : GridVFXRenderer { public int Damage; public ROYALFLAMESGridVFXRenderer(GridVFXParams param):base(param) { } public override void SetPlay(GridVFXPlayType playType = GridVFXPlayType.PlayOnce) { if (IsPlaying) return; if (VFXObject == null) return; _renderer.sprite = Sprite; _renderer.color = Color.yellow; _transfrom.localScale = new Vector2(2f, 2f); Play(playType); } } public class FogGridVFXRenderer : GridVFXRenderer { public FogGridVFXRenderer(GridVFXParams param):base(param) { } } public class TewiFrenchBuffGridVFXRenderer : GridVFXRenderer { public TewiFrenchBuffGridVFXRenderer(GridVFXParams param):base(param) { } public override void SetPlay(GridVFXPlayType playType = GridVFXPlayType.PlayOnce) { if (IsPlaying) return; if (VFXObject == null) return; _renderer.sprite = Sprite; _renderer.color = Color.white; _transfrom.localScale = new Vector2(0.5f, 0.5f); Play(playType); } } public class CoinGridVFXRenderer : GridVFXRenderer { public CoinGridVFXRenderer(GridVFXParams param):base(param) { } public override void SetPlay(GridVFXPlayType playType = GridVFXPlayType.PlayOnce) { if (IsPlaying) return; if (VFXObject == null) return; _renderer.sprite = Sprite; _renderer.color = Color.white; _transfrom.localScale = new Vector2(1f, 1f); Play(playType); } } public class KaguyaFrenchBuffGridVFXRenderer : GridVFXRenderer { public KaguyaFrenchBuffGridVFXRenderer(GridVFXParams param):base(param) { } public override void SetPlay(GridVFXPlayType playType = GridVFXPlayType.PlayOnce) { if (IsPlaying) return; if (VFXObject == null) return; _renderer.sprite = Sprite; _renderer.color = Color.white; _transfrom.localScale = new Vector2(1.5f, 1.5f); Play(playType); } } public class TreasureGridVFXRenderer : GridVFXRenderer { public TreasureGridVFXRenderer(GridVFXParams param):base(param) { } } public class DieGridVFXRenderer : GridVFXRenderer { public DieGridVFXRenderer(GridVFXParams param):base(param) { } } public class DieHintGridVFXRenderer : GridVFXRenderer { public DieHintGridVFXRenderer(GridVFXParams param):base(param) { } } public class HurtGridVFXRenderer : GridVFXRenderer { public HurtGridVFXRenderer(GridVFXParams param):base(param) { } } public class HealGridVFXRenderer : GridVFXRenderer { public HealGridVFXRenderer(GridVFXParams param):base(param) { } } public class CounterDieHintGridVFXRenderer : GridVFXRenderer { public CounterDieHintGridVFXRenderer(GridVFXParams param):base(param) { } } public class FireGridVFXRenderer : GridVFXRenderer { public FireGridVFXRenderer(GridVFXParams param):base(param) { } public override void Play(GridVFXPlayType playType = GridVFXPlayType.PlayOnce) { IsPlaying = true; VFXObject.SetActive(true); } } public class CityConnectGridVFXRendererer : GridVFXRenderer { public CityConnectGridVFXRendererer(GridVFXParams param):base(param) { } } public class RedMistCreateVFXRenderer : GridVFXRenderer { public RedMistCreateVFXRenderer(GridVFXParams param):base(param) { } } }