Compare commits

..

3 Commits
4.13.0 ... main

Author SHA1 Message Date
semantic-release-bot
16ab8d7bb8 chore(release): 4.13.1 [skip ci]
## [4.13.1](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.13.0...v4.13.1) (2026-06-26)

### Bug Fixes

* `ParticleSystemPreviewer` is no longer included in build ([bad976c](bad976cf01))
* add support for Unity 6.7 ([26fd3da](26fd3da20b)), closes [#408](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/408)
2026-06-26 02:57:47 +00:00
mob-sakai
2350ea82d2 fix: ParticleSystemPreviewer is no longer included in build 2026-06-26 11:55:28 +09:00
mob-sakai
a7f64c6033 fix: add support for Unity 6.7
close #408
2026-06-26 11:51:43 +09:00
7 changed files with 203 additions and 19 deletions

View File

@@ -1,3 +1,11 @@
## [4.13.1](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.13.0...v4.13.1) (2026-06-26)
### Bug Fixes
* `ParticleSystemPreviewer` is no longer included in build ([bad976c](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/bad976cf01180bdabf5cd2f1760e069afdcb644a))
* add support for Unity 6.7 ([26fd3da](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/26fd3da20b6b07f7a26df662358c53757a7cc5f5)), closes [#408](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/408)
# [4.13.0](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.12.2...v4.13.0) (2026-06-25) # [4.13.0](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.12.2...v4.13.0) (2026-06-25)

View File

@@ -34,6 +34,7 @@ You can render, mask, and sort your `ParticleSystems` for UI without the need fo
- [Usage with `Mask` or `RectMask2D` Component](#usage-with-mask-or-rectmask2d-component) - [Usage with `Mask` or `RectMask2D` Component](#usage-with-mask-or-rectmask2d-component)
- [Usage with Script](#usage-with-script) - [Usage with Script](#usage-with-script)
- [Component: UIParticleAttractor](#component-uiparticleattractor) - [Component: UIParticleAttractor](#component-uiparticleattractor)
- [Component: ParticleSystemPreviewer](#component-particlesystempreviewer)
- [Project Settings](#project-settings) - [Project Settings](#project-settings)
- [🛠 Development Note](#-development-note) - [🛠 Development Note](#-development-note)
- [Compares the Baking mesh approach with the conventional approach](#compares-the-baking-mesh-approach-with-the-conventional-approach) - [Compares the Baking mesh approach with the conventional approach](#compares-the-baking-mesh-approach-with-the-conventional-approach)
@@ -116,7 +117,7 @@ _This package requires **Unity 2018.3 or later**._
``` ```
- To update the package, use Package Manager UI (`Window > Package Manager`) or run the following command with `@{version}`: - 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.9.0 openupm add com.coffee.ui-particle@4.13.0
``` ```
#### Install via UPM (with Package Manager UI) #### Install via UPM (with Package Manager UI)
@@ -125,7 +126,7 @@ _This package requires **Unity 2018.3 or later**._
- Click `+ > Add package from git URL...` and input the repository URL: `https://github.com/mob-sakai/ParticleEffectForUGUI.git` - Click `+ > Add package from git URL...` and input the repository URL: `https://github.com/mob-sakai/ParticleEffectForUGUI.git`
![](https://github.com/user-attachments/assets/f88f47ad-c606-44bd-9e86-ee3f72eac548) ![](https://github.com/user-attachments/assets/f88f47ad-c606-44bd-9e86-ee3f72eac548)
- To update the package, change suffix `#{version}` to the target version. - To update the package, change suffix `#{version}` to the target version.
- e.g. `https://github.com/mob-sakai/ParticleEffectForUGUI.git#4.9.0` - e.g. `https://github.com/mob-sakai/ParticleEffectForUGUI.git#4.13.0`
#### Install via UPM (Manually) #### Install via UPM (Manually)
@@ -140,7 +141,7 @@ _This package requires **Unity 2018.3 or later**._
``` ```
- 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.9.0",` - e.g. `"com.coffee.ui-particle": "https://github.com/mob-sakai/ParticleEffectForUGUI.git#4.13.0",`
#### Install as Embedded Package #### Install as Embedded Package
@@ -271,16 +272,17 @@ uiParticle.Stop();
- **Unscaled Time:** Update with unscaled delta time. - **Unscaled Time:** Update with unscaled delta time.
- **OnAttracted**: An event called when attracting is complete (per particle). - **OnAttracted**: An event called when attracting is complete (per particle).
<br><br> <br><br>
### Component: ParticleSystemPreviewer ### Component: ParticleSystemPreviewer
`ParticleSystemPreviewer` is used to preview a ParticleSystem in the editor. `ParticleSystemPreviewer` is used to preview a `ParticleSystem` in the editor.
![](https://github.com/mob-sakai/mob-sakai/releases/download/docs/1782441157549.png)
- When a `GameObject` with this component is selected in the editor, a temporary `ParticleSystem` is added if needed so you can preview the effect in the Scene view. - When a `GameObject` with this component is selected in the editor, a temporary `ParticleSystem` is added if needed so you can preview the effect in the Scene view.
- The generated `ParticleSystem` is marked with `HideFlags.DontSave`, so it is neither saved nor included in builds. - The generated `ParticleSystem` is marked with `HideFlags.DontSave`, so it is neither saved nor included in builds.
- This component will be removed in builds.
<br><br> <br><br>

View File

@@ -0,0 +1,153 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
namespace Coffee.UIParticleInternal
{
internal static class MeshExtensions
{
internal static readonly InternalObjectPool<Mesh> s_MeshPool = new InternalObjectPool<Mesh>(
() =>
{
var mesh = new Mesh
{
hideFlags = HideFlags.DontSave | HideFlags.NotEditable
};
mesh.MarkDynamic();
return mesh;
},
mesh => mesh,
mesh =>
{
if (mesh != null)
{
mesh.Clear();
}
});
public static Mesh Rent()
{
return s_MeshPool.Rent();
}
public static void Return(ref Mesh mesh)
{
s_MeshPool.Return(ref mesh);
}
public static void CopyTo(this Mesh self, Mesh dst)
{
if (self == null || dst == null) return;
var vector3List = InternalListPool<Vector3>.Rent();
var vector4List = InternalListPool<Vector4>.Rent();
var color32List = InternalListPool<Color32>.Rent();
var intList = InternalListPool<int>.Rent();
dst.Clear(false);
self.GetVertices(vector3List);
dst.SetVertices(vector3List);
self.GetTriangles(intList, 0);
dst.SetTriangles(intList, 0);
self.GetNormals(vector3List);
dst.SetNormals(vector3List);
self.GetTangents(vector4List);
dst.SetTangents(vector4List);
self.GetColors(color32List);
dst.SetColors(color32List);
self.GetUVs(0, vector4List);
dst.SetUVs(0, vector4List);
self.GetUVs(1, vector4List);
dst.SetUVs(1, vector4List);
self.GetUVs(2, vector4List);
dst.SetUVs(2, vector4List);
self.GetUVs(3, vector4List);
dst.SetUVs(3, vector4List);
dst.RecalculateBounds();
InternalListPool<Vector3>.Return(ref vector3List);
InternalListPool<Vector4>.Return(ref vector4List);
InternalListPool<Color32>.Return(ref color32List);
InternalListPool<int>.Return(ref intList);
}
public static void CopyTo(this VertexHelper self, Mesh dst)
{
if (self == null || dst == null) return;
self.FillMesh(dst);
}
public static void CopyTo(this Mesh self, VertexHelper dst)
{
if (self == null || dst == null) return;
var vertexCount = self.vertexCount;
var indexCount = self.triangles.Length;
self.CopyTo(dst, vertexCount, indexCount);
}
public static void CopyTo(this Mesh self, VertexHelper dst, int vertexCount, int indexCount)
{
if (self == null || dst == null) return;
var positions = InternalListPool<Vector3>.Rent();
var normals = InternalListPool<Vector3>.Rent();
var uv0 = InternalListPool<Vector4>.Rent();
var uv1 = InternalListPool<Vector4>.Rent();
var uv2 = InternalListPool<Vector4>.Rent();
var uv3 = InternalListPool<Vector4>.Rent();
var tangents = InternalListPool<Vector4>.Rent();
var colors = InternalListPool<Color32>.Rent();
var indices = InternalListPool<int>.Rent();
self.GetVertices(positions);
self.GetColors(colors);
self.GetUVs(0, uv0);
self.GetUVs(1, uv1);
self.GetUVs(2, uv1);
self.GetUVs(3, uv1);
self.GetNormals(normals);
self.GetTangents(tangents);
self.GetIndices(indices, 0);
dst.Clear();
for (var i = 0; i < vertexCount; i++)
{
dst.AddVert(positions.GetOrDefault(i), colors.GetOrDefault(i), uv0.GetOrDefault(i), uv1.GetOrDefault(i),
uv2.GetOrDefault(i), uv3.GetOrDefault(i), normals.GetOrDefault(i), tangents.GetOrDefault(i));
}
var count = Mathf.Clamp(indexCount, 0, indices.Count);
for (var i = 0; i < count - 2; i += 3)
{
dst.AddTriangle(indices[i], indices[i + 1], indices[i + 2]);
}
InternalListPool<Vector3>.Return(ref positions);
InternalListPool<Vector3>.Return(ref normals);
InternalListPool<Vector4>.Return(ref uv0);
InternalListPool<Vector4>.Return(ref uv1);
InternalListPool<Vector4>.Return(ref uv2);
InternalListPool<Vector4>.Return(ref uv3);
InternalListPool<Vector4>.Return(ref tangents);
InternalListPool<Color32>.Return(ref colors);
InternalListPool<int>.Return(ref indices);
}
private static T GetOrDefault<T>(this List<T> self, int index)
{
return 0 <= index && index < self.Count
? self[index]
: default;
}
}
}

View File

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

View File

@@ -1,3 +1,4 @@
#if UNITY_EDITOR
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using Coffee.UIParticleInternal; using Coffee.UIParticleInternal;
@@ -13,7 +14,6 @@ namespace Coffee.UIExtensions
// Do nothing. // Do nothing.
} }
#if UNITY_EDITOR
[CustomEditor(typeof(ParticleSystemPreviewer))] [CustomEditor(typeof(ParticleSystemPreviewer))]
[CanEditMultipleObjects] [CanEditMultipleObjects]
internal class ParticleSystemPreviewerEditor : Editor internal class ParticleSystemPreviewerEditor : Editor
@@ -29,6 +29,7 @@ namespace Coffee.UIExtensions
public override void OnInspectorGUI() public override void OnInspectorGUI()
{ {
base.OnInspectorGUI(); base.OnInspectorGUI();
EditorGUILayout.HelpBox("ParticleSystemPreviewer will be removed in build.", MessageType.Warning);
ParticleSystemPreviewSystem.DrawWarningForTemporary(_gameObjects); ParticleSystemPreviewSystem.DrawWarningForTemporary(_gameObjects);
ParticleSystemPreviewSystem.DrawWarningForPermanent(_gameObjects); ParticleSystemPreviewSystem.DrawWarningForPermanent(_gameObjects);
} }
@@ -43,6 +44,12 @@ namespace Coffee.UIExtensions
{ {
private const HideFlags k_TemporaryHideFlags = HideFlags.DontSave | HideFlags.NotEditable; private const HideFlags k_TemporaryHideFlags = HideFlags.DontSave | HideFlags.NotEditable;
private const string k_TemporaryMesssage = "The temporary ParticleSystem for preview is attached.\n" +
"It will be removed when exiting edit mode.";
private const string k_PermanentMesssage = "The permanent ParticleSystem is attached.\n" +
"It will be included in build.";
[SerializeField] [SerializeField]
private List<GameObject> m_PreviewObjects = new List<GameObject>(); private List<GameObject> m_PreviewObjects = new List<GameObject>();
@@ -192,8 +199,7 @@ namespace Coffee.UIExtensions
{ {
if (gameObjects == null || gameObjects.Length == 0 || !gameObjects.Any(HasTemporaryParticleSystem)) return; if (gameObjects == null || gameObjects.Length == 0 || !gameObjects.Any(HasTemporaryParticleSystem)) return;
if (WarningButton("The temporary ParticleSystem for preview is attached.\n" + if (HelpBoxButton(MessageType.Warning, k_TemporaryMesssage, "Remove"))
"It will be removed when exiting edit mode.", "Remove"))
{ {
foreach (var go in gameObjects) foreach (var go in gameObjects)
{ {
@@ -209,8 +215,7 @@ namespace Coffee.UIExtensions
{ {
if (gameObjects == null || gameObjects.Length == 0 || !gameObjects.Any(HasPermanentParticleSystem)) return; if (gameObjects == null || gameObjects.Length == 0 || !gameObjects.Any(HasPermanentParticleSystem)) return;
if (WarningButton("The permanent ParticleSystem is attached.\n" + if (HelpBoxButton(MessageType.Info, k_PermanentMesssage, "Remove"))
"It will be included in build.", "Remove"))
{ {
foreach (var go in gameObjects) foreach (var go in gameObjects)
{ {
@@ -224,14 +229,14 @@ namespace Coffee.UIExtensions
} }
} }
private static bool WarningButton(string message, string buttonText) private static bool HelpBoxButton(MessageType messageType, string message, string buttonText)
{ {
EditorGUILayout.BeginHorizontal(); EditorGUILayout.BeginHorizontal();
EditorGUILayout.HelpBox(message, MessageType.Warning, true); EditorGUILayout.HelpBox(message, messageType, true);
var clicked = GUILayout.Button(EditorGUIUtility.TrTempContent(buttonText)); var clicked = GUILayout.Button(EditorGUIUtility.TrTempContent(buttonText));
EditorGUILayout.EndHorizontal(); EditorGUILayout.EndHorizontal();
return clicked; return clicked;
} }
} }
#endif
} }
#endif

View File

@@ -26,6 +26,7 @@ namespace Coffee.UIExtensions
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 Vector3[] s_Corners = new Vector3[4]; private static readonly Vector3[] s_Corners = new Vector3[4];
private static readonly VertexHelper s_VertexHelper = new VertexHelper();
private bool _delay; private bool _delay;
private int _index; private int _index;
private bool _isPrevStored; private bool _isPrevStored;
@@ -451,11 +452,15 @@ namespace Coffee.UIExtensions
var components = InternalListPool<Component>.Rent(); var components = InternalListPool<Component>.Rent();
GetComponents(typeof(IMeshModifier), components); GetComponents(typeof(IMeshModifier), components);
if (0 < components.Count)
{
workerMesh.CopyTo(s_VertexHelper);
for (var i = 0; i < components.Count; i++) for (var i = 0; i < components.Count; i++)
{ {
#pragma warning disable CS0618 // Type or member is obsolete ((IMeshModifier)components[i]).ModifyMesh(s_VertexHelper);
((IMeshModifier)components[i]).ModifyMesh(workerMesh); }
#pragma warning restore CS0618 // Type or member is obsolete
s_VertexHelper.FillMesh(workerMesh);
} }
InternalListPool<Component>.Return(ref components); InternalListPool<Component>.Return(ref components);

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": "4.13.0", "version": "4.13.1",
"unity": "2018.2", "unity": "2018.2",
"license": "MIT", "license": "MIT",
"repository": { "repository": {