using System.Collections.Generic; using Game; using UnityEngine; namespace Game { public class CastShadowPoolItem : ObjectPoolItemBase { public GameObject GameObject; public float LifeTime; public float LifeTimeMax; public Material Material; protected override void OnCreate() { base.OnCreate(); LifeTime = LifeTimeMax; GameObject.SetActive(true); } protected override void OnDestroy() { base.OnDestroy(); GameObject.SetActive(false); } } public class CastShadowPoolManager : ObjectPoolBase { private const string CastShadowPath = "Effect/CastShadow/"; private readonly Dictionary _castShadowMap = new Dictionary { [ECastShadowType.Common] = "CastShadowCommon", [ECastShadowType.PlayerFlash] = "CastShadowPlayerFlash", [ECastShadowType.Monster] = "CastShadowMonster", [ECastShadowType.DeadBody] = "CastShadowDeadBody" }; private readonly HashSet _castShadowPoolSet = new HashSet(); private static readonly int Alpha = Shader.PropertyToID("_Alpha"); public override void Update() { var dt = Time.deltaTime * 1000; foreach (var poolName in _castShadowPoolSet) foreach (var objectPoolItemBase in EnSureGetPool(poolName)) { var item = (CastShadowPoolItem)objectPoolItemBase; if (item.IsAlive) { item.LifeTime -= dt; if (item.LifeTime <= 0) { item.Destroy(); } else { var value = item.LifeTime / item.LifeTimeMax; item.Material.SetFloat(Alpha, value); } } } } public override void OnDestroy() { } public void DestroyCastShadowAll() { foreach (var poolName in _castShadowPoolSet) foreach (var objectPoolItemBase in EnSureGetPool(poolName)) { var item = (CastShadowPoolItem)objectPoolItemBase; if (item.IsAlive) item.Destroy(); } } public void CreateCastShadow(Sprite sprite, Vector3 pos, Vector3 scale, float lifeTime = 500, ECastShadowType castShadowType = ECastShadowType.Common) { if (!_castShadowMap.ContainsKey(castShadowType)) Util.Print("残影类型不存在:", castShadowType); var castShadowId = _castShadowMap[castShadowType]; var poolName = $"CastShadow_{castShadowId}"; _castShadowPoolSet.Add(poolName); var effectNew = Create(poolName, item => { var newGo = CreateCastShadowGo(castShadowId); var newRenderer = newGo.GetComponent(); item.GameObject = newGo; item.Material = newRenderer.material; item.GameObject.transform.parent = Root.transform; }); var go = effectNew.GameObject; var renderer = go.GetComponent(); effectNew.LifeTimeMax = lifeTime; effectNew.LifeTime = lifeTime; renderer.sprite = sprite; effectNew.GameObject.transform.position = new Vector3(pos.x, pos.y, pos.z + 0.1f); effectNew.GameObject.transform.localScale = scale; } private GameObject CreateCastShadowGo(string castShadowId) { var path = $"{CastShadowPath}{castShadowId}"; return PrefabManager.Instance.CreateGo(path); } } } namespace Game { public abstract partial class Util { public static void CastShadow(Sprite sprite, Vector3 pos, Vector3 scale, float lifeTime, ECastShadowType castShadowType) { CastShadowPoolManager.Instance.CreateCastShadow(sprite, pos, scale, lifeTime, castShadowType); } public static void DestroyCastShadowAll() { CastShadowPoolManager.Instance.DestroyCastShadowAll(); } } } public partial class GameEntity { public void CastShadow(float lifeTime = 150, ECastShadowType castShadowType = ECastShadowType.Common) { Util.CastShadow(view.SpriteRenderer.sprite, view.PositionView, view.TransformViewMain.localScale, lifeTime, castShadowType); } }