Compare commits

...

10 Commits

Author SHA1 Message Date
semantic-release-bot
cf402745f6 chore(release): 5.0.0-preview.17 [skip ci]
# [5.0.0-preview.17](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/5.0.0-preview.16...5.0.0-preview.17) (2026-06-08)

### Bug Fixes

* add `meshCleared` flag to optimize mesh clearing ([859fa20](859fa20d29))
* add early return for case where subEmitter module is disabled ([d1386a1](d1386a1221))
* avoid endless loop ([eb2e862](eb2e862e80)), closes [#392](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/392)
* fix icon ([a9461ec](a9461ecb4d))
* fix Unity6.5 compile errors and warnings ([a5ee687](a5ee687821)), closes [#400](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/400)
* fix URL link in README ([a79ffb2](a79ffb2c2b))
* fix URL link in README ([1c8c65d](1c8c65d25e)), closes [#376](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/376)
* fix: second and subsequent bursts not displayed when world simulation and non-looping ([df2f3ca](df2f3caafb)), closes [#326](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/326)
* ignore "EditorOnly" tagged gameObjects on refresh ([031d46a](031d46a321))
* potential access to UIParticleRenderer that has already been destroyed ([b740dd6](b740dd662d)), closes [#403](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/403)
* UIParticle in canvas with 0f-0.01f alpha value does not start to play until alpha value is greater than 0.01f, causes play calls to be delayed unintentionally if canvas alpha value is set to mentioned value range ([38aec2e](38aec2ea1a))
* updated support for some changed menu paths ([f8ac986](f8ac9869f1)), closes [#397](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/397)

### Features

* explicit null checks ([5384f61](5384f61c56))
2026-06-08 18:45:42 +00:00
mob-sakai
9dbd16920f chore: update release workflow 2026-06-09 03:42:57 +09:00
mob-sakai
cc339fb3f0 Merge branch 'develop' into develop-preview
# Conflicts:
#	.github/workflows/release.yml
#	Packages/src/CHANGELOG.md
#	Packages/src/package.json
2026-06-09 03:41:03 +09:00
semantic-release-bot
18175c040e chore(release): 4.12.2 [skip ci]
## [4.12.2](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.12.1...v4.12.2) (2026-06-08)

### Bug Fixes

* add `meshCleared` flag to optimize mesh clearing ([859fa20](859fa20d29))
* fix Unity6.5 compile errors and warnings ([a5ee687](a5ee687821)), closes [#400](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/400)
* potential access to UIParticleRenderer that has already been destroyed ([b740dd6](b740dd662d)), closes [#403](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/403)
* updated support for some changed menu paths ([f8ac986](f8ac9869f1)), closes [#397](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/397)
2026-06-08 13:33:41 +00:00
mob-sakai
9cd47c32bc chore: ignore alpha for test 2026-06-08 22:33:03 +09:00
mob-sakai
48b38ec34f update internal code 2026-06-08 15:55:42 +09:00
mob-sakai
b740dd662d fix: potential access to UIParticleRenderer that has already been destroyed
close #403
2026-06-08 13:28:24 +09:00
tako
f8ac9869f1 fix: updated support for some changed menu paths
close #397
2026-06-08 13:28:24 +09:00
tako
a5ee687821 fix: fix Unity6.5 compile errors and warnings
close #400
2026-06-08 13:28:24 +09:00
Minhyuk Kim
859fa20d29 fix: add meshCleared flag to optimize mesh clearing 2026-06-08 11:33:57 +09:00
19 changed files with 106 additions and 72 deletions

View File

@@ -25,10 +25,10 @@ jobs:
tag: ${{ steps.release.outputs.new_release_git_tag }}
steps:
- name: 🚚 Checkout (${{ github.ref_name }})
uses: actions/checkout@v4
uses: actions/checkout@v6
- name: 🔖 Run semantic release
uses: cycjimmy/semantic-release-action@v4
uses: cycjimmy/semantic-release-action@v6
id: release
with:
working_directory: Packages/src

View File

@@ -7,9 +7,9 @@ run-name: 🧪 Test (${{ github.event.pull_request.title || github.ref_name }})
env:
# MINIMUM_VERSION: The minimum version of Unity.
MINIMUM_VERSION: 2019.4
MINIMUM_VERSION: 2020.3
# EXCLUDE_FILTER: The excluded versions of Unity.
EXCLUDE_FILTER: "(2020.2.0|2021.1|2023.3)"
EXCLUDE_FILTER: "(2017|2018|2023.3)"
PROJECT_PATH: .
on:
@@ -46,9 +46,9 @@ jobs:
id: setup
run: |
echo "==== Target Unity Versions ===="
LATEST_VERSIONS=`npx unity-changeset@latest list --versions --latest-patch --min ${MINIMUM_VERSION} --json --all`
LATEST_VERSIONS=`npx unity-changeset@latest list --versions --latest-patch --min ${MINIMUM_VERSION} --json --all --ignore-alpha`
if [ "${{ inputs.usePeriodVersions }}" = "true" ]; then
ADDITIONAL_VERSIONS=`npx unity-changeset list --versions --grep '0f' --min ${MINIMUM_VERSION} --json`
ADDITIONAL_VERSIONS=`npx unity-changeset list --versions --grep '0f' --min ${MINIMUM_VERSION} --json --ignore-alpha`
else
ADDITIONAL_VERSIONS=[]
fi
@@ -72,11 +72,11 @@ jobs:
steps:
- name: 🚚 Checkout ($${{ github.ref }})
if: github.event_name == 'push'
uses: actions/checkout@v5
uses: actions/checkout@v6
- name: 🚚 Checkout pull request (pull_request_target)
if: github.event_name == 'pull_request_target'
uses: actions/checkout@v5
uses: actions/checkout@v6
with:
ref: ${{ github.event.pull_request.head.sha }}
fetch-depth: 0
@@ -90,7 +90,7 @@ jobs:
git log --oneline -n 10
- name: 📥 Cache library
uses: actions/cache@v4
uses: actions/cache@v5
with:
path: ${{ env.PROJECT_PATH }}/Library
key: ${{ env.PROJECT_PATH }}-Library-${{ matrix.unityVersion }}-${{ github.event.pull_request.head.sha || github.sha }}
@@ -99,7 +99,7 @@ jobs:
${{ env.PROJECT_PATH }}-Library-
- name: 🛠️ Build Unity Project (Test)
uses: game-ci/unity-builder@main
uses: game-ci/unity-builder@v5
timeout-minutes: 45
with:
customImage: ghcr.io/mob-sakai/unity3d:${{ matrix.unityVersion }}

View File

@@ -1,3 +1,26 @@
# [5.0.0-preview.17](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/5.0.0-preview.16...5.0.0-preview.17) (2026-06-08)
### Bug Fixes
* add `meshCleared` flag to optimize mesh clearing ([859fa20](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/859fa20d297c3f44e3361f20dbb7ce966407e03e))
* add early return for case where subEmitter module is disabled ([d1386a1](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/d1386a12216743a6e09f1b9b87bea1dfcf7702e4))
* avoid endless loop ([eb2e862](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/eb2e862e80e549c8cf16ddfed776c101c2413bac)), closes [#392](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/392)
* fix icon ([a9461ec](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/a9461ecb4d40d7fe878e12465d6e38faae7ae65b))
* fix Unity6.5 compile errors and warnings ([a5ee687](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/a5ee6878212be2fc4d7b48879426f239e8753009)), closes [#400](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/400)
* fix URL link in README ([a79ffb2](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/a79ffb2c2b4c26f23d2925cb18674fda5d8bc9cb))
* fix URL link in README ([1c8c65d](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/1c8c65d25e7f6fe7b1d20da4461333df8fc7578e)), closes [#376](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/376)
* fix: second and subsequent bursts not displayed when world simulation and non-looping ([df2f3ca](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/df2f3caafbe279f1457d74f8183cb561ac14aa17)), closes [#326](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/326)
* ignore "EditorOnly" tagged gameObjects on refresh ([031d46a](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/031d46a3216c942d2d1a6ccfadf5f0b9e3ce3006))
* potential access to UIParticleRenderer that has already been destroyed ([b740dd6](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/b740dd662d423c6bef849662ce1b0bfbb4940ed4)), closes [#403](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/403)
* UIParticle in canvas with 0f-0.01f alpha value does not start to play until alpha value is greater than 0.01f, causes play calls to be delayed unintentionally if canvas alpha value is set to mentioned value range ([38aec2e](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/38aec2ea1afd77677d629c86665a3342d92e49d9))
* updated support for some changed menu paths ([f8ac986](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/f8ac9869f141238169730e74f5d65c4fc6081f51)), closes [#397](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/397)
### Features
* explicit null checks ([5384f61](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/5384f61c569e9f78ff9d5b45acfc6f5c2f021a87))
# [5.0.0-preview.16](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/5.0.0-preview.15...5.0.0-preview.16) (2025-03-15)

View File

@@ -78,10 +78,19 @@ namespace Coffee.UIExtensions
var mat = mats[j];
if (mat == null || mat.shader == null) continue;
#if UNITY_6000_5_OR_NEWER
for (var i = 0; i < mat.shader.GetPropertyCount(); i++)
#else
for (var i = 0; i < ShaderUtil.GetPropertyCount(mat.shader); i++)
#endif
{
#if UNITY_6000_5_OR_NEWER
var name = mat.shader.GetPropertyName(i);
var type = (AnimatableProperty.ShaderPropertyType)mat.shader.GetPropertyType(i);
#else
var name = ShaderUtil.GetPropertyName(mat.shader, i);
var type = (AnimatableProperty.ShaderPropertyType)ShaderUtil.GetPropertyType(mat.shader, i);
#endif
if (!s_Names.Add(name)) continue;
AddMenu(gm, sp, new ShaderProperty(name, type), true);

View File

@@ -6,11 +6,22 @@ namespace Coffee.UIExtensions
{
internal class UIParticleMenu
{
[MenuItem("GameObject/UI/Particle System (Empty)", false, 2018)]
#if UNITY_6000_5_OR_NEWER
private const string k_MenuPathToCreateParticleSystem = "GameObject/Visual Effects/Particle System";
#else
private const string k_MenuPathToCreateParticleSystem = "GameObject/Effects/Particle System";
#endif
#if UNITY_6000_3_OR_NEWER
private const string k_MenuPathForUgui = "GameObject/UI (Canvas)";
#else
private const string k_MenuPathForUgui = "GameObject/UI";
#endif
[MenuItem(k_MenuPathForUgui + "/Particle System (Empty)", false, 2018)]
private static void AddParticleEmpty(MenuCommand menuCommand)
{
// Create empty UI element.
EditorApplication.ExecuteMenuItem("GameObject/UI/Image");
EditorApplication.ExecuteMenuItem(k_MenuPathForUgui + "/Image");
var ui = Selection.activeGameObject;
Object.DestroyImmediate(ui.GetComponent<Image>());
@@ -21,7 +32,7 @@ namespace Coffee.UIExtensions
uiParticle.rectTransform.sizeDelta = Vector2.zero;
}
[MenuItem("GameObject/UI/Particle System", false, 2019)]
[MenuItem(k_MenuPathForUgui + "/Particle System", false, 2019)]
private static void AddParticle(MenuCommand menuCommand)
{
// Create empty UIEffect.
@@ -29,7 +40,7 @@ namespace Coffee.UIExtensions
var uiParticle = Selection.activeGameObject.GetComponent<UIParticle>();
// Create ParticleSystem.
EditorApplication.ExecuteMenuItem("GameObject/Effects/Particle System");
EditorApplication.ExecuteMenuItem(k_MenuPathToCreateParticleSystem);
var ps = Selection.activeGameObject;
ps.transform.SetParent(uiParticle.transform, false);
ps.transform.localPosition = Vector3.zero;

View File

@@ -37,37 +37,17 @@ namespace Coffee.UIExtensions
switch (type)
{
case ShaderPropertyType.Color:
var color = mpb.GetColor(id);
if (color != default)
{
material.SetColor(id, color);
}
material.SetColor(id, mpb.GetColor(id));
break;
case ShaderPropertyType.Vector:
var vector = mpb.GetVector(id);
if (vector != default)
{
material.SetVector(id, vector);
}
material.SetVector(id, mpb.GetVector(id));
break;
case ShaderPropertyType.Float:
case ShaderPropertyType.Range:
var value = mpb.GetFloat(id);
if (!Mathf.Approximately(value, 0))
{
material.SetFloat(id, value);
}
material.SetFloat(id, mpb.GetFloat(id));
break;
case ShaderPropertyType.Texture:
var tex = mpb.GetTexture(id);
if (tex != default(Texture))
{
material.SetTexture(id, tex);
}
material.SetTexture(id, mpb.GetTexture(id));
break;
}
}

View File

@@ -184,7 +184,7 @@ namespace Coffee.UIParticleInternal
/// <summary>
/// Verify whether it can be converted to the specified component.
/// </summary>
internal static bool CanConvertTo<T>(this Object context) where T : MonoBehaviour
internal static bool CanConvertTo<T>(this Object context) where T : MonoBehaviour
{
return context != null && context.GetType() != typeof(T);
}

View File

@@ -158,6 +158,8 @@ namespace Coffee.UIParticleInternal
private void OnPlayModeStateChanged(PlayModeStateChange state)
{
if (!this) return;
switch (state)
{
case PlayModeStateChange.ExitingEditMode:

View File

@@ -11,7 +11,7 @@ using Conditional = System.Diagnostics.ConditionalAttribute;
namespace Coffee.UIParticleInternal
{
internal static class Logging
internal static class Logger
{
#if !ENABLE_COFFEE_LOGGER
private const string k_DisableSymbol = "DISABLE_COFFEE_LOGGER";

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 4f9f22bb079324476b1473030ad9fec3

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 8255313895da84e7cbdc876be3795334
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -20,7 +20,9 @@ namespace Coffee.UIParticleInternal
{
public static T[] FindObjectsOfType<T>() where T : Object
{
#if UNITY_2023_1_OR_NEWER
#if UNITY_6000_4_OR_NEWER
return Object.FindObjectsByType<T>(FindObjectsInactive.Include);
#elif UNITY_2023_1_OR_NEWER
return Object.FindObjectsByType<T>(FindObjectsInactive.Include, FindObjectsSortMode.None);
#else
return Object.FindObjectsOfType<T>();

View File

@@ -34,7 +34,7 @@ namespace Coffee.UIParticleInternal
}
// If there are no instances in the pool, create a new one.
Logging.Log(this, $"A new instance is created (pooled: {_pool.CountInactive}, created: {_pool.CountAll}).");
Logger.Log(this, $"A new instance is created (pooled: {_pool.CountInactive}, created: {_pool.CountAll}).");
return _pool.Get();
}
@@ -47,7 +47,7 @@ namespace Coffee.UIParticleInternal
if (instance == null) return; // Ignore if already pooled or null.
_pool.Release(instance);
Logging.Log(this, $"An instance is released (pooled: {_pool.CountInactive}, created: {_pool.CountAll}).");
Logger.Log(this, $"An instance is released (pooled: {_pool.CountInactive}, created: {_pool.CountAll}).");
instance = default; // Set the reference to null.
}
#else
@@ -80,7 +80,7 @@ namespace Coffee.UIParticleInternal
}
// If there are no instances in the pool, create a new one.
Logging.Log(this, $"A new instance is created (pooled: {_pool.Count}, created: {++_count}).");
Logger.Log(this, $"A new instance is created (pooled: {_pool.Count}, created: {++_count}).");
return _onCreate();
}
@@ -94,7 +94,7 @@ namespace Coffee.UIParticleInternal
_onReturn(instance); // Return the instance to the pool.
_pool.Push(instance);
Logging.Log(this, $"An instance is released (pooled: {_pool.Count}, created: {_count}).");
Logger.Log(this, $"An instance is released (pooled: {_pool.Count}, created: {_count}).");
instance = default; // Set the reference to null.
}
#endif

View File

@@ -103,7 +103,7 @@ namespace Coffee.UIParticleInternal
Release(ref obj);
++entry.reference;
obj = entry.storedObject;
Logging.Log(_name, $"Get(total#{count}): {entry}");
Logger.Log(_name, $"Get(total#{count}): {entry}");
}
Profiler.EndSample();
@@ -130,8 +130,8 @@ namespace Coffee.UIParticleInternal
newEntry.hash = hash;
newEntry.reference = 1;
_cache[hash] = newEntry;
_objectKey[newObject.GetInstanceID()] = hash;
Logging.Log(_name, $"<color=#03c700>Add</color>(total#{count}): {newEntry}");
_objectKey[newObject.GetHashCode()] = hash;
Logger.Log(_name, $"<color=#03c700>Add</color>(total#{count}): {newEntry}");
Release(ref obj);
obj = newObject;
Profiler.EndSample();
@@ -146,7 +146,7 @@ namespace Coffee.UIParticleInternal
// Find and release the entry.
Profiler.BeginSample("(COF)[ObjectRepository] Release");
var id = obj.GetInstanceID();
var id = obj.GetHashCode();
if (_objectKey.TryGetValue(id, out var hash)
&& _cache.TryGetValue(hash, out var entry))
{
@@ -157,12 +157,12 @@ namespace Coffee.UIParticleInternal
}
else
{
Logging.Log(_name, $"Release(total#{_cache.Count}): {entry}");
Logger.Log(_name, $"Release(total#{_cache.Count}): {entry}");
}
}
else
{
Logging.Log(_name, $"Release(total#{_cache.Count}): <color=red>Already released: {obj}</color>");
Logger.Log(_name, $"Release(total#{_cache.Count}): <color=red>Already released: {obj}</color>");
}
obj = null;
@@ -175,10 +175,10 @@ namespace Coffee.UIParticleInternal
Profiler.BeginSample("(COF)[ObjectRepository] Remove");
_cache.Remove(entry.hash);
_objectKey.Remove(entry.storedObject.GetInstanceID());
_objectKey.Remove(entry.storedObject.GetHashCode());
_pool.Push(entry);
entry.reference = 0;
Logging.Log(_name, $"<color=#f29e03>Remove</color>(total#{_cache.Count}): {entry}");
Logger.Log(_name, $"<color=#f29e03>Remove</color>(total#{_cache.Count}): {entry}");
entry.Release(_onRelease);
Profiler.EndSample();
}

View File

@@ -1,4 +1,5 @@
using System;
using System.Reflection;
using UnityEditor;
using UnityEngine;
using UnityEngine.UI;
@@ -20,7 +21,7 @@ namespace Coffee.UIParticleInternal
static UIExtraCallbacks()
{
Canvas.willRenderCanvases += OnBeforeCanvasRebuild;
Logging.LogMulticast(typeof(Canvas), "willRenderCanvases", message: "ctor");
Logger.LogMulticast(typeof(Canvas), "willRenderCanvases", message: "ctor");
}
/// <summary>
@@ -67,9 +68,17 @@ namespace Coffee.UIParticleInternal
if (s_IsInitializedAfterCanvasRebuild) return;
s_IsInitializedAfterCanvasRebuild = true;
// Explicitly set `Canvas.willRenderCanvases += CanvasUpdateRegistry.PerformUpdate`.
CanvasUpdateRegistry.IsRebuildingLayout();
#if TMP_ENABLE
// Explicitly set `Canvas.willRenderCanvases += TMP_UpdateManager.DoRebuilds`.
typeof(TMPro.TMP_UpdateManager)
.GetProperty("instance", BindingFlags.NonPublic | BindingFlags.Static)
.GetValue(null);
#endif
Canvas.willRenderCanvases -= OnAfterCanvasRebuild;
Canvas.willRenderCanvases += OnAfterCanvasRebuild;
Logging.LogMulticast(typeof(Canvas), "willRenderCanvases",
Logger.LogMulticast(typeof(Canvas), "willRenderCanvases",
message: "InitializeAfterCanvasRebuild");
}

View File

@@ -386,6 +386,7 @@ namespace Coffee.UIExtensions
_isScaleStored = false;
UIParticleUpdater.Unregister(this);
_renderers.RemoveAll(r => r == null);
_renderers.ForEach(r => r.Reset());
_canvas = null;
}

View File

@@ -30,6 +30,7 @@ namespace Coffee.UIExtensions
private int _index;
private bool _isPrevStored;
private bool _isTrail;
private bool _meshCleared;
private Bounds _lastBounds;
private Material _materialForRendering;
private Material _modifiedMaterial;
@@ -205,9 +206,9 @@ namespace Coffee.UIExtensions
}
var hash = new Hash128(
modifiedMaterial ? (uint)modifiedMaterial.GetInstanceID() : 0,
texture ? (uint)texture.GetInstanceID() : 0,
0 < _parent.m_AnimatableProperties.Length ? (uint)GetInstanceID() : 0,
modifiedMaterial ? (uint)modifiedMaterial.GetHashCode() : 0,
texture ? (uint)texture.GetHashCode() : 0,
0 < _parent.m_AnimatableProperties.Length ? (uint)GetHashCode() : 0,
#if UNITY_EDITOR
(uint)EditorJsonUtility.ToJson(modifiedMaterial).GetHashCode()
#else
@@ -285,10 +286,14 @@ namespace Coffee.UIExtensions
|| (_isTrail && !_particleSystem.trails.enabled) // Trail, but it is not enabled.
)
{
// Skip clearing the mesh if it's already cleared.
if (_meshCleared) return;
Profiler.BeginSample("[UIParticleRenderer] Clear Mesh");
workerMesh.Clear();
canvasRenderer.SetMesh(workerMesh);
_lastBounds = new Bounds();
_meshCleared = true;
Profiler.EndSample();
return;
@@ -312,6 +317,7 @@ namespace Coffee.UIExtensions
// customData.SetVector(ParticleSystemCustomData.Custom2, 3, 0);
// }
_meshCleared = false;
var main = _particleSystem.main;
var scale = GetWorldScale();
var psPos = _particleSystem.transform.position;

View File

@@ -92,7 +92,7 @@ namespace Coffee.UIParticleInternal
if (sortByMaterial)
{
return aMat.GetInstanceID() - bMat.GetInstanceID();
return aMat.GetHashCode() - bMat.GetHashCode();
}
if (aMat.renderQueue != bMat.renderQueue)
@@ -131,7 +131,7 @@ namespace Coffee.UIParticleInternal
{
for (var i = 0; i < list.Count; i++)
{
if (list[i].GetInstanceID() == ps.GetInstanceID())
if (list[i].GetHashCode() == ps.GetHashCode())
{
return i;
}

View File

@@ -2,7 +2,7 @@
"name": "com.coffee.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.",
"version": "5.0.0-preview.16",
"version": "5.0.0-preview.17",
"unity": "2019.3",
"license": "MIT",
"repository": {