From 59f00f3cc1ff35ca1418fbdf1e6057ef76c0cb89 Mon Sep 17 00:00:00 2001 From: mob-sakai <12690315+mob-sakai@users.noreply.github.com> Date: Thu, 27 Jun 2024 11:38:28 +0900 Subject: [PATCH] refactor --- Editor/AnimatablePropertyEditor.cs | 41 ++++---- Editor/UIParticleEditor.cs | 47 +++++---- README.md | 147 ++++++++++++++++------------- Runtime/UIParticle.cs | 83 ++++++++-------- Runtime/UIParticleRenderer.cs | 2 +- 5 files changed, 174 insertions(+), 146 deletions(-) diff --git a/Editor/AnimatablePropertyEditor.cs b/Editor/AnimatablePropertyEditor.cs index 036e308..9e28284 100644 --- a/Editor/AnimatablePropertyEditor.cs +++ b/Editor/AnimatablePropertyEditor.cs @@ -31,35 +31,35 @@ namespace Coffee.UIExtensions } else { - result.Aggregate(s_Sb, (a, b) => s_Sb.AppendFormat("{0}, ", b)); + result.Aggregate(s_Sb, (a, b) => + { + s_Sb.Append(b); + return s_Sb.Append(", "); + }); s_Sb.Length -= 2; } return s_Sb.ToString(); } - public static void Draw(SerializedProperty sp, Material[] mats) + public static void Draw(SerializedProperty sp, List mats) { - bool isClicked; - using (new EditorGUILayout.HorizontalScope(GUILayout.ExpandWidth(false))) - { - var pos = EditorGUILayout.GetControlRect(true); - var label = new GUIContent(sp.displayName, sp.tooltip); - var rect = EditorGUI.PrefixLabel(pos, label); - var text = sp.hasMultipleDifferentValues - ? "-" - : CollectActiveNames(sp, s_ActiveNames); - isClicked = GUI.Button(rect, text, EditorStyles.popup); - } + var pos = EditorGUILayout.GetControlRect(true); + var label = new GUIContent(sp.displayName, sp.tooltip); + var rect = EditorGUI.PrefixLabel(pos, label); + var text = sp.hasMultipleDifferentValues + ? "-" + : CollectActiveNames(sp, s_ActiveNames); - if (!isClicked) return; + if (!GUI.Button(rect, text, EditorStyles.popup)) return; var gm = new GenericMenu(); - gm.AddItem(s_ContentNothing, s_ActiveNames.Count == 0, () => + gm.AddItem(s_ContentNothing, s_ActiveNames.Count == 0, x => { - sp.ClearArray(); - sp.serializedObject.ApplyModifiedProperties(); - }); + var current = (SerializedProperty)x; + current.ClearArray(); + current.serializedObject.ApplyModifiedProperties(); + }, sp); if (!sp.hasMultipleDifferentValues) { @@ -73,7 +73,7 @@ namespace Coffee.UIExtensions } s_Names.Clear(); - for (var j = 0; j < mats.Length; j++) + for (var j = 0; j < mats.Count; j++) { var mat = mats[j]; if (!mat || !mat.shader) continue; @@ -82,8 +82,7 @@ namespace Coffee.UIExtensions { var name = ShaderUtil.GetPropertyName(mat.shader, i); var type = (AnimatableProperty.ShaderPropertyType)ShaderUtil.GetPropertyType(mat.shader, i); - if (s_Names.Contains(name)) continue; - s_Names.Add(name); + if (!s_Names.Add(name)) continue; AddMenu(gm, sp, new ShaderProperty(name, type), true); diff --git a/Editor/UIParticleEditor.cs b/Editor/UIParticleEditor.cs index d9ab0a2..b7a709f 100644 --- a/Editor/UIParticleEditor.cs +++ b/Editor/UIParticleEditor.cs @@ -4,6 +4,7 @@ using System.Text.RegularExpressions; using UnityEditor; using UnityEditorInternal; using UnityEngine; +using UnityEngine.Profiling; using UnityEngine.UI; #if UNITY_2021_2_OR_NEWER @@ -44,6 +45,8 @@ namespace Coffee.UIExtensions private static readonly GUIContent s_ContentRandom = new GUIContent("Random"); private static readonly GUIContent s_ContentScale = new GUIContent("Scale"); private static readonly GUIContent s_ContentPrimary = new GUIContent("Primary"); + private static readonly Regex s_RegexBuiltInGuid = new Regex(@"^0{16}.0{15}$", RegexOptions.Compiled); + private static readonly List s_TempMaterials = new List(); private static bool s_XYZMode; private SerializedProperty _maskable; @@ -169,6 +172,7 @@ namespace Coffee.UIExtensions var current = target as UIParticle; if (!current) return; + Profiler.BeginSample("(UIP:E) OnInspectorGUI"); serializedObject.Update(); // Maskable @@ -180,13 +184,8 @@ namespace Coffee.UIExtensions EditorGUI.EndDisabledGroup(); // AnimatableProperties - var mats = current.particles - .Where(x => x) - .Select(x => x.GetComponent().sharedMaterial) - .Where(x => x) - .ToArray(); - - AnimatablePropertyEditor.Draw(_animatableProperties, mats); + current.GetMaterials(s_TempMaterials); + AnimatablePropertyEditor.Draw(_animatableProperties, s_TempMaterials); // Mesh sharing EditorGUI.BeginChangeCheck(); @@ -194,9 +193,12 @@ namespace Coffee.UIExtensions if (EditorGUI.EndChangeCheck()) { serializedObject.ApplyModifiedProperties(); - foreach (var uip in targets.OfType()) + foreach (var t in targets) { - uip.ResetGroupId(); + if (t is UIParticle uip) + { + uip.ResetGroupId(); + } } } @@ -204,7 +206,7 @@ namespace Coffee.UIExtensions EditorGUILayout.PropertyField(_positionMode); // Auto Scaling - DrawAutoScaling(_autoScalingMode, targets.OfType()); + EditorGUILayout.PropertyField(_autoScalingMode); // Custom View Size EditorGUILayout.PropertyField(_useCustomView); @@ -221,9 +223,7 @@ namespace Coffee.UIExtensions // Target ParticleSystems. EditorGUI.BeginChangeCheck(); - EditorGUI.BeginDisabledGroup(targets.OfType().Any(x => !x.canvas)); _ro.DoLayoutList(); - EditorGUI.EndDisabledGroup(); serializedObject.ApplyModifiedProperties(); if (EditorGUI.EndChangeCheck()) @@ -236,7 +236,8 @@ namespace Coffee.UIExtensions } // Non-UI built-in shader is not supported. - foreach (var mat in current.materials) + Profiler.BeginSample("(UIP:E) Non-UI built-in shader is not supported."); + foreach (var mat in s_TempMaterials) { if (!mat || !mat.shader) continue; var shader = mat.shader; @@ -249,15 +250,18 @@ namespace Coffee.UIExtensions } } + Profiler.EndSample(); + // Does the shader support UI masks? + Profiler.BeginSample("(UIP:E) Does the shader support UI masks?"); if (current.maskable && current.GetComponentInParent(false)) { - foreach (var mat in current.materials) + foreach (var mat in s_TempMaterials) { if (!mat || !mat.shader) continue; var shader = mat.shader; - if (s_Shaders.Contains(shader)) continue; - s_Shaders.Add(shader); + if (!s_Shaders.Add(shader)) continue; + foreach (var propName in s_MaskablePropertyNames) { if (mat.HasProperty(propName)) continue; @@ -271,7 +275,9 @@ namespace Coffee.UIExtensions } } + s_TempMaterials.Clear(); s_Shaders.Clear(); + Profiler.EndSample(); // UIParticle for trail should be removed. var label = "This UIParticle component should be removed. The UIParticle for trails is no longer needed."; @@ -310,12 +316,15 @@ namespace Coffee.UIExtensions } } #endif + Profiler.EndSample(); + EditorApplication.delayCall += () => Profiler.enabled = false; } private static bool IsBuiltInObject(Object obj) { - return AssetDatabase.TryGetGUIDAndLocalFileIdentifier(obj, out var guid, out long _) - && Regex.IsMatch(guid, "^0{16}.0{15}$", RegexOptions.Compiled); + return AssetDatabase.IsMainAsset(obj) + && AssetDatabase.TryGetGUIDAndLocalFileIdentifier(obj, out var guid, out long _) + && s_RegexBuiltInGuid.IsMatch(guid); } #if UNITY_2018 || UNITY_2019 @@ -419,7 +428,7 @@ namespace Coffee.UIExtensions return showMax; } - private static void DrawAutoScaling(SerializedProperty prop, IEnumerable uiParticles) + private static void DrawAutoScaling(SerializedProperty prop) { EditorGUILayout.PropertyField(prop); } diff --git a/README.md b/README.md index 71bff0d..d40fa9d 100644 --- a/README.md +++ b/README.md @@ -17,45 +17,36 @@ The particle rendering is maskable and sortable, without the need for an extra C ## 📝 Description -![](https://user-images.githubusercontent.com/12690315/41771577-8da4b968-7650-11e8-9524-cd162c422d9d.gif) +![Demo](https://user-images.githubusercontent.com/12690315/41771577-8da4b968-7650-11e8-9524-cd162c422d9d.gif) -This package utilizes the new APIs `MeshBake/MashTrailBake` (introduced with Unity 2018.2) to render particles through -CanvasRenderer. -You can render, mask, and sort your ParticleSystems for UI without the necessity of an additional Camera, RenderTexture, -or Canvas. +This package uses the new APIs `MeshBake/MeshTrailBake` (introduced in Unity 2018.2) to render particles through CanvasRenderer. +You can render, mask, and sort your ParticleSystems for UI without the need for an additional Camera, RenderTexture, or Canvas. -### Features +### Key Features -* Easy to use: The package is ready to use out of the box. -* Sort particle effects and other UI by sibling index. -* No extra Camera, RenderTexture, or Canvas required. -* Masking options for Mask or RectMask2D. -* Support for the Trail module. -* Support for CanvasGroup alpha. -* No allocations needed to render particles. -* Compatibility with overlay, camera space, and world space. -* Support for Universal Render Pipeline (URP) and High Definition Render Pipeline (HDRP). -* Support for disabling `Enter Play Mode Options > Reload Domain`. -* Support for changing material property with AnimationClip (AnimatableProperty). - ![AnimatableProperty.gif][AnimatableProperty.gif] -* [4.0.0+] Support for 8+ materials. -* [4.0.0+] Correct world space particle position adjustment when changing window size for standalone platforms (Windows, - MacOSX, and Linux). -* [4.0.0+] Adaptive scaling for UI. -* [4.0.0+] Mesh sharing group to improve performance. - ![MeshSharing.gif][MeshSharing.gif] -* [4.0.0+] Particle attractor component. - ![ParticleAttractor.gif][ParticleAttractor.gif] -* [4.1.0+] Relative/Absolute particle position mode. - ![AbsolutePosition.gif][AbsolutePosition.gif] - -[AnimatableProperty.gif]: https://user-images.githubusercontent.com/12690315/53286323-2d94a980-37b0-11e9-8afb-c4a207805ff2.gif - -[MeshSharing.gif]: https://user-images.githubusercontent.com/12690315/174311048-c882df81-6c34-4eba-b0aa-5645457692f1.gif - -[ParticleAttractor.gif]: https://user-images.githubusercontent.com/12690315/174311027-462929a4-13f0-4ec4-86ea-9c832f2eecf1.gif - -[AbsolutePosition.gif]: https://user-images.githubusercontent.com/12690315/175751579-5a2357e8-2ecf-4afd-83c8-66e9771bde39.gif +* **Easy to use:** The package is ready to use out of the box. +* **Sortable:** Sort particle effects and other UI elements by sibling index. +* **Maskable:** Supports `Mask` or `RectMask2D`. +* **No extra components required:** No need for an additional `Camera`, `RenderTexture`, or `Canvas`. +* **Trail module support:** Fully supports the Trail module. +* **CanvasGroup alpha support:** Integrates with `CanvasGroup` alpha. +* **No allocations:** Efficiently renders particles without allocations. +* **Any canvas render mode support:** Works with overlay, camera space, and world space. +* **Any Render pipeline support:** Compatible with Universal Render Pipeline (URP) and High Definition Render Pipeline (HDRP). +* **Disabling domain reload support:** Supports disabling `Enter Play Mode Options > Reload Domain`. +* **Animatable material properties:** Supports changing material properties with AnimationClip (AnimatableProperty). + ![AnimatableProperty.gif](https://user-images.githubusercontent.com/12690315/53286323-2d94a980-37b0-11e9-8afb-c4a207805ff2.gif) +* **Multiple materials:** Supports 8+ materials. +* **Correct positioning:** Adjusts world space particle positions correctly when changing window size for standalone platforms (Windows, MacOSX, and Linux). +* **Adaptive scaling:** Provides adaptive scaling for UI (AutoScalingMode). +* **Performance optimization:** Mesh sharing group to improve performance. + MeshSharing.gif +* **Particle attractor:** Includes a particle attractor component. + ParticleAttractor.gif +* **Emission position mode:** Supports relative/absolute particle emission position modes. + AbsolutePosition.gif +* **Custom view size:** Fixes min/max particle size mismatch. + ![CustomViewSize.gif](https://github.com/mob-sakai/ParticleEffectForUGUI/assets/12690315/dd929959-1a37-420b-b13d-e849022b9c9d)

@@ -76,44 +67,55 @@ or Canvas. [JMO]: https://assetstore.unity.com/publishers/1669 -

## ⚙ Installation -_This package requires Unity 2018.3 or later._ +_This package requires **Unity 2018.3 or later**._ #### Install via OpenUPM -This package is available on [OpenUPM](https://openupm.com) package registry. -This is the preferred method of installation, as you can easily receive updates as they're released. +- This package is available on [OpenUPM](https://openupm.com) package registry. +- This is the preferred method of installation, as you can easily receive updates as they're released. +- If you have [openupm-cli](https://github.com/openupm/openupm-cli) installed, then run the following command in your project's directory: + ``` + openupm add com.coffee.ui-particle + ``` +- To update the package, use Package Manager UI (`Window > Package Manager`) or run the following command with `@{version}`: + ``` + openupm add com.coffee.ui-particle@4.8.0 + ``` -If you have [openupm-cli](https://github.com/openupm/openupm-cli) installed, then run the following command in your -project's directory: +#### Install via UPM (with Package Manager UI) -```sh -openupm add com.coffee.ui-particle -``` +- Click `Window > Package Manager` to open Package Manager UI. +- Click `+ > Add package from git URL...` and input the repository URL: `https://github.com/mob-sakai/ParticleEffectForUGUI.git` + ![](https://gist.github.com/assets/12690315/24af63ed-8a2e-483d-9023-7aa53d913330) +- To update the package, change suffix `#{version}` to the target version. + - e.g. `https://github.com/mob-sakai/ParticleEffectForUGUI.git#4.8.0` -#### Install via UPM (using Git URL) +#### Install via UPM (Manually) -Navigate to your project's Packages folder and open the `manifest.json` file. Then add this package somewhere in -the `dependencies` block: - -```json -{ - "dependencies": { - "com.coffee.ui-particle": "https://github.com/mob-sakai/ParticleEffectForUGUI.git", - ... +- Open the `Packages/manifest.json` file in your project. Then add this package somewhere in the `dependencies` block: + ```json + { + "dependencies": { + "com.coffee.ui-particle": "https://github.com/mob-sakai/ParticleEffectForUGUI.git", + ... + } } -} -``` + ``` -To update the package, change suffix `#{version}` to the target version. +- To update the package, change suffix `#{version}` to the target version. + - e.g. `"com.coffee.ui-particle": "https://github.com/mob-sakai/ParticleEffectForUGUI.git#4.8.0",` -* e.g. `"com.coffee.ui-particle": "https://github.com/mob-sakai/ParticleEffectForUGUI.git#4.6.0",` +#### Install as Embedded Package -Or, use [UpmGitExtension](https://github.com/mob-sakai/UpmGitExtension) to install and update the package. +1. Download a source code zip file from [Releases](https://github.com/mob-sakai/ParticleEffectForUGUI.git/releases) and extract it. +2. Place it in your project's `Packages` directory. + ![](https://github.com/mob-sakai/mob-sakai/assets/12690315/0b7484b4-5fca-43b0-a9ef-e5dbd99bcdb4) +- If you want to fix bugs or add features, install it as an embedded package. +- To update the package, you need to re-download it and replace the contents.

@@ -133,19 +135,28 @@ Or, use [UpmGitExtension](https://github.com/mob-sakai/UpmGitExtension) to insta `UIParticle` controls the ParticleSystems that are attached to its own game objects and child game objects. -![](https://github.com/mob-sakai/ParticleEffectForUGUI/assets/12690315/3559df45-63e7-4c4c-9233-f455779efa29) +![](https://github.com/mob-sakai/ParticleEffectForUGUI/assets/12690315/1cf5753b-33fc-4cef-91c3-413c515a954f) -- **Maskable**: Does this graphic allow masking. -- **Scale**: Scale the rendering. When the `3D` toggle is enabled, 3D scale (x, y, z) is supported. +- **Maskable**: Does this graphic allow maskable. +- **Scale**: Scale the rendering particles. When the `3D` toggle is enabled, 3D scale (x, y, z) is supported. - **Animatable Properties**: If you want to update material properties (e.g., `_MainTex_ST`, `_Color`) in AnimationClip, - use this to mark the changes. + use this to mark as animatable. - **Mesh Sharing**: Particle simulation results are shared within the same group. A large number of the same effects can be displayed with a small load. When the `Random` toggle is enabled, it will be grouped randomly. + - **None:** Disable mesh sharing. + - **Auto:** Automatically select Primary/Replica. + - **Primary:** Provides particle simulation results to the same group. + - **Primary Simulator:** Primary, but do not render the particle (simulation only). + - **Replica:** Render simulation results provided by the primary. - **Position Mode**: Emission position mode. - - **Absolute:** Emit from the world position of the `ParticleSystem`. - - **Relative:** Emit from the scaled position of the `ParticleSystem`. -- **Auto Scaling**: `Transform.lossyScale` (=world scale) will be set to `(1, 1, 1)` on update. It prevents the - root-Canvas scale from affecting the hierarchy-scaled `ParticleSystem`. + - **Absolute:** The particles will be emitted from the world position. + - **Relative:** The particles will be emitted from the scaled position. +- **Auto Scaling Mode**: How to automatically adjust when the Canvas scale is changed by the screen size or reference resolution. + - **None:** Do nothing. + - **Transform:** Transform.lossyScale (=world scale) will be set to (1, 1, 1). + - **UIParticle:** UIParticle.scale will be adjusted. +- **Use Custom View:** Use this if the particles are not displayed correctly due to min/max particle size. + - **Custom view size:** Change the bake view size. - **Rendering Order**: The ParticleSystem list to be rendered. You can change the order and the materials. **NOTE:** Press the `Refresh` button to reconstruct the rendering order based on children ParticleSystem's sorting order @@ -206,7 +217,7 @@ uiParticle.Stop(); `UIParticleAttractor` attracts particles generated by the specified ParticleSystem. -![](https://github.com/mob-sakai/ParticleEffectForUGUI/assets/12690315/ea6ae0ed-f9a8-437c-8baa-47526303391e) +![](https://github.com/mob-sakai/ParticleEffectForUGUI/assets/12690315/5c20ad73-4b9a-4f38-9cdc-119df5cce077) ![](https://user-images.githubusercontent.com/12690315/174311027-462929a4-13f0-4ec4-86ea-9c832f2eecf1.gif) - **Particle System**: Attracts particles generated by the specified particle system. diff --git a/Runtime/UIParticle.cs b/Runtime/UIParticle.cs index 36b6c27..ce59d7c 100644 --- a/Runtime/UIParticle.cs +++ b/Runtime/UIParticle.cs @@ -58,12 +58,12 @@ namespace Coffee.UIExtensions [Obsolete] internal bool m_AbsoluteMode; - [Tooltip("Particle effect scale")] + [Tooltip("Scale the rendering particles. When the `3D` toggle is enabled, 3D scale (x, y, z) is supported.")] [SerializeField] private Vector3 m_Scale3D = new Vector3(1, 1, 1); - [Tooltip("Animatable material properties.\n" + - "If you want to change the material properties of the ParticleSystem in Animation, enable it.")] + [Tooltip("If you want to update material properties (e.g. _MainTex_ST, _Color) in AnimationClip, " + + "use this to mark as animatable.")] [SerializeField] internal AnimatableProperty[] m_AnimatableProperties = new AnimatableProperty[0]; @@ -71,12 +71,13 @@ namespace Coffee.UIExtensions [SerializeField] private List m_Particles = new List(); - [Tooltip("Mesh sharing.\n" + - "None: disable mesh sharing.\n" + - "Auto: automatically select Primary/Replica.\n" + - "Primary: provides particle simulation results to the same group.\n" + + [Tooltip("Particle simulation results are shared within the same group. " + + "A large number of the same effects can be displayed with a small load.\n" + + "None: Disable mesh sharing.\n" + + "Auto: Automatically select Primary/Replica.\n" + + "Primary: Provides particle simulation results to the same group.\n" + "Primary Simulator: Primary, but do not render the particle (simulation only).\n" + - "Replica: render simulation results provided by the primary.")] + "Replica: Render simulation results provided by the primary.")] [SerializeField] private MeshSharing m_MeshSharing = MeshSharing.None; @@ -88,19 +89,22 @@ namespace Coffee.UIExtensions [SerializeField] private int m_GroupMaxId; - [Tooltip("Relative: The particles will be emitted from the scaled position of ParticleSystem.\n" + - "Absolute: The particles will be emitted from the world position of ParticleSystem.")] + [Tooltip("Emission position mode.\n" + + "Relative: The particles will be emitted from the scaled position.\n" + + "Absolute: The particles will be emitted from the world position.")] [SerializeField] private PositionMode m_PositionMode = PositionMode.Relative; [SerializeField] - [Tooltip("Prevent the root-Canvas scale from affecting the hierarchy-scaled ParticleSystem.")] [Obsolete] internal bool m_AutoScaling; [SerializeField] - [Tooltip("Transform: Transform.lossyScale (=world scale) will be set to (1, 1, 1)." + - "UIParticle: UIParticle.scale will be adjusted.")] + [Tooltip( + "How to automatically adjust when the Canvas scale is changed by the screen size or reference resolution.\n" + + "None: Do nothing.\n" + + "Transform: Transform.lossyScale (=world scale) will be set to (1, 1, 1).\n" + + "UIParticle: UIParticle.scale will be adjusted.")] private AutoScalingMode m_AutoScalingMode = AutoScalingMode.Transform; [SerializeField] @@ -117,12 +121,12 @@ namespace Coffee.UIExtensions private bool m_Maskable = true; private readonly List _renderers = new List(); + private Camera _bakeCamera; private Canvas _canvas; private int _groupId; - private Camera _bakeCamera; - private DrivenRectTransformTracker _tracker; - private Vector3 _storedScale; private bool _isScaleStored; + private Vector3 _storedScale; + private DrivenRectTransformTracker _tracker; public RectTransform rectTransform => transform as RectTransform; @@ -158,7 +162,8 @@ namespace Coffee.UIExtensions } /// - /// Mesh sharing. + /// Particle simulation results are shared within the same group. + /// A large number of the same effects can be displayed with a small load. /// None: disable mesh sharing. /// Auto: automatically select Primary/Replica. /// Primary: provides particle simulation results to the same group. @@ -201,9 +206,9 @@ namespace Coffee.UIExtensions } /// - /// Particle position mode. - /// Relative: The particles will be emitted from the scaled position of the ParticleSystem. - /// Absolute: The particles will be emitted from the world position of the ParticleSystem. + /// Emission position mode. + /// Relative: The particles will be emitted from the scaled position. + /// Absolute: The particles will be emitted from the world position. /// public PositionMode positionMode { @@ -216,6 +221,7 @@ namespace Coffee.UIExtensions /// Relative: The particles will be emitted from the scaled position of the ParticleSystem. /// Absolute: The particles will be emitted from the world position of the ParticleSystem. /// + [Obsolete("The absoluteMode is now obsolete. Please use the autoScalingMode instead.", false)] public bool absoluteMode { get => m_PositionMode == PositionMode.Absolute; @@ -233,8 +239,12 @@ namespace Coffee.UIExtensions } /// - /// Auto scaling mode. + /// How to automatically adjust when the Canvas scale is changed by the screen size or reference resolution. + /// + /// None: Do nothing. + /// /// Transform: Transform.lossyScale (=world scale) will be set to (1, 1, 1). + /// /// UIParticle: UIParticle.scale will be adjusted. /// public AutoScalingMode autoScalingMode @@ -318,22 +328,6 @@ namespace Coffee.UIExtensions public List particles => m_Particles; - /// - /// Get all base materials to render. - /// - public IEnumerable materials - { - get - { - for (var i = 0; i < _renderers.Count; i++) - { - var r = _renderers[i]; - if (!r || !r.material) continue; - yield return r.material; - } - } - } - /// /// Paused. /// @@ -492,6 +486,21 @@ namespace Coffee.UIExtensions isPaused = true; } + /// + /// Get all base materials to render. + /// + public void GetMaterials(List result) + { + if (result == null) return; + + for (var i = 0; i < _renderers.Count; i++) + { + var r = _renderers[i]; + if (!r || !r.material) continue; + result.Add(r.material); + } + } + /// /// Refresh UIParticle using the ParticleSystem instance. /// diff --git a/Runtime/UIParticleRenderer.cs b/Runtime/UIParticleRenderer.cs index b75bc2e..f28f6d0 100644 --- a/Runtime/UIParticleRenderer.cs +++ b/Runtime/UIParticleRenderer.cs @@ -29,6 +29,7 @@ namespace Coffee.UIExtensions private static readonly Vector3[] s_Corners = new Vector3[4]; private bool _delay; private int _index; + private bool _isPrevStored; private bool _isTrail; private Bounds _lastBounds; private Material _materialForRendering; @@ -38,7 +39,6 @@ namespace Coffee.UIExtensions private float _prevCanvasScale; private Vector3 _prevPsPos; private Vector3 _prevScale; - private bool _isPrevStored; private Vector2Int _prevScreenSize; private bool _preWarm; private ParticleSystemRenderer _renderer;