/* http://www.cgsoso.com/forum-211-1.html CG搜搜 Unity3d 每日Unity3d插件免费更新 更有VIP资源! CGSOSO 主打游戏开发,影视设计等CG资源素材。 插件如若商用,请务必官网购买! daily assets update for try. U should buy the asset from home store if u use it in your project! */ using System; using UnityEngine; using UnityEngine.Sprites; using UnityEngine.UI; namespace MS { [ExecuteInEditMode] [RequireComponent(typeof(CanvasRenderer))] [RequireComponent(typeof(ParticleSystem))] public class UIParticleSystem : MaskableGraphic { public Texture particleTexture; public Sprite particleSprite; private Transform _transform; private ParticleSystem _particleSystem; private ParticleSystem.Particle[] _particles; private UIVertex[] _quad = new UIVertex[4]; private Vector4 _uv = Vector4.zero; private ParticleSystem.TextureSheetAnimationModule _textureSheetAnimation; private int _textureSheetAnimationFrames; private Vector2 _textureSheedAnimationFrameSize; public override Texture mainTexture { get { if ((bool)particleTexture) { return particleTexture; } if ((bool)particleSprite) { return particleSprite.texture; } return null; } } protected bool Initialize() { if (_transform == null) { _transform = base.transform; } if (_particleSystem == null) { _particleSystem = GetComponent(); if (_particleSystem == null) { return false; } ParticleSystemRenderer particleSystemRenderer = _particleSystem.GetComponent(); if (particleSystemRenderer == null) { particleSystemRenderer = _particleSystem.gameObject.AddComponent(); } Material sharedMaterial = particleSystemRenderer.sharedMaterial; if ((bool)sharedMaterial && sharedMaterial.HasProperty("_MainTex")) { particleTexture = sharedMaterial.mainTexture; } Material material = new Material(Shader.Find("Legacy Shaders/Particles/Alpha Blended")); if (Application.isPlaying) { particleSystemRenderer.material = material; } _particleSystem.scalingMode = ParticleSystemScalingMode.Hierarchy; _particles = null; } if (_particles == null) { _particles = new ParticleSystem.Particle[_particleSystem.maxParticles]; } if ((bool)particleTexture) { _uv = new Vector4(0f, 0f, 1f, 1f); } else if ((bool)particleSprite) { _uv = DataUtility.GetOuterUV(particleSprite); } _textureSheetAnimation = _particleSystem.textureSheetAnimation; _textureSheetAnimationFrames = 0; _textureSheedAnimationFrameSize = Vector2.zero; if (_textureSheetAnimation.enabled) { _textureSheetAnimationFrames = _textureSheetAnimation.numTilesX * _textureSheetAnimation.numTilesY; _textureSheedAnimationFrameSize = new Vector2(1f / (float)_textureSheetAnimation.numTilesX, 1f / (float)_textureSheetAnimation.numTilesY); } return true; } protected override void Awake() { base.Awake(); if (!Initialize()) { base.enabled = false; } } protected override void OnPopulateMesh(VertexHelper vh) { vh.Clear(); if (!base.gameObject.activeInHierarchy) { return; } int particles = _particleSystem.GetParticles(_particles); for (int i = 0; i < particles; i++) { ParticleSystem.Particle particle = _particles[i]; Vector2 a = (_particleSystem.simulationSpace != 0) ? _transform.InverseTransformPoint(particle.position) : particle.position; float num = (0f - particle.rotation) * ((float)Math.PI / 180f); float f = num + (float)Math.PI / 2f; Color32 currentColor = particle.GetCurrentColor(_particleSystem); float num2 = particle.GetCurrentSize(_particleSystem) * 0.5f; if (_particleSystem.scalingMode == ParticleSystemScalingMode.Shape) { a /= base.canvas.scaleFactor; } Vector4 uv = _uv; if (_textureSheetAnimation.enabled) { float num3 = 1f - particle.remainingLifetime / particle.startLifetime; num3 = Mathf.Repeat(num3 * (float)_textureSheetAnimation.cycleCount, 1f); int num4 = 0; switch (_textureSheetAnimation.animation) { case ParticleSystemAnimationType.WholeSheet: num4 = Mathf.FloorToInt(num3 * (float)_textureSheetAnimationFrames); break; case ParticleSystemAnimationType.SingleRow: { num4 = Mathf.FloorToInt(num3 * (float)_textureSheetAnimation.numTilesX); int rowIndex = _textureSheetAnimation.rowIndex; num4 += rowIndex * _textureSheetAnimation.numTilesX; break; } } num4 %= _textureSheetAnimationFrames; uv.x = (float)(num4 % _textureSheetAnimation.numTilesX) * _textureSheedAnimationFrameSize.x; uv.y = (float)Mathf.FloorToInt(num4 / _textureSheetAnimation.numTilesX) * _textureSheedAnimationFrameSize.y; uv.z = uv.x + _textureSheedAnimationFrameSize.x; uv.w = uv.y + _textureSheedAnimationFrameSize.y; } _quad[0] = UIVertex.simpleVert; _quad[0].color = currentColor; _quad[0].uv0 = new Vector2(uv.x, uv.y); _quad[1] = UIVertex.simpleVert; _quad[1].color = currentColor; _quad[1].uv0 = new Vector2(uv.x, uv.w); _quad[2] = UIVertex.simpleVert; _quad[2].color = currentColor; _quad[2].uv0 = new Vector2(uv.z, uv.w); _quad[3] = UIVertex.simpleVert; _quad[3].color = currentColor; _quad[3].uv0 = new Vector2(uv.z, uv.y); if (num == 0f) { Vector2 vector = new Vector2(a.x - num2, a.y - num2); Vector2 vector2 = new Vector2(a.x + num2, a.y + num2); _quad[0].position = new Vector2(vector.x, vector.y); _quad[1].position = new Vector2(vector.x, vector2.y); _quad[2].position = new Vector2(vector2.x, vector2.y); _quad[3].position = new Vector2(vector2.x, vector.y); } else { Vector2 b = new Vector2(Mathf.Cos(num), Mathf.Sin(num)) * num2; Vector2 b2 = new Vector2(Mathf.Cos(f), Mathf.Sin(f)) * num2; _quad[0].position = a - b - b2; _quad[1].position = a - b + b2; _quad[2].position = a + b + b2; _quad[3].position = a + b - b2; } vh.AddUIVertexQuad(_quad); } } private void Update() { if (Application.isPlaying) { _particleSystem.Simulate(Time.unscaledDeltaTime, withChildren: false, restart: false); SetAllDirty(); } } } }