You've already forked ParticleEffectForUGUI
mirror of
https://github.com/mob-sakai/ParticleEffectForUGUI.git
synced 2026-05-16 13:10:07 +00:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a499f0c046 | ||
|
|
447c83dbbc | ||
|
|
bdeeabbbe1 | ||
|
|
5e6da2e158 | ||
|
|
f60d6dfe60 | ||
|
|
c795d24003 | ||
|
|
9e2dbe7758 |
21
CHANGELOG.md
21
CHANGELOG.md
@@ -1,3 +1,24 @@
|
|||||||
|
## [4.1.7](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/4.1.6...4.1.7) (2022-08-30)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* the annoying empty black scene overlay box shown even when nothing is selected ([bdeeabb](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/bdeeabbbe140b0ba80fac7ac477874c2467d3a16))
|
||||||
|
|
||||||
|
## [4.1.6](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/4.1.5...4.1.6) (2022-08-10)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* fix abnormal mesh bounds error ([f60d6df](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/f60d6dfe6030ac89527a4265e414e9a0a20d56db)), closes [#213](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/213) [#218](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/218)
|
||||||
|
|
||||||
|
## [4.1.5](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/4.1.4...4.1.5) (2022-08-10)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* fix culling for RectMask2D ([9e2dbe7](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/9e2dbe7758eb28a4f6a7c11113d9169847880f96)), closes [#220](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/220)
|
||||||
|
|
||||||
## [4.1.4](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/4.1.3...4.1.4) (2022-07-01)
|
## [4.1.4](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/4.1.3...4.1.4) (2022-07-01)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
96
README.md
96
README.md
@@ -195,9 +195,10 @@ NOTE: Press `Refresh` button to reconstruct rendering order based on children Pa
|
|||||||
|
|
||||||
<br><br>
|
<br><br>
|
||||||
|
|
||||||
### With `Mask` or `MaskRect2D` component
|
### With `Mask` or `RectMask2D` component
|
||||||
|
|
||||||
If you want to mask particles, set a stencil supported shader (such as `UI/UIAdditive`) to material for ParticleSystem.
|
If you want to mask particles, set a stencil supported shader (such as `UI/UIAdditive`) to material for ParticleSystem.
|
||||||
|
If you use some custom shaders, see [How to make a custom shader to support Mask/RectMask2D component](#how-to-make-a-custom-shader-to-support-maskrectmask2d-component) section.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
@@ -263,6 +264,99 @@ When improving performance, keep the following in mind:
|
|||||||
- If you are using multiple materials, you will have more draw calls.
|
- If you are using multiple materials, you will have more draw calls.
|
||||||
- Consider single material, atlasing the sprites, and using `Sprite` mode in the `Texture Sheet Animation` module in ParticleSystem.
|
- Consider single material, atlasing the sprites, and using `Sprite` mode in the `Texture Sheet Animation` module in ParticleSystem.
|
||||||
|
|
||||||
|
### How to make a custom shader to support Mask/RectMask2D component
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>Shader tips</summary>
|
||||||
|
|
||||||
|
```ShaderLab
|
||||||
|
Shader "Your/Custom/Shader"
|
||||||
|
{
|
||||||
|
Properties
|
||||||
|
{
|
||||||
|
// ...
|
||||||
|
// #### required for Mask ####
|
||||||
|
_StencilComp ("Stencil Comparison", Float) = 8
|
||||||
|
_Stencil ("Stencil ID", Float) = 0
|
||||||
|
_StencilOp ("Stencil Operation", Float) = 0
|
||||||
|
_StencilWriteMask ("Stencil Write Mask", Float) = 255
|
||||||
|
_StencilReadMask ("Stencil Read Mask", Float) = 255
|
||||||
|
_ColorMask ("Color Mask", Float) = 15
|
||||||
|
[Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
SubShader
|
||||||
|
{
|
||||||
|
Tags
|
||||||
|
{
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
|
||||||
|
// #### required for Mask ####
|
||||||
|
Stencil
|
||||||
|
{
|
||||||
|
Ref [_Stencil]
|
||||||
|
Comp [_StencilComp]
|
||||||
|
Pass [_StencilOp]
|
||||||
|
ReadMask [_StencilReadMask]
|
||||||
|
WriteMask [_StencilWriteMask]
|
||||||
|
}
|
||||||
|
ColorMask [_ColorMask]
|
||||||
|
// ...
|
||||||
|
|
||||||
|
Pass
|
||||||
|
{
|
||||||
|
// ...
|
||||||
|
// #### required for RectMask2D ####
|
||||||
|
#include "UnityUI.cginc"
|
||||||
|
#pragma multi_compile __ UNITY_UI_CLIP_RECT
|
||||||
|
float4 _ClipRect;
|
||||||
|
|
||||||
|
// #### required for Mask ####
|
||||||
|
#pragma multi_compile __ UNITY_UI_ALPHACLIP
|
||||||
|
|
||||||
|
struct appdata_t
|
||||||
|
{
|
||||||
|
// ...
|
||||||
|
};
|
||||||
|
|
||||||
|
struct v2f
|
||||||
|
{
|
||||||
|
// ...
|
||||||
|
// #### required for RectMask2D ####
|
||||||
|
float4 worldPosition : TEXCOORD1;
|
||||||
|
};
|
||||||
|
|
||||||
|
v2f vert(appdata_t v)
|
||||||
|
{
|
||||||
|
v2f OUT;
|
||||||
|
// ...
|
||||||
|
// #### required for RectMask2D ####
|
||||||
|
OUT.worldPosition = v.vertex;
|
||||||
|
return OUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
fixed4 frag(v2f IN) : SV_Target
|
||||||
|
{
|
||||||
|
// ...
|
||||||
|
// #### required for RectMask2D ####
|
||||||
|
#ifdef UNITY_UI_CLIP_RECT
|
||||||
|
color.a *= UnityGet2DClipping(IN.worldPosition.xy, _ClipRect);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// #### required for Mask ####
|
||||||
|
#ifdef UNITY_UI_ALPHACLIP
|
||||||
|
clip (color.a - 0.001);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
ENDCG
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
</details>
|
||||||
|
|
||||||
|
|
||||||
<br><br><br><br>
|
<br><br><br><br>
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ namespace Coffee.UIExtensions
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if UNITY_2019_1_OR_NEWER
|
#if UNITY_2019_1_OR_NEWER
|
||||||
SceneView.duringSceneGui += _ => miSceneViewOverlayWindow.Invoke(null, sceneViewArgs);
|
SceneView.duringSceneGui += _ => { if (s_SerializedObject != null) miSceneViewOverlayWindow.Invoke(null, sceneViewArgs); };
|
||||||
#else
|
#else
|
||||||
SceneView.onSceneGUIDelegate += _ =>
|
SceneView.onSceneGUIDelegate += _ =>
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -14,15 +14,14 @@ namespace Coffee.UIExtensions
|
|||||||
internal class UIParticleRenderer : MaskableGraphic
|
internal class UIParticleRenderer : MaskableGraphic
|
||||||
{
|
{
|
||||||
private static readonly CombineInstance[] s_CombineInstances = new CombineInstance[] { new CombineInstance() };
|
private static readonly CombineInstance[] s_CombineInstances = new CombineInstance[] { new CombineInstance() };
|
||||||
//private static ParticleSystem.Particle[] s_Particles = new ParticleSystem.Particle[2048];
|
|
||||||
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>();
|
private static readonly List<UIParticleRenderer> s_Renderers = new List<UIParticleRenderer>();
|
||||||
|
private static readonly Vector3[] s_Corners = new Vector3[4];
|
||||||
|
|
||||||
private ParticleSystemRenderer _renderer;
|
private ParticleSystemRenderer _renderer;
|
||||||
private ParticleSystem _particleSystem;
|
private ParticleSystem _particleSystem;
|
||||||
internal int _prevParticleCount = 0;
|
private int _prevParticleCount = 0;
|
||||||
//private ParticleSystem _emitter;
|
|
||||||
private UIParticle _parent;
|
private UIParticle _parent;
|
||||||
private int _index;
|
private int _index;
|
||||||
private bool _isTrail;
|
private bool _isTrail;
|
||||||
@@ -33,6 +32,7 @@ namespace Coffee.UIExtensions
|
|||||||
private bool _delay = false;
|
private bool _delay = false;
|
||||||
private bool _prewarm = false;
|
private bool _prewarm = false;
|
||||||
private Material _currentMaterialForRendering;
|
private Material _currentMaterialForRendering;
|
||||||
|
private Bounds _lastBounds;
|
||||||
|
|
||||||
public override Texture mainTexture
|
public override Texture mainTexture
|
||||||
{
|
{
|
||||||
@@ -50,6 +50,37 @@ namespace Coffee.UIExtensions
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Rect rootCanvasRect
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
s_Corners[0] = transform.TransformPoint(_lastBounds.min.x, _lastBounds.min.y, 0);
|
||||||
|
s_Corners[1] = transform.TransformPoint(_lastBounds.min.x, _lastBounds.max.y, 0);
|
||||||
|
s_Corners[2] = transform.TransformPoint(_lastBounds.max.x, _lastBounds.max.y, 0);
|
||||||
|
s_Corners[3] = transform.TransformPoint(_lastBounds.max.x, _lastBounds.min.y, 0);
|
||||||
|
if (canvas)
|
||||||
|
{
|
||||||
|
var worldToLocalMatrix = canvas.rootCanvas.transform.worldToLocalMatrix;
|
||||||
|
for (var i = 0; i < 4; ++i)
|
||||||
|
s_Corners[i] = worldToLocalMatrix.MultiplyPoint(s_Corners[i]);
|
||||||
|
}
|
||||||
|
var corner1 = (Vector2) s_Corners[0];
|
||||||
|
var corner2 = (Vector2) s_Corners[0];
|
||||||
|
for (var i = 1; i < 4; ++i)
|
||||||
|
{
|
||||||
|
if (s_Corners[i].x < corner1.x)
|
||||||
|
corner1.x = s_Corners[i].x;
|
||||||
|
else if (s_Corners[i].x > corner2.x)
|
||||||
|
corner2.x = s_Corners[i].x;
|
||||||
|
if (s_Corners[i].y < corner1.y)
|
||||||
|
corner1.y = s_Corners[i].y;
|
||||||
|
else if (s_Corners[i].y > corner2.y)
|
||||||
|
corner2.y = s_Corners[i].y;
|
||||||
|
}
|
||||||
|
return new Rect(corner1, corner2 - corner1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static UIParticleRenderer AddRenderer(UIParticle parent, int index)
|
public static UIParticleRenderer AddRenderer(UIParticle parent, int index)
|
||||||
{
|
{
|
||||||
// Create renderer object.
|
// Create renderer object.
|
||||||
@@ -123,6 +154,7 @@ namespace Coffee.UIExtensions
|
|||||||
material = null;
|
material = null;
|
||||||
workerMesh.Clear();
|
workerMesh.Clear();
|
||||||
canvasRenderer.SetMesh(workerMesh);
|
canvasRenderer.SetMesh(workerMesh);
|
||||||
|
_lastBounds = new Bounds();
|
||||||
enabled = false;
|
enabled = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -188,6 +220,7 @@ namespace Coffee.UIExtensions
|
|||||||
Profiler.BeginSample("[UIParticleRenderer] Clear Mesh");
|
Profiler.BeginSample("[UIParticleRenderer] Clear Mesh");
|
||||||
workerMesh.Clear();
|
workerMesh.Clear();
|
||||||
canvasRenderer.SetMesh(workerMesh);
|
canvasRenderer.SetMesh(workerMesh);
|
||||||
|
_lastBounds = new Bounds();
|
||||||
Profiler.EndSample();
|
Profiler.EndSample();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@@ -241,7 +274,7 @@ namespace Coffee.UIExtensions
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
s_CombineInstances[0].mesh.Clear();
|
s_CombineInstances[0].mesh.Clear(false);
|
||||||
}
|
}
|
||||||
Profiler.EndSample();
|
Profiler.EndSample();
|
||||||
|
|
||||||
@@ -269,6 +302,7 @@ namespace Coffee.UIExtensions
|
|||||||
extents.z = 0;
|
extents.z = 0;
|
||||||
bounds.extents = extents;
|
bounds.extents = extents;
|
||||||
workerMesh.bounds = bounds;
|
workerMesh.bounds = bounds;
|
||||||
|
_lastBounds = bounds;
|
||||||
}
|
}
|
||||||
Profiler.EndSample();
|
Profiler.EndSample();
|
||||||
|
|
||||||
@@ -286,6 +320,7 @@ namespace Coffee.UIExtensions
|
|||||||
{
|
{
|
||||||
if (s_Renderers[i] == this) continue;
|
if (s_Renderers[i] == this) continue;
|
||||||
s_Renderers[i].canvasRenderer.SetMesh(workerMesh);
|
s_Renderers[i].canvasRenderer.SetMesh(workerMesh);
|
||||||
|
s_Renderers[i]._lastBounds = _lastBounds;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_parent.canRender)
|
if (!_parent.canRender)
|
||||||
@@ -354,6 +389,17 @@ namespace Coffee.UIExtensions
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void Cull(Rect clipRect, bool validRect)
|
||||||
|
{
|
||||||
|
var cull = _lastBounds.extents == Vector3.zero || !validRect || !clipRect.Overlaps(rootCanvasRect, true);
|
||||||
|
if (canvasRenderer.cull == cull) return;
|
||||||
|
|
||||||
|
canvasRenderer.cull = cull;
|
||||||
|
UISystemProfilerApi.AddMarker("MaskableGraphic.cullingChanged", this);
|
||||||
|
onCullStateChanged.Invoke(cull);
|
||||||
|
OnCullingChanged();
|
||||||
|
}
|
||||||
|
|
||||||
private Vector3 GetWorldScale()
|
private Vector3 GetWorldScale()
|
||||||
{
|
{
|
||||||
Profiler.BeginSample("[UIParticleRenderer] GetWorldScale");
|
Profiler.BeginSample("[UIParticleRenderer] GetWorldScale");
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
"name": "com.coffee.ui-particle",
|
"name": "com.coffee.ui-particle",
|
||||||
"displayName": "UI Particle",
|
"displayName": "UI Particle",
|
||||||
"description": "This plugin provide a component to render particle effect for uGUI.\nThe particle rendering is maskable and sortable, without Camera, RenderTexture or Canvas.",
|
"description": "This plugin provide a component to render particle effect for uGUI.\nThe particle rendering is maskable and sortable, without Camera, RenderTexture or Canvas.",
|
||||||
"version": "4.1.4",
|
"version": "4.1.7",
|
||||||
"unity": "2018.2",
|
"unity": "2018.2",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
|||||||
Reference in New Issue
Block a user