using Entitas; using UnityEngine; using Game; using Vector3 = UnityEngine.Vector3; // view 需要在update后 渲染前处理的 public class ViewLateSystem : IExecuteSystem, IInitializeSystem { private IGroup _entities; private static readonly int Flash = Shader.PropertyToID("_Flash"); private static readonly int Color = Shader.PropertyToID("_Color"); private static readonly int UV = Shader.PropertyToID("_UV"); private static readonly int Direction = Shader.PropertyToID("_Direction"); private static readonly int Intensity = Shader.PropertyToID("_Intensity"); public void Initialize() { _entities = Util.GetGroup(GameMatcher.View); } public void Execute() { foreach (var entity in _entities) { UpdateUV(entity); //更新uv坐标 if (Util.IsPause(entity)) { continue; } UpdateFlash(entity); //更新闪白 UpdateScale(entity); //更新缩放 } } private static void UpdateUV(GameEntity entity) { var view = entity.view; if (view.SpriteRenderer == null) { return; } if (view.SpriteRenderer.sprite == null) { return; } var (xMin, yMin, xMax, yMax) = (1f, 1f, 0f, 0f); foreach (var uv in view.SpriteRenderer.sprite.uv) { xMin = Mathf.Min(xMin, uv.x); yMin = Mathf.Min(yMin, uv.y); xMax = Mathf.Max(xMax, uv.x); yMax = Mathf.Max(yMax, uv.y); } var (widthHalf, heightHalf) = ((xMax - xMin) / 2, (yMax - yMin) / 2); var (centerX, centerY) = (xMin + widthHalf, yMin + heightHalf); var param = new Vector4(centerX, centerY, widthHalf, heightHalf); view.Material.SetVector(UV, param); } private static void UpdateFlash(GameEntity entity) { var view = entity.view; if (view.FlashTimeLeft == 0) { return; } view.FlashTimeLeft -= Time.deltaTime; if (view.FlashTimeLeft < 0) { view.FlashTimeLeft = 0; view.FlashColor = UnityEngine.Color.white; } var flashRate = view.FlashTimeLeft / GameConst.FlashTerm; view.Material.SetFloat(Flash, flashRate); view.Material.SetColor(Color, view.FlashColor); } private static void UpdateScale(GameEntity entity) { var view = entity.view; if (view.ScaleTimeLeft == 0) { return; } view.ScaleTimeLeft -= Time.deltaTime; if (view.ScaleTimeLeft < 0) { view.ScaleTimeLeft = 0; view.ScaleDir = Vector3.zero; } var scaleRate = view.ScaleTimeLeft / GameConst.ScaleTerm; view.Material.SetVector(Direction, view.ScaleDir); view.Material.SetFloat(Intensity, scaleRate * view.ScaleRate); } }