Compare commits

...

9 Commits

Author SHA1 Message Date
semantic-release-bot
aff35a65fd chore(release): 5.0.0-preview.4 [skip ci]
# [5.0.0-preview.4](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v5.0.0-preview.3...v5.0.0-preview.4) (2024-06-27)

### Bug Fixes

* generated baking-camera object remains in the prefab or scene (again) ([5babd6d](5babd6d07b))
* SetParticleSystemInstance/Prefab APIs destroy generated objects ([4b30c16](4b30c16b9a))

### Features

* add 'custom view' option. ([4252f11](4252f1199b))
* restore `Transform.localScale` when setting `autoScalingMode` to something other than `Transform` (again) ([04232b6](04232b6749))
* the rendering order list in inspector is now more compact ([9212eaa](9212eaa84c))
2024-06-27 07:51:20 +00:00
mob-sakai
68c066e58c refactor 2024-06-27 16:48:23 +09:00
mob-sakai
e96b1dc7c0 update coffee.internal 2024-06-27 16:26:48 +09:00
mob-sakai
59f00f3cc1 refactor 2024-06-27 16:25:28 +09:00
mob-sakai
2d9f247ef2 feat: the rendering order list in inspector is now more compact 2024-06-27 16:23:48 +09:00
mob-sakai
58d6badb7b feat: restore Transform.localScale when setting autoScalingMode to something other than Transform (again) 2024-06-27 16:23:39 +09:00
mob-sakai
8f9d0bdc64 feat: add 'custom view' option.
Use this if the particles are not displayed correctly due to min/max particle size.
2024-06-27 16:23:30 +09:00
mob-sakai
8bcc87e644 fix: generated baking-camera object remains in the prefab or scene (again) 2024-06-27 16:22:24 +09:00
mob-sakai
0a67cc99bc fix: SetParticleSystemInstance/Prefab APIs destroy generated objects 2024-06-27 16:22:10 +09:00
12 changed files with 320 additions and 211 deletions

View File

@@ -1,3 +1,18 @@
# [5.0.0-preview.4](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v5.0.0-preview.3...v5.0.0-preview.4) (2024-06-27)
### Bug Fixes
* generated baking-camera object remains in the prefab or scene (again) ([5babd6d](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/5babd6d07b2ac17341a29964baf552785cefd90e))
* SetParticleSystemInstance/Prefab APIs destroy generated objects ([4b30c16](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/4b30c16b9a48531873f9be91eec2a573370d17a1))
### Features
* add 'custom view' option. ([4252f11](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/4252f1199b8a7038a6fb447989534c512ec40283))
* restore `Transform.localScale` when setting `autoScalingMode` to something other than `Transform` (again) ([04232b6](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/04232b67491e4506dbf84ce77c1dee7127936a3a))
* the rendering order list in inspector is now more compact ([9212eaa](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/9212eaa84c85524c00f9228ff8ba887e028838dc))
# [5.0.0-preview.3](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v5.0.0-preview.2...v5.0.0-preview.3) (2024-06-21) # [5.0.0-preview.3](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v5.0.0-preview.2...v5.0.0-preview.3) (2024-06-21)

View File

@@ -31,35 +31,35 @@ namespace Coffee.UIExtensions
} }
else 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; s_Sb.Length -= 2;
} }
return s_Sb.ToString(); return s_Sb.ToString();
} }
public static void Draw(SerializedProperty sp, Material[] mats) public static void Draw(SerializedProperty sp, List<Material> mats)
{ {
bool isClicked; var pos = EditorGUILayout.GetControlRect(true);
using (new EditorGUILayout.HorizontalScope(GUILayout.ExpandWidth(false))) var label = new GUIContent(sp.displayName, sp.tooltip);
{ var rect = EditorGUI.PrefixLabel(pos, label);
var pos = EditorGUILayout.GetControlRect(true); var text = sp.hasMultipleDifferentValues
var label = new GUIContent(sp.displayName, sp.tooltip); ? "-"
var rect = EditorGUI.PrefixLabel(pos, label); : CollectActiveNames(sp, s_ActiveNames);
var text = sp.hasMultipleDifferentValues
? "-"
: CollectActiveNames(sp, s_ActiveNames);
isClicked = GUI.Button(rect, text, EditorStyles.popup);
}
if (!isClicked) return; if (!GUI.Button(rect, text, EditorStyles.popup)) return;
var gm = new GenericMenu(); var gm = new GenericMenu();
gm.AddItem(s_ContentNothing, s_ActiveNames.Count == 0, () => gm.AddItem(s_ContentNothing, s_ActiveNames.Count == 0, x =>
{ {
sp.ClearArray(); var current = (SerializedProperty)x;
sp.serializedObject.ApplyModifiedProperties(); current.ClearArray();
}); current.serializedObject.ApplyModifiedProperties();
}, sp);
if (!sp.hasMultipleDifferentValues) if (!sp.hasMultipleDifferentValues)
{ {
@@ -73,7 +73,7 @@ namespace Coffee.UIExtensions
} }
s_Names.Clear(); s_Names.Clear();
for (var j = 0; j < mats.Length; j++) for (var j = 0; j < mats.Count; j++)
{ {
var mat = mats[j]; var mat = mats[j];
if (!mat || !mat.shader) continue; if (!mat || !mat.shader) continue;
@@ -82,8 +82,7 @@ namespace Coffee.UIExtensions
{ {
var name = ShaderUtil.GetPropertyName(mat.shader, i); var name = ShaderUtil.GetPropertyName(mat.shader, i);
var type = (AnimatableProperty.ShaderPropertyType)ShaderUtil.GetPropertyType(mat.shader, i); var type = (AnimatableProperty.ShaderPropertyType)ShaderUtil.GetPropertyType(mat.shader, i);
if (s_Names.Contains(name)) continue; if (!s_Names.Add(name)) continue;
s_Names.Add(name);
AddMenu(gm, sp, new ShaderProperty(name, type), true); AddMenu(gm, sp, new ShaderProperty(name, type), true);

View File

@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 3e440931f761e4e888510a4e6045287a
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -4,6 +4,7 @@ using System.Text.RegularExpressions;
using UnityEditor; using UnityEditor;
using UnityEditorInternal; using UnityEditorInternal;
using UnityEngine; using UnityEngine;
using UnityEngine.Profiling;
using UnityEngine.UI; using UnityEngine.UI;
#if UNITY_2021_2_OR_NEWER #if UNITY_2021_2_OR_NEWER
@@ -31,14 +32,21 @@ namespace Coffee.UIExtensions
//################################ //################################
// Constant or Static Members. // Constant or Static Members.
//################################ //################################
private static readonly GUIContent[] s_ContentMaterials = new[]
{
new GUIContent("Material"),
new GUIContent("Trail Material")
};
private static readonly GUIContent s_ContentRenderingOrder = new GUIContent("Rendering Order"); private static readonly GUIContent s_ContentRenderingOrder = new GUIContent("Rendering Order");
private static readonly GUIContent s_ContentRefresh = new GUIContent("Refresh"); private static readonly GUIContent s_ContentRefresh = new GUIContent("Refresh");
private static readonly GUIContent s_ContentFix = new GUIContent("Fix"); private static readonly GUIContent s_ContentFix = new GUIContent("Fix");
private static readonly GUIContent s_ContentMaterial = new GUIContent("Material");
private static readonly GUIContent s_ContentTrailMaterial = new GUIContent("Trail Material");
private static readonly GUIContent s_Content3D = new GUIContent("3D"); private static readonly GUIContent s_Content3D = new GUIContent("3D");
private static readonly GUIContent s_ContentRandom = new GUIContent("Random"); private static readonly GUIContent s_ContentRandom = new GUIContent("Random");
private static readonly GUIContent s_ContentScale = new GUIContent("Scale"); 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<Material> s_TempMaterials = new List<Material>();
private static bool s_XYZMode; private static bool s_XYZMode;
private SerializedProperty _maskable; private SerializedProperty _maskable;
@@ -49,6 +57,8 @@ namespace Coffee.UIExtensions
private SerializedProperty _groupMaxId; private SerializedProperty _groupMaxId;
private SerializedProperty _positionMode; private SerializedProperty _positionMode;
private SerializedProperty _autoScalingMode; private SerializedProperty _autoScalingMode;
private SerializedProperty _useCustomView;
private SerializedProperty _customViewSize;
private ReorderableList _ro; private ReorderableList _ro;
private bool _showMax; private bool _showMax;
@@ -82,31 +92,43 @@ namespace Coffee.UIExtensions
_groupMaxId = serializedObject.FindProperty("m_GroupMaxId"); _groupMaxId = serializedObject.FindProperty("m_GroupMaxId");
_positionMode = serializedObject.FindProperty("m_PositionMode"); _positionMode = serializedObject.FindProperty("m_PositionMode");
_autoScalingMode = serializedObject.FindProperty("m_AutoScalingMode"); _autoScalingMode = serializedObject.FindProperty("m_AutoScalingMode");
_useCustomView = serializedObject.FindProperty("m_UseCustomView");
_customViewSize = serializedObject.FindProperty("m_CustomViewSize");
var sp = serializedObject.FindProperty("m_Particles"); var sp = serializedObject.FindProperty("m_Particles");
_ro = new ReorderableList(sp.serializedObject, sp, true, true, true, true) _ro = new ReorderableList(sp.serializedObject, sp, true, true, true, true)
{ {
elementHeight = EditorGUIUtility.singleLineHeight * 3 + 4, elementHeightCallback = index =>
elementHeightCallback = _ => 3 * (EditorGUIUtility.singleLineHeight + 2), {
var ps = sp.GetArrayElementAtIndex(index).objectReferenceValue as ParticleSystem;
var materialCount = 0;
if (ps && ps.TryGetComponent<ParticleSystemRenderer>(out var psr))
{
materialCount = psr.sharedMaterials.Length;
}
return (materialCount + 1) * (EditorGUIUtility.singleLineHeight + 2);
},
drawElementCallback = (rect, index, _, __) => drawElementCallback = (rect, index, _, __) =>
{ {
EditorGUI.BeginDisabledGroup(sp.hasMultipleDifferentValues); rect.y += 2;
rect.y += 1;
rect.height = EditorGUIUtility.singleLineHeight; rect.height = EditorGUIUtility.singleLineHeight;
var p = sp.GetArrayElementAtIndex(index); var p = sp.GetArrayElementAtIndex(index);
EditorGUI.ObjectField(rect, p, GUIContent.none); EditorGUI.ObjectField(rect, p, GUIContent.none);
var ps = p.objectReferenceValue as ParticleSystem;
if (!ps || !ps.TryGetComponent<ParticleSystemRenderer>(out var psr)) return;
rect.x += 15; rect.x += 15;
rect.width -= 15; rect.width -= 15;
var ps = p.objectReferenceValue as ParticleSystem; var materials = new SerializedObject(psr).FindProperty("m_Materials");
var materials = ps var count = Mathf.Min(materials.arraySize, 2);
? new SerializedObject(ps.GetComponent<ParticleSystemRenderer>()).FindProperty("m_Materials") for (var i = 0; i < count; i++)
: null; {
rect.y += rect.height + 1; rect.y += rect.height + 2;
MaterialField(rect, s_ContentMaterial, materials, 0); EditorGUI.PropertyField(rect, materials.GetArrayElementAtIndex(i), s_ContentMaterials[i]);
rect.y += rect.height + 1; }
MaterialField(rect, s_ContentTrailMaterial, materials, 1);
EditorGUI.EndDisabledGroup(); if (materials.serializedObject.hasModifiedProperties)
if (materials != null && materials.serializedObject.hasModifiedProperties)
{ {
materials.serializedObject.ApplyModifiedProperties(); materials.serializedObject.ApplyModifiedProperties();
} }
@@ -142,20 +164,6 @@ namespace Coffee.UIExtensions
} }
} }
private static void MaterialField(Rect rect, GUIContent label, SerializedProperty sp, int index)
{
if (sp == null || sp.arraySize <= index)
{
EditorGUI.BeginDisabledGroup(true);
EditorGUI.ObjectField(rect, label, null, typeof(Material), true);
EditorGUI.EndDisabledGroup();
}
else
{
EditorGUI.PropertyField(rect, sp.GetArrayElementAtIndex(index), label);
}
}
/// <summary> /// <summary>
/// Implement this function to make a custom inspector. /// Implement this function to make a custom inspector.
/// </summary> /// </summary>
@@ -164,6 +172,7 @@ namespace Coffee.UIExtensions
var current = target as UIParticle; var current = target as UIParticle;
if (!current) return; if (!current) return;
Profiler.BeginSample("(UIP:E) OnInspectorGUI");
serializedObject.Update(); serializedObject.Update();
// Maskable // Maskable
@@ -175,13 +184,8 @@ namespace Coffee.UIExtensions
EditorGUI.EndDisabledGroup(); EditorGUI.EndDisabledGroup();
// AnimatableProperties // AnimatableProperties
var mats = current.particles current.GetMaterials(s_TempMaterials);
.Where(x => x) AnimatablePropertyEditor.Draw(_animatableProperties, s_TempMaterials);
.Select(x => x.GetComponent<ParticleSystemRenderer>().sharedMaterial)
.Where(x => x)
.ToArray();
AnimatablePropertyEditor.Draw(_animatableProperties, mats);
// Mesh sharing // Mesh sharing
EditorGUI.BeginChangeCheck(); EditorGUI.BeginChangeCheck();
@@ -189,9 +193,12 @@ namespace Coffee.UIExtensions
if (EditorGUI.EndChangeCheck()) if (EditorGUI.EndChangeCheck())
{ {
serializedObject.ApplyModifiedProperties(); serializedObject.ApplyModifiedProperties();
foreach (var uip in targets.OfType<UIParticle>()) foreach (var t in targets)
{ {
uip.ResetGroupId(); if (t is UIParticle uip)
{
uip.ResetGroupId();
}
} }
} }
@@ -199,16 +206,29 @@ namespace Coffee.UIExtensions
EditorGUILayout.PropertyField(_positionMode); EditorGUILayout.PropertyField(_positionMode);
// Auto Scaling // Auto Scaling
DrawAutoScaling(_autoScalingMode, targets.OfType<UIParticle>()); EditorGUILayout.PropertyField(_autoScalingMode);
// Custom View Size
EditorGUILayout.PropertyField(_useCustomView);
EditorGUI.BeginChangeCheck();
EditorGUI.BeginDisabledGroup(!_useCustomView.boolValue);
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(_customViewSize);
EditorGUI.indentLevel--;
EditorGUI.EndDisabledGroup();
if (EditorGUI.EndChangeCheck())
{
_customViewSize.floatValue = Mathf.Max(0.1f, _customViewSize.floatValue);
}
// Target ParticleSystems. // Target ParticleSystems.
EditorGUI.BeginChangeCheck(); EditorGUI.BeginChangeCheck();
EditorGUI.BeginDisabledGroup(targets.OfType<UIParticle>().Any(x => !x.canvas));
_ro.DoLayoutList(); _ro.DoLayoutList();
EditorGUI.EndDisabledGroup();
serializedObject.ApplyModifiedProperties(); serializedObject.ApplyModifiedProperties();
if (EditorGUI.EndChangeCheck()) if (EditorGUI.EndChangeCheck())
{ {
EditorApplication.QueuePlayerLoopUpdate();
foreach (var uip in targets.OfType<UIParticle>()) foreach (var uip in targets.OfType<UIParticle>())
{ {
uip.RefreshParticles(uip.particles); uip.RefreshParticles(uip.particles);
@@ -216,7 +236,8 @@ namespace Coffee.UIExtensions
} }
// Non-UI built-in shader is not supported. // 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; if (!mat || !mat.shader) continue;
var shader = mat.shader; var shader = mat.shader;
@@ -229,15 +250,18 @@ namespace Coffee.UIExtensions
} }
} }
Profiler.EndSample();
// Does the shader support UI masks? // Does the shader support UI masks?
Profiler.BeginSample("(UIP:E) Does the shader support UI masks?");
if (current.maskable && current.GetComponentInParent<Mask>(false)) if (current.maskable && current.GetComponentInParent<Mask>(false))
{ {
foreach (var mat in current.materials) foreach (var mat in s_TempMaterials)
{ {
if (!mat || !mat.shader) continue; if (!mat || !mat.shader) continue;
var shader = mat.shader; var shader = mat.shader;
if (s_Shaders.Contains(shader)) continue; if (!s_Shaders.Add(shader)) continue;
s_Shaders.Add(shader);
foreach (var propName in s_MaskablePropertyNames) foreach (var propName in s_MaskablePropertyNames)
{ {
if (mat.HasProperty(propName)) continue; if (mat.HasProperty(propName)) continue;
@@ -251,7 +275,9 @@ namespace Coffee.UIExtensions
} }
} }
s_TempMaterials.Clear();
s_Shaders.Clear(); s_Shaders.Clear();
Profiler.EndSample();
// UIParticle for trail should be removed. // UIParticle for trail should be removed.
var label = "This UIParticle component should be removed. The UIParticle for trails is no longer needed."; var label = "This UIParticle component should be removed. The UIParticle for trails is no longer needed.";
@@ -290,12 +316,15 @@ namespace Coffee.UIExtensions
} }
} }
#endif #endif
Profiler.EndSample();
EditorApplication.delayCall += () => Profiler.enabled = false;
} }
private bool IsBuiltInObject(Object obj) private static bool IsBuiltInObject(Object obj)
{ {
return AssetDatabase.TryGetGUIDAndLocalFileIdentifier(obj, out var guid, out long _) return AssetDatabase.IsMainAsset(obj)
&& Regex.IsMatch(guid, "^0{16}.0{15}$", RegexOptions.Compiled); && AssetDatabase.TryGetGUIDAndLocalFileIdentifier(obj, out var guid, out long _)
&& s_RegexBuiltInGuid.IsMatch(guid);
} }
#if UNITY_2018 || UNITY_2019 #if UNITY_2018 || UNITY_2019
@@ -389,7 +418,7 @@ namespace Coffee.UIExtensions
{ {
EditorGUI.BeginDisabledGroup(true); EditorGUI.BeginDisabledGroup(true);
var obj = UIParticleUpdater.GetPrimary(spGroupId.intValue); var obj = UIParticleUpdater.GetPrimary(spGroupId.intValue);
EditorGUILayout.ObjectField("Primary", obj, typeof(UIParticle), false); EditorGUILayout.ObjectField(s_ContentPrimary, obj, typeof(UIParticle), false);
EditorGUI.EndDisabledGroup(); EditorGUI.EndDisabledGroup();
} }
@@ -399,7 +428,7 @@ namespace Coffee.UIExtensions
return showMax; return showMax;
} }
private static void DrawAutoScaling(SerializedProperty prop, IEnumerable<UIParticle> uiParticles) private static void DrawAutoScaling(SerializedProperty prop)
{ {
EditorGUILayout.PropertyField(prop); EditorGUILayout.PropertyField(prop);
} }

150
README.md
View File

@@ -17,45 +17,36 @@ The particle rendering is maskable and sortable, without the need for an extra C
## 📝 Description ## 📝 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 This package uses the new APIs `MeshBake/MeshTrailBake` (introduced in Unity 2018.2) to render particles through CanvasRenderer.
CanvasRenderer. You can render, mask, and sort your ParticleSystems for UI without the need for an additional Camera, RenderTexture, or Canvas.
You can render, mask, and sort your ParticleSystems for UI without the necessity of an additional Camera, RenderTexture,
or Canvas.
### Features ### Key Features
* Easy to use: The package is ready to use out of the box. * **Easy to use:** The package is ready to use out of the box.
* Sort particle effects and other UI by sibling index. * **Sortable:** Sort particle effects and other UI elements by sibling index.
* No extra Camera, RenderTexture, or Canvas required. * **Maskable:** Supports `Mask` or `RectMask2D`.
* Masking options for Mask or RectMask2D. * **No extra components required:** No need for an additional `Camera`, `RenderTexture`, or `Canvas`.
* Support for the Trail module. * **Trail module support:** Fully supports the Trail module.
* Support for CanvasGroup alpha. * **CanvasGroup alpha support:** Integrates with `CanvasGroup` alpha.
* No allocations needed to render particles. * **No allocations:** Efficiently renders particles without allocations.
* Compatibility with overlay, camera space, and world space. * **Any canvas render mode support:** Works with overlay, camera space, and world space.
* Support for Universal Render Pipeline (URP) and High Definition Render Pipeline (HDRP). * **Any Render pipeline support:** Compatible with Universal Render Pipeline (URP) and High Definition Render Pipeline (HDRP).
* Support for disabling `Enter Play Mode Options > Reload Domain`. * **Disabling domain reload support:** Supports disabling `Enter Play Mode Options > Reload Domain`.
* Support for changing material property with AnimationClip (AnimatableProperty). * **Animatable material properties:** Supports changing material properties with AnimationClip (AnimatableProperty).
![AnimatableProperty.gif][AnimatableProperty.gif] ![AnimatableProperty.gif](https://user-images.githubusercontent.com/12690315/53286323-2d94a980-37b0-11e9-8afb-c4a207805ff2.gif)
* [4.0.0+] Support for 8+ materials. * **Multiple materials:** Supports 8+ materials.
* [4.0.0+] Correct world space particle position adjustment when changing window size for standalone platforms (Windows, * **Correct positioning:** Adjusts world space particle positions correctly when changing window size for standalone platforms (Windows, MacOSX, and Linux).
MacOSX, and Linux). * **Adaptive scaling:** Provides adaptive scaling for UI (AutoScalingMode).
* [4.0.0+] Adaptive scaling for UI. * **Performance optimization:** Mesh sharing group to improve performance.
* [4.0.0+] Mesh sharing group to improve performance. <img alt="MeshSharing.gif" src="https://user-images.githubusercontent.com/12690315/174311048-c882df81-6c34-4eba-b0aa-5645457692f1.gif" width="450"/>
![MeshSharing.gif][MeshSharing.gif] * **Particle attractor:** Includes a particle attractor component.
* [4.0.0+] Particle attractor component. <img alt="ParticleAttractor.gif" src="https://user-images.githubusercontent.com/12690315/174311027-462929a4-13f0-4ec4-86ea-9c832f2eecf1.gif" width="450"/>
![ParticleAttractor.gif][ParticleAttractor.gif] * **Emission position mode:** Supports relative/absolute particle emission position modes.
* [4.1.0+] Relative/Absolute particle position mode. <img alt="AbsolutePosition.gif" src="https://user-images.githubusercontent.com/12690315/175751579-5a2357e8-2ecf-4afd-83c8-66e9771bde39.gif" width="450"/>
![AbsolutePosition.gif][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)
[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
<br><br> <br><br>
@@ -76,44 +67,55 @@ or Canvas.
[JMO]: https://assetstore.unity.com/publishers/1669 [JMO]: https://assetstore.unity.com/publishers/1669
<br><br> <br><br>
## ⚙ Installation ## ⚙ Installation
_This package requires Unity 2018.3 or later._ _This package requires **Unity 2018.3 or later**._
#### Install via OpenUPM #### Install via OpenUPM
This package is available on [OpenUPM](https://openupm.com) package registry. - 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 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 #### Install via UPM (with Package Manager UI)
project's directory:
```sh - Click `Window > Package Manager` to open Package Manager UI.
openupm add com.coffee.ui-particle - 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 - Open the `Packages/manifest.json` file in your project. Then add this package somewhere in the `dependencies` block:
the `dependencies` block: ```json
{
```json "dependencies": {
{ "com.coffee.ui-particle": "https://github.com/mob-sakai/ParticleEffectForUGUI.git",
"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.
<br><br> <br><br>
@@ -123,7 +125,8 @@ Or, use [UpmGitExtension](https://github.com/mob-sakai/UpmGitExtension) to insta
- The default value of `UIParticle.scale` has been changed from `10` to `1`. - The default value of `UIParticle.scale` has been changed from `10` to `1`.
- `UIParticle` no longer inherits from `MaskableGraphic`. - `UIParticle` no longer inherits from `MaskableGraphic`.
- - Add project settings for UIParticle
- enableLinearToGamma: Enables LinearToGamma during mesh baking
<br><br> <br><br>
@@ -133,19 +136,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. `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. - **Maskable**: Does this graphic allow maskable.
- **Scale**: Scale the rendering. When the `3D` toggle is enabled, 3D scale (x, y, z) is supported. - **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, - **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 - **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. 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. - **Position Mode**: Emission position mode.
- **Absolute:** Emit from the world position of the `ParticleSystem`. - **Absolute:** The particles will be emitted from the world position.
- **Relative:** Emit from the scaled position of the `ParticleSystem`. - **Relative:** The particles will be emitted from the scaled position.
- **Auto Scaling**: `Transform.lossyScale` (=world scale) will be set to `(1, 1, 1)` on update. It prevents the - **Auto Scaling Mode**: How to automatically adjust when the Canvas scale is changed by the screen size or reference resolution.
root-Canvas scale from affecting the hierarchy-scaled `ParticleSystem`. - **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. - **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 **NOTE:** Press the `Refresh` button to reconstruct the rendering order based on children ParticleSystem's sorting order
@@ -206,7 +218,7 @@ uiParticle.Stop();
`UIParticleAttractor` attracts particles generated by the specified ParticleSystem. `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) ![](https://user-images.githubusercontent.com/12690315/174311027-462929a4-13f0-4ec4-86ea-9c832f2eecf1.gif)
- **Particle System**: Attracts particles generated by the specified particle system. - **Particle System**: Attracts particles generated by the specified particle system.

View File

@@ -50,7 +50,7 @@ namespace Coffee.UIParticleInternal
var childCount = tr.childCount; var childCount = tr.childCount;
for (var i = 0; i < childCount; i++) for (var i = 0; i < childCount; i++)
{ {
tr.GetChild(i).GetComponentsInChildren(results, depth - 1); tr.GetChild(i).GetComponentsInChildren_Internal(results, depth - 1);
} }
} }

View File

@@ -20,6 +20,7 @@ namespace Coffee.UIParticleInternal
/// </summary> /// </summary>
public void Add(T rhs) public void Add(T rhs)
{ {
if (rhs == null) return;
Profiler.BeginSample("(COF)[FastAction] Add Action"); Profiler.BeginSample("(COF)[FastAction] Add Action");
var node = s_NodePool.Rent(); var node = s_NodePool.Rent();
node.Value = rhs; node.Value = rhs;
@@ -32,6 +33,7 @@ namespace Coffee.UIParticleInternal
/// </summary> /// </summary>
public void Remove(T rhs) public void Remove(T rhs)
{ {
if (rhs == null) return;
Profiler.BeginSample("(COF)[FastAction] Remove Action"); Profiler.BeginSample("(COF)[FastAction] Remove Action");
var node = _delegates.Find(rhs); var node = _delegates.Find(rhs);
if (node != null) if (node != null)
@@ -63,6 +65,11 @@ namespace Coffee.UIParticleInternal
node = node.Next; node = node.Next;
} }
} }
public void Clear()
{
_delegates.Clear();
}
} }
/// <summary> /// <summary>

View File

@@ -5,7 +5,6 @@ using Object = UnityEngine.Object;
#if ENABLE_COFFEE_LOGGER #if ENABLE_COFFEE_LOGGER
using System.Reflection; using System.Reflection;
using System.Collections.Generic; using System.Collections.Generic;
#else #else
using Conditional = System.Diagnostics.ConditionalAttribute; using Conditional = System.Diagnostics.ConditionalAttribute;
#endif #endif

View File

@@ -64,11 +64,12 @@ namespace Coffee.UIParticleInternal
#if UNITY_EDITOR #if UNITY_EDITOR
[InitializeOnLoadMethod] [InitializeOnLoadMethod]
#else
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
#endif #endif
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
private static void InitializeOnLoad() private static void InitializeOnLoad()
{ {
Canvas.willRenderCanvases -= OnAfterCanvasRebuild;
s_IsInitializedAfterCanvasRebuild = false;
} }
/// <summary> /// <summary>

View File

@@ -58,12 +58,12 @@ namespace Coffee.UIExtensions
[Obsolete] [Obsolete]
internal bool m_AbsoluteMode; 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] [SerializeField]
private Vector3 m_Scale3D = new Vector3(1, 1, 1); private Vector3 m_Scale3D = new Vector3(1, 1, 1);
[Tooltip("Animatable material properties.\n" + [Tooltip("If you want to update material properties (e.g. _MainTex_ST, _Color) in AnimationClip, " +
"If you want to change the material properties of the ParticleSystem in Animation, enable it.")] "use this to mark as animatable.")]
[SerializeField] [SerializeField]
internal AnimatableProperty[] m_AnimatableProperties = new AnimatableProperty[0]; internal AnimatableProperty[] m_AnimatableProperties = new AnimatableProperty[0];
@@ -71,12 +71,13 @@ namespace Coffee.UIExtensions
[SerializeField] [SerializeField]
private List<ParticleSystem> m_Particles = new List<ParticleSystem>(); private List<ParticleSystem> m_Particles = new List<ParticleSystem>();
[Tooltip("Mesh sharing.\n" + [Tooltip("Particle simulation results are shared within the same group. " +
"None: disable mesh sharing.\n" + "A large number of the same effects can be displayed with a small load.\n" +
"Auto: automatically select Primary/Replica.\n" + "None: Disable mesh sharing.\n" +
"Primary: provides particle simulation results to the same group.\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" + "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] [SerializeField]
private MeshSharing m_MeshSharing = MeshSharing.None; private MeshSharing m_MeshSharing = MeshSharing.None;
@@ -88,31 +89,44 @@ namespace Coffee.UIExtensions
[SerializeField] [SerializeField]
private int m_GroupMaxId; private int m_GroupMaxId;
[Tooltip("Relative: The particles will be emitted from the scaled position of ParticleSystem.\n" + [Tooltip("Emission position mode.\n" +
"Absolute: The particles will be emitted from the world position of ParticleSystem.")] "Relative: The particles will be emitted from the scaled position.\n" +
"Absolute: The particles will be emitted from the world position.")]
[SerializeField] [SerializeField]
private PositionMode m_PositionMode = PositionMode.Relative; private PositionMode m_PositionMode = PositionMode.Relative;
[SerializeField] [SerializeField]
[Tooltip("Prevent the root-Canvas scale from affecting the hierarchy-scaled ParticleSystem.")]
[Obsolete] [Obsolete]
internal bool m_AutoScaling; internal bool m_AutoScaling;
[SerializeField] [SerializeField]
[Tooltip("Transform: Transform.lossyScale (=world scale) will be set to (1, 1, 1)." + [Tooltip(
"UIParticle: UIParticle.scale will be adjusted.")] "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; private AutoScalingMode m_AutoScalingMode = AutoScalingMode.Transform;
[SerializeField]
[Tooltip("Use a custom view.\n" +
"Use this if the particles are not displayed correctly due to min/max particle size.")]
private bool m_UseCustomView;
[SerializeField]
[Tooltip("Custom view size.\n" +
"Change the bake view size.")]
private float m_CustomViewSize = 10;
[SerializeField] [SerializeField]
private bool m_Maskable = true; private bool m_Maskable = true;
private readonly List<UIParticleRenderer> _renderers = new List<UIParticleRenderer>(); private readonly List<UIParticleRenderer> _renderers = new List<UIParticleRenderer>();
private Camera _bakeCamera;
private Canvas _canvas; private Canvas _canvas;
private int _groupId; private int _groupId;
private Camera _bakeCamera;
private DrivenRectTransformTracker _tracker;
private Vector3 _storedScale;
private bool _isScaleStored; private bool _isScaleStored;
private Vector3 _storedScale;
private DrivenRectTransformTracker _tracker;
public RectTransform rectTransform => transform as RectTransform; public RectTransform rectTransform => transform as RectTransform;
@@ -148,7 +162,8 @@ namespace Coffee.UIExtensions
} }
/// <summary> /// <summary>
/// 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. /// None: disable mesh sharing.
/// Auto: automatically select Primary/Replica. /// Auto: automatically select Primary/Replica.
/// Primary: provides particle simulation results to the same group. /// Primary: provides particle simulation results to the same group.
@@ -191,9 +206,9 @@ namespace Coffee.UIExtensions
} }
/// <summary> /// <summary>
/// Particle position mode. /// Emission position mode.
/// Relative: The particles will be emitted from the scaled position of the ParticleSystem. /// Relative: The particles will be emitted from the scaled position.
/// Absolute: The particles will be emitted from the world position of the ParticleSystem. /// Absolute: The particles will be emitted from the world position.
/// </summary> /// </summary>
public PositionMode positionMode public PositionMode positionMode
{ {
@@ -206,6 +221,7 @@ namespace Coffee.UIExtensions
/// Relative: The particles will be emitted from the scaled position of the ParticleSystem. /// 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. /// Absolute: The particles will be emitted from the world position of the ParticleSystem.
/// </summary> /// </summary>
[Obsolete("The absoluteMode is now obsolete. Please use the autoScalingMode instead.", false)]
public bool absoluteMode public bool absoluteMode
{ {
get => m_PositionMode == PositionMode.Absolute; get => m_PositionMode == PositionMode.Absolute;
@@ -223,8 +239,12 @@ namespace Coffee.UIExtensions
} }
/// <summary> /// <summary>
/// Auto scaling mode. /// How to automatically adjust when the Canvas scale is changed by the screen size or reference resolution.
/// <para/>
/// None: Do nothing.
/// <para/>
/// Transform: Transform.lossyScale (=world scale) will be set to (1, 1, 1). /// Transform: Transform.lossyScale (=world scale) will be set to (1, 1, 1).
/// <para/>
/// UIParticle: UIParticle.scale will be adjusted. /// UIParticle: UIParticle.scale will be adjusted.
/// </summary> /// </summary>
public AutoScalingMode autoScalingMode public AutoScalingMode autoScalingMode
@@ -243,6 +263,26 @@ namespace Coffee.UIExtensions
} }
} }
/// <summary>
/// Use a custom view.
/// Use this if the particles are not displayed correctly due to min/max particle size.
/// </summary>
public bool useCustomView
{
get => m_UseCustomView;
set => m_UseCustomView = value;
}
/// <summary>
/// Custom view size.
/// Change the bake view size.
/// </summary>
public float customViewSize
{
get => m_CustomViewSize;
set => m_CustomViewSize = Mathf.Max(0.1f, value);
}
internal bool useMeshSharing => m_MeshSharing != MeshSharing.None; internal bool useMeshSharing => m_MeshSharing != MeshSharing.None;
internal bool isPrimary => internal bool isPrimary =>
@@ -288,22 +328,6 @@ namespace Coffee.UIExtensions
public List<ParticleSystem> particles => m_Particles; public List<ParticleSystem> particles => m_Particles;
/// <summary>
/// Get all base materials to render.
/// </summary>
public IEnumerable<Material> materials
{
get
{
for (var i = 0; i < _renderers.Count; i++)
{
var r = _renderers[i];
if (!r || !r.material) continue;
yield return r.material;
}
}
}
/// <summary> /// <summary>
/// Paused. /// Paused.
/// </summary> /// </summary>
@@ -462,6 +486,21 @@ namespace Coffee.UIExtensions
isPaused = true; isPaused = true;
} }
/// <summary>
/// Get all base materials to render.
/// </summary>
public void GetMaterials(List<Material> 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);
}
}
/// <summary> /// <summary>
/// Refresh UIParticle using the ParticleSystem instance. /// Refresh UIParticle using the ParticleSystem instance.
/// </summary> /// </summary>
@@ -481,6 +520,9 @@ namespace Coffee.UIExtensions
for (var i = 0; i < childCount; i++) for (var i = 0; i < childCount; i++)
{ {
var go = transform.GetChild(i).gameObject; var go = transform.GetChild(i).gameObject;
if (go.TryGetComponent<Camera>(out var cam) && cam == _bakeCamera) continue;
if (go.TryGetComponent<UIParticleRenderer>(out var _)) continue;
go.SetActive(false); go.SetActive(false);
if (destroyOldParticles) if (destroyOldParticles)
{ {
@@ -602,8 +644,12 @@ namespace Coffee.UIExtensions
} }
var currentScale = transform.localScale; var currentScale = transform.localScale;
_storedScale = currentScale; if (!_isScaleStored)
_isScaleStored = true; {
_storedScale = currentScale.IsVisible() ? currentScale : Vector3.one;
_isScaleStored = true;
}
_tracker.Add(this, rectTransform, DrivenTransformProperties.Scale); _tracker.Add(this, rectTransform, DrivenTransformProperties.Scale);
var newScale = parentScale.Inverse(); var newScale = parentScale.Inverse();
if (currentScale != newScale) if (currentScale != newScale)
@@ -671,7 +717,16 @@ namespace Coffee.UIExtensions
private Camera GetBakeCamera() private Camera GetBakeCamera()
{ {
if (!canvas) return Camera.main; if (!canvas) return Camera.main;
if (_bakeCamera) return _bakeCamera; if (!useCustomView && canvas.renderMode != RenderMode.ScreenSpaceOverlay && canvas.rootCanvas.worldCamera)
{
return canvas.rootCanvas.worldCamera;
}
if (_bakeCamera)
{
_bakeCamera.orthographicSize = useCustomView ? customViewSize : 10;
return _bakeCamera;
}
// Find existing baking camera. // Find existing baking camera.
var childCount = transform.childCount; var childCount = transform.childCount;
@@ -688,10 +743,7 @@ namespace Coffee.UIExtensions
// Create baking camera. // Create baking camera.
if (!_bakeCamera) if (!_bakeCamera)
{ {
var go = new GameObject("[generated] UIParticle BakingCamera") var go = new GameObject("[generated] UIParticle BakingCamera");
{
hideFlags = HideFlags.HideAndDontSave
};
go.SetActive(false); go.SetActive(false);
go.transform.SetParent(transform, false); go.transform.SetParent(transform, false);
_bakeCamera = go.AddComponent<Camera>(); _bakeCamera = go.AddComponent<Camera>();
@@ -699,7 +751,7 @@ namespace Coffee.UIExtensions
// Setup baking camera. // Setup baking camera.
_bakeCamera.enabled = false; _bakeCamera.enabled = false;
_bakeCamera.orthographicSize = 1000; _bakeCamera.orthographicSize = useCustomView ? customViewSize : 10;
_bakeCamera.transform.SetPositionAndRotation(new Vector3(0, 0, -1000), Quaternion.identity); _bakeCamera.transform.SetPositionAndRotation(new Vector3(0, 0, -1000), Quaternion.identity);
_bakeCamera.orthographic = true; _bakeCamera.orthographic = true;
_bakeCamera.farClipPlane = 2000f; _bakeCamera.farClipPlane = 2000f;
@@ -710,6 +762,9 @@ namespace Coffee.UIExtensions
_bakeCamera.renderingPath = RenderingPath.Forward; _bakeCamera.renderingPath = RenderingPath.Forward;
_bakeCamera.useOcclusionCulling = false; _bakeCamera.useOcclusionCulling = false;
_bakeCamera.gameObject.SetActive(false);
_bakeCamera.gameObject.hideFlags = HideFlags.HideAndDontSave;
return _bakeCamera; return _bakeCamera;
} }
} }

View File

@@ -25,10 +25,10 @@ namespace Coffee.UIExtensions
private static readonly CombineInstance[] s_CombineInstances = { new CombineInstance() }; private static readonly CombineInstance[] s_CombineInstances = { new CombineInstance() };
private static readonly List<Material> s_Materials = new List<Material>(2); private static readonly List<Material> s_Materials = new List<Material>(2);
private static MaterialPropertyBlock s_Mpb; private static MaterialPropertyBlock s_Mpb;
private static readonly List<UIParticleRenderer> s_Renderers = new List<UIParticleRenderer>(8);
private static readonly Vector3[] s_Corners = new Vector3[4]; private static readonly Vector3[] s_Corners = new Vector3[4];
private bool _delay; private bool _delay;
private int _index; private int _index;
private bool _isPrevStored;
private bool _isTrail; private bool _isTrail;
private Bounds _lastBounds; private Bounds _lastBounds;
private Material _materialForRendering; private Material _materialForRendering;
@@ -38,7 +38,6 @@ namespace Coffee.UIExtensions
private float _prevCanvasScale; private float _prevCanvasScale;
private Vector3 _prevPsPos; private Vector3 _prevPsPos;
private Vector3 _prevScale; private Vector3 _prevScale;
private bool _isPrevStored;
private Vector2Int _prevScreenSize; private Vector2Int _prevScreenSize;
private bool _preWarm; private bool _preWarm;
private ParticleSystemRenderer _renderer; private ParticleSystemRenderer _renderer;
@@ -445,22 +444,25 @@ namespace Coffee.UIExtensions
// Get grouped renderers. // Get grouped renderers.
Profiler.BeginSample("[UIParticleRenderer] Set Mesh"); Profiler.BeginSample("[UIParticleRenderer] Set Mesh");
s_Renderers.Clear(); var renderers = ListPool<UIParticleRenderer>.Rent();
if (_parent.useMeshSharing) if (_parent.useMeshSharing)
{ {
UIParticleUpdater.GetGroupedRenderers(_parent.groupId, _index, s_Renderers); UIParticleUpdater.GetGroupedRenderers(_parent.groupId, _index, renderers);
} }
for (var i = 0; i < s_Renderers.Count; i++) for (var i = 0; i < renderers.Count; i++)
{ {
if (s_Renderers[i] == this) continue; var r = renderers[i];
if (r == this) continue;
s_Renderers[i].canvasRenderer.SetMesh(workerMesh); r.canvasRenderer.SetMesh(workerMesh);
s_Renderers[i]._lastBounds = _lastBounds; r._lastBounds = _lastBounds;
s_Renderers[i].canvasRenderer.materialCount = 1; r.canvasRenderer.materialCount = 1;
s_Renderers[i].canvasRenderer.SetMaterial(materialForRendering, 0); r.canvasRenderer.SetMaterial(materialForRendering, 0);
} }
ListPool<UIParticleRenderer>.Return(ref renderers);
if (_parent.canRender) if (_parent.canRender)
{ {
canvasRenderer.SetMesh(workerMesh); canvasRenderer.SetMesh(workerMesh);
@@ -471,8 +473,6 @@ namespace Coffee.UIExtensions
} }
Profiler.EndSample(); Profiler.EndSample();
s_Renderers.Clear();
} }
public override void SetMaterialDirty() public override void SetMaterialDirty()

View File

@@ -2,7 +2,7 @@
"name": "com.coffee.ui-particle", "name": "com.coffee.ui-particle",
"displayName": "UI Particle", "displayName": "UI Particle",
"description": "This package provides a component to render particle effects for uGUI.\nThe particle rendering is maskable and sortable, without the need for an extra Camera, RenderTexture, or Canvas.", "description": "This package provides a component to render particle effects for uGUI.\nThe particle rendering is maskable and sortable, without the need for an extra Camera, RenderTexture, or Canvas.",
"version": "5.0.0-preview.3", "version": "5.0.0-preview.4",
"unity": "2018.2", "unity": "2018.2",
"license": "MIT", "license": "MIT",
"repository": { "repository": {