| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524 | 
							- #if UNITY_2019_3_11 || UNITY_2019_3_12 || UNITY_2019_3_13 || UNITY_2019_3_14 || UNITY_2019_3_15 || UNITY_2019_4_OR_NEWER
 
- #define SERIALIZE_FIELD_MASKABLE
 
- #endif
 
- using System.Collections;
 
- using System.Collections.Generic;
 
- using System.Runtime.CompilerServices;
 
- using Coffee.UIParticleExtensions;
 
- using UnityEngine;
 
- using UnityEngine.Rendering;
 
- using UnityEngine.Serialization;
 
- using UnityEngine.UI;
 
- [assembly: InternalsVisibleTo("Fort23.Editor")]
 
- namespace Coffee.UIExtensions
 
- {
 
-     /// <summary>
 
-     /// Render maskable and sortable particle effect ,without Camera, RenderTexture or Canvas.
 
-     /// </summary>
 
-     [ExecuteInEditMode]
 
-     [RequireComponent(typeof(RectTransform))]
 
-     [RequireComponent(typeof(CanvasRenderer))]
 
-     public class UIParticle : MaskableGraphic
 
- #if UNITY_EDITOR
 
-         , ISerializationCallbackReceiver
 
- #endif
 
-     {
 
-         [HideInInspector] [SerializeField] internal bool m_IsTrail = false;
 
-         [Tooltip("Ignore canvas scaler")] [SerializeField] [FormerlySerializedAs("m_IgnoreParent")]
 
-         bool m_IgnoreCanvasScaler = true;
 
-         [Tooltip("Particle effect scale")] [SerializeField]
 
-         float m_Scale = 100;
 
-         [Tooltip("Particle effect scale")] [SerializeField]
 
-         private Vector3 m_Scale3D;
 
-         [Tooltip("Animatable material properties. If you want to change the material properties of the ParticleSystem in Animation, enable it.")] [SerializeField]
 
-         internal AnimatableProperty[] m_AnimatableProperties = new AnimatableProperty[0];
 
-         [Tooltip("Particles")] [SerializeField]
 
-         private List<ParticleSystem> m_Particles = new List<ParticleSystem>();
 
-         [Tooltip("Shrink rendering by material on refresh.\nNOTE: Performance will be improved, but in some cases the rendering is not correct.")] [SerializeField]
 
-         bool m_ShrinkByMaterial = false;
 
- #if !SERIALIZE_FIELD_MASKABLE
 
-         [SerializeField] private bool m_Maskable = true;
 
- #endif
 
-         private bool _shouldBeRemoved;
 
-         private DrivenRectTransformTracker _tracker;
 
-         private Mesh _bakedMesh;
 
-         private readonly List<Material> _modifiedMaterials = new List<Material>();
 
-         private readonly List<Material> _maskMaterials = new List<Material>();
 
-         private readonly List<bool> _activeMeshIndices = new List<bool>();
 
-         private Vector3 _cachedPosition;
 
-         private static readonly List<Material> s_TempMaterials = new List<Material>(2);
 
-         private static MaterialPropertyBlock s_Mpb;
 
-         private static readonly List<Material> s_PrevMaskMaterials = new List<Material>();
 
-         private static readonly List<Material> s_PrevModifiedMaterials = new List<Material>();
 
-         private static readonly List<Component> s_Components = new List<Component>();
 
-         private static readonly List<ParticleSystem> s_ParticleSystems = new List<ParticleSystem>();
 
-         /// <summary>
 
-         /// Should this graphic be considered a target for raycasting?
 
-         /// </summary>
 
-         public override bool raycastTarget
 
-         {
 
-             get { return false; }
 
-             set { }
 
-         }
 
-         public bool ignoreCanvasScaler
 
-         {
 
-             get { return m_IgnoreCanvasScaler; }
 
-             set
 
-             {
 
-                 // if (m_IgnoreCanvasScaler == value) return;
 
-                 m_IgnoreCanvasScaler = value;
 
-                 _tracker.Clear();
 
-                 if (isActiveAndEnabled && m_IgnoreCanvasScaler)
 
-                     _tracker.Add(this, rectTransform, DrivenTransformProperties.Scale);
 
-             }
 
-         }
 
-         public bool shrinkByMaterial
 
-         {
 
-             get { return m_ShrinkByMaterial; }
 
-             set
 
-             {
 
-                 if (m_ShrinkByMaterial == value) return;
 
-                 m_ShrinkByMaterial = value;
 
-                 RefreshParticles();
 
-             }
 
-         }
 
-         /// <summary>
 
-         /// Particle effect scale.
 
-         /// </summary>
 
-         public float scale
 
-         {
 
-             get { return m_Scale3D.x; }
 
-             set
 
-             {
 
-                 m_Scale = Mathf.Max(0.001f, value);
 
-                 m_Scale3D = new Vector3(m_Scale, m_Scale, m_Scale);
 
-             }
 
-         }
 
-         /// <summary>
 
-         /// Particle effect scale.
 
-         /// </summary>
 
-         public Vector3 scale3D
 
-         {
 
-             get { return m_Scale3D; }
 
-             set
 
-             {
 
-                 if (m_Scale3D == value) return;
 
-                 m_Scale3D.x = Mathf.Max(0.001f, value.x);
 
-                 m_Scale3D.y = Mathf.Max(0.001f, value.y);
 
-                 m_Scale3D.z = Mathf.Max(0.001f, value.z);
 
-             }
 
-         }
 
-         internal Mesh bakedMesh
 
-         {
 
-             get { return _bakedMesh; }
 
-         }
 
-         public List<ParticleSystem> particles
 
-         {
 
-             get { return m_Particles; }
 
-         }
 
-         public IEnumerable<Material> materials
 
-         {
 
-             get { return _modifiedMaterials; }
 
-         }
 
-         public override Material materialForRendering
 
-         {
 
-             get { return canvasRenderer.GetMaterial(0); }
 
-         }
 
-         public List<bool> activeMeshIndices
 
-         {
 
-             get { return _activeMeshIndices; }
 
-             set
 
-             {
 
-                 if (_activeMeshIndices.SequenceEqualFast(value)) return;
 
-                 _activeMeshIndices.Clear();
 
-                 _activeMeshIndices.AddRange(value);
 
-                 UpdateMaterial();
 
-             }
 
-         }
 
-         internal Vector3 cachedPosition
 
-         {
 
-             get { return _cachedPosition; }
 
-             set { _cachedPosition = value; }
 
-         }
 
-         public void Play()
 
-         {
 
-             particles.Exec(p => p.Play());
 
-         }
 
-         public void Pause()
 
-         {
 
-             particles.Exec(p => p.Pause());
 
-         }
 
-         public void Stop()
 
-         {
 
-             particles.Exec(p => p.Stop());
 
-         }
 
-         public void Clear()
 
-         {
 
-             particles.Exec(p => p.Clear());
 
-         }
 
-         public void SetParticleSystemInstance(GameObject instance)
 
-         {
 
-             SetParticleSystemInstance(instance, true);
 
-         }
 
-         public void SetParticleSystemInstance(GameObject instance, bool destroyOldParticles)
 
-         {
 
-             if (!instance) return;
 
-             foreach (Transform child in transform)
 
-             {
 
-                 var go = child.gameObject;
 
-                 go.SetActive(false);
 
-                 if (!destroyOldParticles) continue;
 
- #if UNITY_EDITOR
 
-                 if (!Application.isPlaying)
 
-                     DestroyImmediate(go);
 
-                 else
 
- #endif
 
-                     Destroy(go);
 
-             }
 
-             var tr = instance.transform;
 
-             tr.SetParent(transform, false);
 
-             tr.localPosition = Vector3.zero;
 
-             RefreshParticles(instance);
 
-         }
 
-         public void SetParticleSystemPrefab(GameObject prefab)
 
-         {
 
-             if (!prefab) return;
 
-             SetParticleSystemInstance(Instantiate(prefab.gameObject), true);
 
-         }
 
-         public void RefreshParticles()
 
-         {
 
-             RefreshParticles(gameObject);
 
-         }
 
-         public void RefreshParticles(GameObject root)
 
-         {
 
-             if (!root) return;
 
-             root.GetComponentsInChildren(particles);
 
-             particles.RemoveAll(x => x.GetComponentInParent<UIParticle>() != this);
 
-             foreach (var ps in particles)
 
-             {
 
-                 var tsa = ps.textureSheetAnimation;
 
-                 if (tsa.mode == ParticleSystemAnimationMode.Sprites && tsa.uvChannelMask == (UVChannelFlags) 0)
 
-                     tsa.uvChannelMask = UVChannelFlags.UV0;
 
-             }
 
-             particles.Exec(p => p.GetComponent<ParticleSystemRenderer>().enabled = !enabled);
 
-             particles.SortForRendering(transform, m_ShrinkByMaterial);
 
-             SetMaterialDirty();
 
-         }
 
-         protected override void UpdateMaterial()
 
-         {
 
-             // Clear mask materials.
 
-             s_PrevMaskMaterials.AddRange(_maskMaterials);
 
-             _maskMaterials.Clear();
 
-             // Clear modified materials.
 
-             s_PrevModifiedMaterials.AddRange(_modifiedMaterials);
 
-             _modifiedMaterials.Clear();
 
-             // Recalculate stencil value.
 
-             if (m_ShouldRecalculateStencil)
 
-             {
 
-                 var rootCanvas = MaskUtilities.FindRootSortOverrideCanvas(transform);
 
-                 m_StencilValue = maskable ? MaskUtilities.GetStencilDepth(transform, rootCanvas) : 0;
 
-                 m_ShouldRecalculateStencil = false;
 
-             }
 
-             // No mesh to render.
 
-             var count = activeMeshIndices.CountFast();
 
-             if (count == 0 || !isActiveAndEnabled || particles.Count == 0)
 
-             {
 
-                 canvasRenderer.Clear();
 
-                 ClearPreviousMaterials();
 
-                 return;
 
-             }
 
-             //
 
-             GetComponents(typeof(IMaterialModifier), s_Components);
 
-             var materialCount = Mathf.Min(16, count);
 
-             canvasRenderer.materialCount = materialCount;
 
-             var j = 0;
 
-             for (var i = 0; i < particles.Count; i++)
 
-             {
 
-                 if (materialCount <= j) break;
 
-                 var ps = particles[i];
 
-                 if (!ps) continue;
 
-                 var r = ps.GetComponent<ParticleSystemRenderer>();
 
-                 r.GetSharedMaterials(s_TempMaterials);
 
-                 // Main
 
-                 var index = i * 2;
 
-                 if (activeMeshIndices.Count <= index) break;
 
-                 if (activeMeshIndices[index] && 0 < s_TempMaterials.Count)
 
-                 {
 
-                     var mat = GetModifiedMaterial(s_TempMaterials[0], ps.GetTextureForSprite());
 
-                     for (var k = 1; k < s_Components.Count; k++)
 
-                         mat = (s_Components[k] as IMaterialModifier).GetModifiedMaterial(mat);
 
-                     canvasRenderer.SetMaterial(mat, j);
 
-                     UpdateMaterialProperties(r, j);
 
-                     j++;
 
-                 }
 
-                 // Trails
 
-                 index++;
 
-                 if (activeMeshIndices.Count <= index || materialCount <= j) break;
 
-                 if (activeMeshIndices[index] && 1 < s_TempMaterials.Count)
 
-                 {
 
-                     var mat = GetModifiedMaterial(s_TempMaterials[1], null);
 
-                     for (var k = 1; k < s_Components.Count; k++)
 
-                         mat = (s_Components[k] as IMaterialModifier).GetModifiedMaterial(mat);
 
-                     canvasRenderer.SetMaterial(mat, j++);
 
-                 }
 
-             }
 
-             ClearPreviousMaterials();
 
-         }
 
-         private void ClearPreviousMaterials()
 
-         {
 
-             foreach (var m in s_PrevMaskMaterials)
 
-                 StencilMaterial.Remove(m);
 
-             s_PrevMaskMaterials.Clear();
 
-             foreach (var m in s_PrevModifiedMaterials)
 
-                 ModifiedMaterial.Remove(m);
 
-             s_PrevModifiedMaterials.Clear();
 
-         }
 
-         private Material GetModifiedMaterial(Material baseMaterial, Texture2D texture)
 
-         {
 
-             if (0 < m_StencilValue)
 
-             {
 
-                 baseMaterial = StencilMaterial.Add(baseMaterial, (1 << m_StencilValue) - 1, StencilOp.Keep, CompareFunction.Equal, ColorWriteMask.All, (1 << m_StencilValue) - 1, 0);
 
-                 _maskMaterials.Add(baseMaterial);
 
-             }
 
-             if (texture == null && m_AnimatableProperties.Length == 0) return baseMaterial;
 
-             var id = m_AnimatableProperties.Length == 0 ? 0 : GetInstanceID();
 
-             baseMaterial = ModifiedMaterial.Add(baseMaterial, texture, id);
 
-             _modifiedMaterials.Add(baseMaterial);
 
-             return baseMaterial;
 
-         }
 
-         internal void UpdateMaterialProperties()
 
-         {
 
-             if (m_AnimatableProperties.Length == 0) return;
 
-             //
 
-             var count = activeMeshIndices.CountFast();
 
-             var materialCount = Mathf.Max(8, count);
 
-             canvasRenderer.materialCount = materialCount;
 
-             var j = 0;
 
-             for (var i = 0; i < particles.Count; i++)
 
-             {
 
-                 if (materialCount <= j) break;
 
-                 var ps = particles[i];
 
-                 if (!ps) continue;
 
-                 var r = ps.GetComponent<ParticleSystemRenderer>();
 
-                 r.GetSharedMaterials(s_TempMaterials);
 
-                 // Main
 
-                 if (activeMeshIndices[i * 2] && 0 < s_TempMaterials.Count)
 
-                 {
 
-                     UpdateMaterialProperties(r, j);
 
-                     j++;
 
-                 }
 
-             }
 
-         }
 
-         internal void UpdateMaterialProperties(Renderer r, int index)
 
-         {
 
-             if (m_AnimatableProperties.Length == 0 || canvasRenderer.materialCount <= index) return;
 
-             r.GetPropertyBlock(s_Mpb ?? (s_Mpb = new MaterialPropertyBlock()));
 
-             if (s_Mpb.isEmpty) return;
 
-             // #41: Copy the value from MaterialPropertyBlock to CanvasRenderer
 
-             var mat = canvasRenderer.GetMaterial(index);
 
-             if (!mat) return;
 
-             foreach (var ap in m_AnimatableProperties)
 
-             {
 
-                 ap.UpdateMaterialProperties(mat, s_Mpb);
 
-             }
 
-             s_Mpb.Clear();
 
-         }
 
-         /// <summary>
 
-         /// This function is called when the object becomes enabled and active.
 
-         /// </summary>
 
-         protected override void OnEnable()
 
-         {
 
- #if !SERIALIZE_FIELD_MASKABLE
 
-             maskable = m_Maskable;
 
- #endif
 
-             activeMeshIndices.Clear();
 
-             UIParticleUpdater.Register(this);
 
-             particles.Exec(p => p.GetComponent<ParticleSystemRenderer>().enabled = false);
 
-             if (isActiveAndEnabled && m_IgnoreCanvasScaler)
 
-             {
 
-                 _tracker.Add(this, rectTransform, DrivenTransformProperties.Scale);
 
-             }
 
-             // Create objects.
 
-             _bakedMesh = MeshPool.Rent();
 
-             base.OnEnable();
 
-             InitializeIfNeeded();
 
-         }
 
-         private new IEnumerator Start()
 
-         {
 
-             // #147: ParticleSystem creates Particles in wrong position during prewarm
 
-             // #148: Particle Sub Emitter not showing when start game
 
-             var delayToPlay = particles.AnyFast(ps =>
 
-             {
 
-                 ps.GetComponentsInChildren(false, s_ParticleSystems);
 
-                 return s_ParticleSystems.AnyFast(p => p.isPlaying && (p.subEmitters.enabled || p.main.prewarm));
 
-             });
 
-             s_ParticleSystems.Clear();
 
-             if (!delayToPlay) yield break;
 
-             Stop();
 
-             Clear();
 
-             yield return null;
 
-             Play();
 
-         }
 
-         /// <summary>
 
-         /// This function is called when the behaviour becomes disabled.
 
-         /// </summary>
 
-         protected override void OnDisable()
 
-         {
 
-             UIParticleUpdater.Unregister(this);
 
-             if (!_shouldBeRemoved)
 
-                 particles.Exec(p => p.GetComponent<ParticleSystemRenderer>().enabled = true);
 
-             _tracker.Clear();
 
-             // Destroy object.
 
-             MeshPool.Return(_bakedMesh);
 
-             _bakedMesh = null;
 
-             base.OnDisable();
 
-         }
 
-         /// <summary>
 
-         /// Call to update the geometry of the Graphic onto the CanvasRenderer.
 
-         /// </summary>
 
-         protected override void UpdateGeometry()
 
-         {
 
-         }
 
-         /// <summary>
 
-         /// Callback for when properties have been changed by animation.
 
-         /// </summary>
 
-         protected override void OnDidApplyAnimationProperties()
 
-         {
 
-         }
 
-         private void InitializeIfNeeded()
 
-         {
 
-             if (enabled && m_IsTrail)
 
-             {
 
-                 UnityEngine.Debug.LogWarningFormat(this, "[UIParticle] The UIParticle component should be removed: {0}\nReason: UIParticle for trails is no longer needed.", name);
 
-                 gameObject.hideFlags = HideFlags.None;
 
-                 _shouldBeRemoved = true;
 
-                 enabled = false;
 
-                 return;
 
-             }
 
-             if (!this || particles.AnyFast()) return;
 
-             // refresh.
 
- #if UNITY_EDITOR
 
-             if (!Application.isPlaying)
 
-                 UnityEditor.EditorApplication.delayCall += () =>
 
-                 {
 
-                     if (this) RefreshParticles();
 
-                 };
 
-             else
 
- #endif
 
-                 RefreshParticles();
 
-         }
 
- #if UNITY_EDITOR
 
-         protected override void OnValidate()
 
-         {
 
-             SetLayoutDirty();
 
-             SetVerticesDirty();
 
-             m_ShouldRecalculateStencil = true;
 
-             RecalculateClipping();
 
- #if !SERIALIZE_FIELD_MASKABLE
 
-             maskable = m_Maskable;
 
- #endif
 
-         }
 
-         void ISerializationCallbackReceiver.OnBeforeSerialize()
 
-         {
 
-             if (Application.isPlaying) return;
 
-             InitializeIfNeeded();
 
-         }
 
-         void ISerializationCallbackReceiver.OnAfterDeserialize()
 
-         {
 
-             if (m_Scale3D == Vector3.zero)
 
-             {
 
-                 scale = m_Scale;
 
-             }
 
-             UnityEditor.EditorApplication.delayCall += () =>
 
-             {
 
-                 if (Application.isPlaying || !this) return;
 
-                 InitializeIfNeeded();
 
-             };
 
-         }
 
- #endif
 
-     }
 
- }
 
 
  |