Compare commits

..

27 Commits

Author SHA1 Message Date
semantic-release-bot
c795d24003 chore(release): 4.1.5 [skip ci]
## [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](9e2dbe7758)), closes [#220](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/220)
2022-08-10 01:44:58 +00:00
takashi.sakai
9e2dbe7758 fix: fix culling for RectMask2D
close #220
2022-08-10 10:31:50 +09:00
semantic-release-bot
4edcef1bbf chore(release): 4.1.4 [skip ci]
## [4.1.4](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/4.1.3...4.1.4) (2022-07-01)

### Bug Fixes

* add `Enabled` toggle in overlay window ([f97e619](f97e6195e6))
* if `m_Particles` contains null, an error will occur ([550d0c4](550d0c43be)), closes [#214](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/214)
* ParticleSystem reordering and refreshing in inspector does not work for prefab asset ([7eb4112](7eb41124db))
* refresh button does not works in prefab edit mode ([c1538a8](c1538a8399)), closes [#214](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/214)
* when `UIParticlrRenderer` destroy manually, an error will occur ([a11d2d0](a11d2d01ce))
2022-07-01 07:49:12 +00:00
mob-sakai
a11d2d01ce fix: when UIParticlrRenderer destroy manually, an error will occur 2022-07-01 16:10:10 +09:00
mob-sakai
550d0c43be fix: if m_Particles contains null, an error will occur
close #214
2022-07-01 16:10:10 +09:00
mob-sakai
c1538a8399 fix: refresh button does not works in prefab edit mode
close #214
2022-07-01 16:10:10 +09:00
mob-sakai
f97e6195e6 fix: add Enabled toggle in overlay window 2022-07-01 16:10:10 +09:00
mob-sakai
7eb41124db fix: ParticleSystem reordering and refreshing in inspector does not work for prefab asset 2022-07-01 16:10:09 +09:00
semantic-release-bot
65c60000c2 chore(release): 4.1.3 [skip ci]
## [4.1.3](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/4.1.2...4.1.3) (2022-06-28)

### Bug Fixes

* error on drag prefab to scene ([fa2f867](fa2f867bca)), closes [#211](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/211)
2022-06-28 08:07:32 +00:00
mob-sakai
fa2f867bca fix: error on drag prefab to scene
close #211
2022-06-28 14:26:09 +09:00
semantic-release-bot
b2b2b0f767 chore(release): 4.1.2 [skip ci]
## [4.1.2](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/4.1.1...4.1.2) (2022-06-27)

### Bug Fixes

* error on editor ([8034228](8034228713)), closes [#210](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/210)
* incorrect position of world space trail particles ([fb7f308](fb7f308f09)), closes [#209](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/209)
2022-06-27 16:08:02 +00:00
mob-sakai
fb7f308f09 fix: incorrect position of world space trail particles
close #209
2022-06-28 00:20:37 +09:00
mob-sakai
8034228713 fix: error on editor
close #210
2022-06-28 00:18:59 +09:00
semantic-release-bot
f526671826 chore(release): 4.1.1 [skip ci]
## [4.1.1](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/4.1.0...4.1.1) (2022-06-25)

### Bug Fixes

* add absolute mode toggle to overlay window ([48d1994](48d1994f5f))
2022-06-25 06:57:43 +00:00
mob-sakai
81dacb1efe docs: update readme (for absolute mode) 2022-06-25 13:22:09 +09:00
mob-sakai
48d1994f5f fix: add absolute mode toggle to overlay window 2022-06-25 13:22:09 +09:00
semantic-release-bot
f9901a0255 chore(release): 4.1.0 [skip ci]
# [4.1.0](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/4.0.1...4.1.0) (2022-06-25)

### Features

* add relative/absolute particle position mode ([1879ac8](1879ac8c53)), closes [#205](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/205)
2022-06-25 00:37:09 +00:00
mob-sakai
3b0f6985f6 demo: add relative/absolute position mode demo 2022-06-25 09:07:28 +09:00
mob-sakai
1879ac8c53 feat: add relative/absolute particle position mode
close #205
2022-06-25 09:07:28 +09:00
semantic-release-bot
e651039032 chore(release): 4.0.1 [skip ci]
## [4.0.1](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/4.0.0...4.0.1) (2022-06-24)

### Bug Fixes

* overlays do not exist in Unity 2019.2-2021.1 ([cd8e037](cd8e0372b6)), closes [#207](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/207) [#208](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/208)
2022-06-24 00:54:28 +00:00
mob-sakai
1d5c87463a docs: update license 2022-06-24 09:46:13 +09:00
mob-sakai
cd8e0372b6 fix: overlays do not exist in Unity 2019.2-2021.1
close #207, close #208
2022-06-24 09:30:51 +09:00
semantic-release-bot
e1715afbab chore(release): 4.0.0 [skip ci]
# [4.0.0](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/3.3.12...4.0.0) (2022-06-21)

### Bug Fixes

* correct world space particle position when changing screen size ([c6644a2](c6644a2132))
* keep properly canvas batches ([d8e96e6](d8e96e69a6))

### Features

* adaptive scaling for UI ([aa0d56f](aa0d56f9fa))
* add overlay window for UIParticle ([7b21c50](7b21c500ef))
* add particle attractor component ([386170c](386170cbf6))
* display warning in inspector if using 'TEXCOORD*.zw' components as custom vertex stream ([59221d5](59221d5821))
* mesh sharing group ([9afeebf](9afeebf672))
* random mesh sharing group ([4fa43ed](4fa43eda4b))
* support 8+ materials ([b76bf5a](b76bf5a5ad)), closes [#122](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/122) [#152](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/152) [#186](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/186)

### BREAKING CHANGES

* If you update to v4, you may be required to adjust your UIParticle.scale.
2022-06-21 12:12:02 +00:00
mob-sakai
2f51bff791 docs: update readme 2022-06-21 21:09:59 +09:00
mob-sakai
59221d5821 feat: display warning in inspector if using 'TEXCOORD*.zw' components as custom vertex stream 2022-06-21 19:52:22 +09:00
mob-sakai
4fe9a3200d fix on editor: on select UIParticle, particles will be cleared 2022-06-21 19:47:08 +09:00
mob-sakai
8c959b257c demo: update demo 2022-06-20 15:48:59 +09:00
12 changed files with 18619 additions and 598 deletions

View File

@@ -1,3 +1,81 @@
## [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)
### Bug Fixes
* add `Enabled` toggle in overlay window ([f97e619](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/f97e6195e62b5acfa8f3e97bfe3bc4a7dcadf38a))
* if `m_Particles` contains null, an error will occur ([550d0c4](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/550d0c43be35cd07e390ffd5749557c89fee0332)), closes [#214](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/214)
* ParticleSystem reordering and refreshing in inspector does not work for prefab asset ([7eb4112](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/7eb41124db06ea794db76788b35ce82a0af2c402))
* refresh button does not works in prefab edit mode ([c1538a8](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/c1538a83998608a30dc90944b05f8b75e165cf05)), closes [#214](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/214)
* when `UIParticlrRenderer` destroy manually, an error will occur ([a11d2d0](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/a11d2d01ce5f67e3f430bcb0bfdee1ad9abf7cfe))
## [4.1.3](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/4.1.2...4.1.3) (2022-06-28)
### Bug Fixes
* error on drag prefab to scene ([fa2f867](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/fa2f867bcaff437bb9420da1abcef970cdb09ade)), closes [#211](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/211)
## [4.1.2](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/4.1.1...4.1.2) (2022-06-27)
### Bug Fixes
* error on editor ([8034228](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/80342287137c07d58a7492875a401d80cb134073)), closes [#210](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/210)
* incorrect position of world space trail particles ([fb7f308](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/fb7f308f092db8a1512383857b80110cd626ecf9)), closes [#209](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/209)
## [4.1.1](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/4.1.0...4.1.1) (2022-06-25)
### Bug Fixes
* add absolute mode toggle to overlay window ([48d1994](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/48d1994f5f8751b707b6ef7695b552df731bece9))
# [4.1.0](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/4.0.1...4.1.0) (2022-06-25)
### Features
* add relative/absolute particle position mode ([1879ac8](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/1879ac8c538778e386e68cfc989a6f4f974043ca)), closes [#205](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/205)
## [4.0.1](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/4.0.0...4.0.1) (2022-06-24)
### Bug Fixes
* overlays do not exist in Unity 2019.2-2021.1 ([cd8e037](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/cd8e0372b63bb6feaaf053518013a641bc7e65ac)), closes [#207](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/207) [#208](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/208)
# [4.0.0](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/3.3.12...4.0.0) (2022-06-21)
### Bug Fixes
* correct world space particle position when changing screen size ([c6644a2](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/c6644a213263375c7a35b5082ef4b71cc58964e6))
* keep properly canvas batches ([d8e96e6](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/d8e96e69a62dff7a451eaed32c7a814e7e62dbb9))
### Features
* adaptive scaling for UI ([aa0d56f](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/aa0d56f9faa05e9679d4b476bcf135eafb1b8af9))
* add overlay window for UIParticle ([7b21c50](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/7b21c500ef78103b605fdca71051d2357b09602f))
* add particle attractor component ([386170c](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/386170cbf68ebf59d4510fe0a45cf83925ec9ba4))
* display warning in inspector if using 'TEXCOORD*.zw' components as custom vertex stream ([59221d5](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/59221d58217a440b77d504e6428bf99f10246260))
* mesh sharing group ([9afeebf](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/9afeebf67212cdf4d3ac9e9a3b78a7ced5c7ecfe))
* random mesh sharing group ([4fa43ed](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/4fa43eda4bc70c9c827c4fad9d5ae1327bfbc322))
* support 8+ materials ([b76bf5a](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/b76bf5a5ad378c3c4b16bcf08d21337757557101)), closes [#122](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/122) [#152](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/152) [#186](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/186)
### BREAKING CHANGES
* If you update to v4, you may be required to adjust your UIParticle.scale.
# [4.0.0-preview.1](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/3.3.12...4.0.0-preview.1) (2022-06-18)

View File

@@ -1,4 +1,4 @@
Copyright 2018 mob-sakai
Copyright 2018-2022 mob-sakai
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

View File

@@ -1,8 +1,6 @@
Particle Effect For UGUI (UI Particle)
===
**:warning: NOTE: Do not use [the obsolete tags and branches](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/108) to reference the package. They will be removed in near future. :warning:**
This plugin provide a component to render particle effect for uGUI in Unity 2018.2 or later.
The particle rendering is maskable and sortable, without Camera, RenderTexture or Canvas.
@@ -30,26 +28,35 @@ This plugin uses new APIs `MeshBake/MashTrailBake` (added with Unity 2018.2) to
You can mask and sort particles for uGUI without Camera, RenderTexture, Canvas.
Compares this "Baking mesh" approach with the conventional approach:
(This scene is included in the package.)
[Performance test results](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/193#issuecomment-1160028374)
|Approach|Good|Bad|Screenshot|
|-|-|-|-|
|Baking mesh<br>**\(UIParticle\)**|Rendered as is.<br>Maskable.<br>Sortable.<br>Less objects.|**Requires Unity 2018.2 or later.**<br>Requires UI shaders to use Mask.|<img src="https://user-images.githubusercontent.com/12690315/41765089-0302b9a2-763e-11e8-88b3-b6ffa306bbb0.gif" width="500px">|
|Baking mesh<br>**\(UIParticle\)**|Rendered as is.<br>Maskable.<br>Sortable.<br>Less objects.|[Not support `TEXCOORD*.zw` components for custom vertex stream](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/191#issuecomment-1043409186)|<img src="https://user-images.githubusercontent.com/12690315/41765089-0302b9a2-763e-11e8-88b3-b6ffa306bbb0.gif" width="500px">|
|Do nothing|Rendered as is.|**Looks like a glitch.**<br>Not maskable.<br>Not sortable.|<img src="https://user-images.githubusercontent.com/12690315/41765090-0329828a-763e-11e8-8d8a-f1d269ea3bc7.gif" width="500px">|
|Convert particle to UIVertex<br>[\(UIParticleSystem\)](https://forum.unity.com/threads/free-script-particle-systems-in-ui-screen-space-overlay.406862/)|Maskable.<br>Sortable.<br>Less objects.|**Adjustment is difficult.**<br>Requires UI shaders.<br>Difficult to adjust scale.<br>Force hierarchy scalling.<br>Simulation results are incorrect.<br>Trail, rotation of transform, time scaling are not supported.<br>Generate heavy GC every frame.|<img src="https://user-images.githubusercontent.com/12690315/41765088-02deb9c6-763e-11e8-98d0-9e0c1766ef39.gif" width="500px">|
|Use Canvas to sort|Rendered as is.<br>Sortable.|**You must to manage sorting orders.**<br>Not maskable.<br>More batches.|<img src="https://user-images.githubusercontent.com/12690315/41765087-02b866ea-763e-11e8-8c33-081c9ad852f8.gif" width="500px">|
|Use RenderTexture|Maskable.<br>Sortable.|**Requires Camera and RenderTexture.**<br>Difficult to adjust position and size.<br>Quality depends on the RenderTexture's setting.|<img src="https://user-images.githubusercontent.com/12690315/41765085-0291b3e2-763e-11e8-827b-72e5ee9bc556.gif" width="500px">|
|Approach|FPS on Editor|FPS on iPhone6|FPS on Xperia XZ|
|--|--|--|--|
|Particle System|43|57|22|
|UIParticleSystem|4|3|0 (unmeasurable)|
|Sorting By Canvas|43|44|18|
|UIParticle|17|12|4|
|UIParticle with MeshSharing|44|45|30|
<br><br>
#### Features
* Easy to use: the package is out-of-the-box
* Sort particle effects with UI
* Sort particle effects and UI by sibling index
* No Camera, RenderTexture or Canvas are required
* Masking with Mask or RectMask2D
* Masking by Mask or RectMask2D
* Support Trail module
* Change alpha with CanvasGroup
* No heavy allocation every frame
* Support CanvasGroup alpha
* No allocations
* Support overlay, camera space and world space
* Support changing material property with AnimationClip (AnimatableProperty)
![](https://user-images.githubusercontent.com/12690315/53286323-2d94a980-37b0-11e9-8afb-c4a207805ff2.gif)
@@ -58,8 +65,10 @@ Compares this "Baking mesh" approach with the conventional approach:
* [4.0.0+] Adaptive scaling for UI
* [4.0.0+] Mesh sharing group to improve performance
![](https://user-images.githubusercontent.com/12690315/174311048-c882df81-6c34-4eba-b0aa-5645457692f1.gif)
* [4.0.0+] particle attractor component
* [4.0.0+] Particle attractor component
![](https://user-images.githubusercontent.com/12690315/174311027-462929a4-13f0-4ec4-86ea-9c832f2eecf1.gif)
* [4.1.0+] Relative/Absolute particle position mode
![](https://user-images.githubusercontent.com/12690315/175751579-5a2357e8-2ecf-4afd-83c8-66e9771bde39.gif)
<br><br><br><br>
@@ -161,6 +170,7 @@ Unity 2018.2 supports embedded packages.
| Scale | Scale the rendering.<br>When the `3D` toggle is enabled, 3D scale (x,y,z) is supported. |
| Animatable Properties | If you want update material properties (e.g. `_MainTex_ST`, `_Color`) in AnimationClip, use this to mark the changes. |
| Mesh Sharing | Particle simulation results are shared within the same group.<br>A large number of the same effects can be displayed with a small load.<br>When the `Random` toggle is enabled, it will be grouped randomaly. |
| Absolute Mode | The particles will be emitted at the ParticleSystem position.<br>Move the UIParticle/ParticleSystem to move the particle. |
| Rendering Order | The ParticleSystems to be rendered.<br>You can change the rendering order and the materials. |
NOTE: Press `Refresh` button to reconstruct rendering order based on children ParticleSystem's sorting order and z position.

View File

@@ -0,0 +1,84 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 6
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: UIParticle_Demo_Dot
m_Shader: {fileID: 10770, guid: 0000000000000000f000000000000000, type: 0}
m_ShaderKeywords:
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: 3001
stringTagMap: {}
disabledShaderPasses: []
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _BumpMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailAlbedoMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailMask:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailNormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _EmissionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MetallicGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _OcclusionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ParallaxMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Floats:
- _BumpScale: 1
- _ColorMask: 15
- _Cutoff: 0.5
- _DetailNormalMapScale: 1
- _DstBlend: 0
- _GlossMapScale: 1
- _Glossiness: 0.5
- _GlossyReflections: 1
- _Metallic: 0
- _Mode: 0
- _OcclusionStrength: 1
- _Parallax: 0.02
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _SrcBlend: 1
- _Stencil: 0
- _StencilComp: 8
- _StencilOp: 0
- _StencilReadMask: 255
- _StencilWriteMask: 255
- _UVSec: 0
- _UseUIAlphaClip: 0
- _ZWrite: 1
m_Colors:
- _Color: {r: 1, g: 1, b: 1, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: b35a584a784274746b87deef91c15c5c
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -14,6 +14,7 @@ public class UIElementDragger : MonoBehaviour, IBeginDragHandler, IDragHandler,
private Canvas canvas;
public Target m_Target;
public Transform m_CustomTarget;
public bool ex2;
private void OnEnable()
{
@@ -37,6 +38,8 @@ public class UIElementDragger : MonoBehaviour, IBeginDragHandler, IDragHandler,
rectTransform.localPosition += delta;
if (m_CustomTarget)
{
if (ex2)
delta.Scale(canvas.rootCanvas.transform.localScale);
m_CustomTarget.localPosition += delta;
}
break;

File diff suppressed because it is too large Load Diff

View File

@@ -62,12 +62,15 @@ namespace Coffee.UIExtensions
private SerializedProperty m_MeshSharing;
private SerializedProperty m_GroupId;
private SerializedProperty m_GroupMaxId;
private SerializedProperty m_AbsoluteMode;
private ReorderableList _ro;
static private bool _xyzMode;
private bool _showMax;
private static readonly HashSet<Shader> s_Shaders = new HashSet<Shader>();
private static readonly List<ParticleSystemVertexStream> s_Streams = new List<ParticleSystemVertexStream>();
private static readonly List<string> s_MaskablePropertyNames = new List<string>
{
"_Stencil",
@@ -83,15 +86,21 @@ namespace Coffee.UIExtensions
static void Init()
{
#if !UNITY_2021_2_OR_NEWER
// static void Window(GUIContent title, WindowFunction sceneViewFunc, int order, UnityEngine.Object target, WindowDisplayOption option)
var miSceneViewOverlayWindow = Type.GetType("UnityEditor.SceneViewOverlay, UnityEditor")
.GetMethods(BindingFlags.Public | BindingFlags.Static)
.First(x => x.Name == "Window" && x.GetParameters().Length == 5);
.First(x => x.Name == "Window" && 5 <= x.GetParameters().Length);
var windowFunction = (Action<UnityEngine.Object, SceneView>)WindowFunction;
var windowFunctionType = Type.GetType("UnityEditor.SceneViewOverlay+WindowFunction, UnityEditor");
var windowFunctionDelegate = Delegate.CreateDelegate(windowFunctionType, windowFunction.Method);
var windowTitle = new GUIContent(ObjectNames.NicifyVariableName(typeof(UIParticle).Name));
#if UNITY_2019_2_OR_NEWER
//public static void Window(GUIContent title, WindowFunction sceneViewFunc, int order, Object target, WindowDisplayOption option, EditorWindow window = null)
var sceneViewArgs = new object[] { windowTitle, windowFunctionDelegate, 599, null, 2, null };
#else
//public static void Window(GUIContent title, WindowFunction sceneViewFunc, int order, Object target, WindowDisplayOption option)
var sceneViewArgs = new object[] { windowTitle, windowFunctionDelegate, 599, null, 2 };
#endif
#if UNITY_2019_1_OR_NEWER
SceneView.duringSceneGui += _ => miSceneViewOverlayWindow.Invoke(null, sceneViewArgs);
#else
@@ -111,15 +120,15 @@ namespace Coffee.UIExtensions
.Select(x => x.GetComponent<ParticleSystem>())
.Where(x => x)
.Select(x => x.GetComponentInParent<UIParticle>())
.Where(x => x)
.Where(x => x && x.canvas)
.Concat(
Selection.gameObjects
.Select(x => x.GetComponent<UIParticle>())
.Where(x => x)
.Where(x => x && x.canvas)
)
.Distinct()
.ToArray();
return uiParticles.Any() ? new SerializedObject(uiParticles) : null;
return 0 < uiParticles.Length ? new SerializedObject(uiParticles) : null;
};
s_SerializedObject = createSerializeObject();
@@ -142,12 +151,13 @@ namespace Coffee.UIExtensions
m_MeshSharing = serializedObject.FindProperty("m_MeshSharing");
m_GroupId = serializedObject.FindProperty("m_GroupId");
m_GroupMaxId = serializedObject.FindProperty("m_GroupMaxId");
m_AbsoluteMode = serializedObject.FindProperty("m_AbsoluteMode");
var sp = serializedObject.FindProperty("m_Particles");
_ro = new ReorderableList(sp.serializedObject, sp, true, true, true, true);
_ro.elementHeight = EditorGUIUtility.singleLineHeight * 3 + 4;
_ro.elementHeight = (EditorGUIUtility.singleLineHeight * 3) + 4;
_ro.elementHeightCallback = _ => 3 * (EditorGUIUtility.singleLineHeight + 2);
_ro.drawElementCallback = (rect, index, active, focused) =>
_ro.drawElementCallback = (rect, index, _, __) =>
{
EditorGUI.BeginDisabledGroup(sp.hasMultipleDifferentValues);
rect.y += 1;
@@ -165,7 +175,7 @@ namespace Coffee.UIExtensions
rect.y += rect.height + 1;
MaterialField(rect, s_ContentTrailMaterial, materials, 1);
EditorGUI.EndDisabledGroup();
if (materials != null)
if (materials != null && materials.serializedObject.hasModifiedProperties)
{
materials.serializedObject.ApplyModifiedProperties();
}
@@ -182,16 +192,17 @@ namespace Coffee.UIExtensions
foreach (UIParticle t in targets)
{
t.RefreshParticles();
EditorUtility.SetDirty(t);
}
}
};
_ro.onReorderCallback = _ =>
// On select UIParticle, refresh particles.
foreach (UIParticle t in targets)
{
foreach (UIParticle t in targets)
{
t.RefreshParticles(t.particles);
}
};
if (Application.isPlaying || PrefabUtility.GetPrefabAssetType(t) != PrefabAssetType.NotAPrefab) continue;
t.RefreshParticles(t.particles);
}
}
private static void MaterialField(Rect rect, GUIContent label, SerializedProperty sp, int index)
@@ -214,7 +225,7 @@ namespace Coffee.UIExtensions
public override void OnInspectorGUI()
{
var current = target as UIParticle;
if (current == null) return;
if (!current) return;
serializedObject.Update();
@@ -248,10 +259,22 @@ namespace Coffee.UIExtensions
}
}
// Target ParticleSystems.
_ro.DoLayoutList();
// Absolute Mode
EditorGUILayout.PropertyField(m_AbsoluteMode);
// Target ParticleSystems.
EditorGUI.BeginChangeCheck();
EditorGUI.BeginDisabledGroup(targets.OfType<UIParticle>().Any(x => !x.canvas));
_ro.DoLayoutList();
EditorGUI.EndDisabledGroup();
serializedObject.ApplyModifiedProperties();
if (EditorGUI.EndChangeCheck())
{
foreach (var uip in targets.OfType<UIParticle>())
{
uip.RefreshParticles(uip.particles);
}
}
// Does the shader support UI masks?
if (current.maskable && current.GetComponentInParent<Mask>())
@@ -260,6 +283,8 @@ namespace Coffee.UIExtensions
{
if (!mat || !mat.shader) continue;
var shader = mat.shader;
if (s_Shaders.Contains(shader)) continue;
s_Shaders.Add(shader);
foreach (var propName in s_MaskablePropertyNames)
{
if (mat.HasProperty(propName)) continue;
@@ -269,6 +294,7 @@ namespace Coffee.UIExtensions
}
}
}
s_Shaders.Clear();
// UIParticle for trail should be removed.
if (FixButton(current.m_IsTrail, "This UIParticle component should be removed. The UIParticle for trails is no longer needed."))
@@ -286,15 +312,86 @@ namespace Coffee.UIExtensions
if (0 < allPsRenderers.Length)
{
var so = new SerializedObject(allPsRenderers);
var sp = so.FindProperty("m_ApplyActiveColorSpace");//.boolValue = false;
var sp = so.FindProperty("m_ApplyActiveColorSpace");
if (FixButton(sp.boolValue || sp.hasMultipleDifferentValues, "When using linear color space, the particle colors are not output correctly.\nTo fix, set 'Apply Active Color Space' in renderer module to false."))
{
sp.boolValue = false;
so.ApplyModifiedProperties();
}
// Check to use 'TEXCOORD*.zw' components as custom vertex stream.
foreach (var psr in allPsRenderers)
{
if (!new SerializedObject(psr).FindProperty("m_UseCustomVertexStreams").boolValue) continue;
if (psr.activeVertexStreamsCount == 0) continue;
psr.GetActiveVertexStreams(s_Streams);
if (2 < s_Streams.Select(GetUsedComponentCount).Sum())
{
EditorGUILayout.HelpBox(string.Format("ParticleSystem '{0}' uses 'TEXCOORD*.zw' components as custom vertex stream.\nUIParticle does not support it (See README.md).", psr.name), MessageType.Warning);
}
}
}
}
private static int GetUsedComponentCount(ParticleSystemVertexStream s)
{
switch (s)
{
case ParticleSystemVertexStream.Position:
case ParticleSystemVertexStream.Normal:
case ParticleSystemVertexStream.Tangent:
case ParticleSystemVertexStream.Color:
return 0;
case ParticleSystemVertexStream.UV:
case ParticleSystemVertexStream.UV2:
case ParticleSystemVertexStream.UV3:
case ParticleSystemVertexStream.UV4:
case ParticleSystemVertexStream.SizeXY:
case ParticleSystemVertexStream.StableRandomXY:
case ParticleSystemVertexStream.VaryingRandomXY:
case ParticleSystemVertexStream.Custom1XY:
case ParticleSystemVertexStream.Custom2XY:
case ParticleSystemVertexStream.NoiseSumXY:
case ParticleSystemVertexStream.NoiseImpulseXY:
return 2;
case ParticleSystemVertexStream.AnimBlend:
case ParticleSystemVertexStream.AnimFrame:
case ParticleSystemVertexStream.VertexID:
case ParticleSystemVertexStream.SizeX:
case ParticleSystemVertexStream.Rotation:
case ParticleSystemVertexStream.RotationSpeed:
case ParticleSystemVertexStream.Velocity:
case ParticleSystemVertexStream.Speed:
case ParticleSystemVertexStream.AgePercent:
case ParticleSystemVertexStream.InvStartLifetime:
case ParticleSystemVertexStream.StableRandomX:
case ParticleSystemVertexStream.VaryingRandomX:
case ParticleSystemVertexStream.Custom1X:
case ParticleSystemVertexStream.Custom2X:
case ParticleSystemVertexStream.NoiseSumX:
case ParticleSystemVertexStream.NoiseImpulseX:
return 1;
case ParticleSystemVertexStream.Center:
case ParticleSystemVertexStream.SizeXYZ:
case ParticleSystemVertexStream.Rotation3D:
case ParticleSystemVertexStream.RotationSpeed3D:
case ParticleSystemVertexStream.StableRandomXYZ:
case ParticleSystemVertexStream.VaryingRandomXYZ:
case ParticleSystemVertexStream.Custom1XYZ:
case ParticleSystemVertexStream.Custom2XYZ:
case ParticleSystemVertexStream.NoiseSumXYZ:
case ParticleSystemVertexStream.NoiseImpulseXYZ:
return 3;
case ParticleSystemVertexStream.StableRandomXYZW:
case ParticleSystemVertexStream.VaryingRandomXYZW:
case ParticleSystemVertexStream.Custom1XYZW:
case ParticleSystemVertexStream.Custom2XYZW:
return 4;
}
return 3;
}
private static bool DrawMeshSharing(SerializedProperty spMeshSharing, SerializedProperty spGroupId, SerializedProperty spGroupMaxId, bool showMax)
{
showMax |= spGroupId.intValue != spGroupMaxId.intValue ||
@@ -333,15 +430,18 @@ namespace Coffee.UIExtensions
{
try
{
if (s_SerializedObject.targetObjects.Any(x => !x)) return;
if (s_SerializedObject.targetObjects.OfType<UIParticle>().Any(x => !x || !x.canvas)) return;
s_SerializedObject.Update();
GUILayout.BeginHorizontal(GUILayout.Width(220f));
var labelWidth = EditorGUIUtility.labelWidth;
EditorGUIUtility.labelWidth = 60;
_xyzMode = DrawFloatOrVector3Field(s_SerializedObject.FindProperty("m_Scale3D"), _xyzMode);
EditorGUIUtility.labelWidth = labelWidth;
GUILayout.EndHorizontal();
using (new EditorGUILayout.VerticalScope(GUILayout.Width(220f)))
{
var labelWidth = EditorGUIUtility.labelWidth;
EditorGUIUtility.labelWidth = 100;
EditorGUILayout.PropertyField(s_SerializedObject.FindProperty("m_Enabled"));
_xyzMode = DrawFloatOrVector3Field(s_SerializedObject.FindProperty("m_Scale3D"), _xyzMode);
EditorGUILayout.PropertyField(s_SerializedObject.FindProperty("m_AbsoluteMode"));
EditorGUIUtility.labelWidth = labelWidth;
}
s_SerializedObject.ApplyModifiedProperties();
}
catch

View File

@@ -2,6 +2,7 @@
#define SERIALIZE_FIELD_MASKABLE
#endif
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using Coffee.UIParticleExtensions;
using UnityEngine;
@@ -54,6 +55,10 @@ namespace Coffee.UIExtensions
[SerializeField]
private int m_GroupMaxId = 0;
[SerializeField]
[Tooltip("The particles will be emitted at the ParticleSystem position.\nMove the UIParticle/ParticleSystem to move the particle.")]
private bool m_AbsoluteMode = false;
private List<UIParticleRenderer> m_Renderers = new List<UIParticleRenderer>();
#if !SERIALIZE_FIELD_MASKABLE
@@ -112,6 +117,17 @@ namespace Coffee.UIExtensions
}
}
/// <summary>
/// Absolute particle position mode.
/// The particles will be emitted at the ParticleSystem position.
/// Move the UIParticle/ParticleSystem to move the particle.
/// </summary>
public bool absoluteMode
{
get { return m_AbsoluteMode; }
set { m_AbsoluteMode = value; }
}
internal bool useMeshSharing
{
get { return m_MeshSharing != MeshSharing.None; }
@@ -272,20 +288,21 @@ namespace Coffee.UIExtensions
{
GetComponentsInChildren(m_Renderers);
for (var i = 0; i < m_Renderers.Count; i++)
{
GetRenderer(i).Clear(i);
}
var j = 0;
for (var i = 0; i < particles.Count; i++)
{
if (!particles[i]) continue;
GetRenderer(j++).Set(this, particles[i], false);
if (particles[i].trails.enabled)
{
GetRenderer(j++).Set(this, particles[i], true);
}
}
for (; j < m_Renderers.Count; j++)
{
GetRenderer(j).Clear(j);
}
}
internal void UpdateTransformScale()
@@ -306,9 +323,15 @@ namespace Coffee.UIExtensions
{
if (!isActiveAndEnabled) return;
if (m_Renderers.Any(x => !x))
{
RefreshParticles(particles);
}
var bakeCamera = GetBakeCamera();
for (var i = 0; i < m_Renderers.Count; i++)
{
if (!m_Renderers[i]) continue;
m_Renderers[i].UpdateMesh(bakeCamera);
}
}
@@ -317,6 +340,7 @@ namespace Coffee.UIExtensions
{
for (var i = 0; i < m_Renderers.Count; i++)
{
if (!m_Renderers[i]) continue;
m_Renderers[i].UpdateParticleCount();
}
}
@@ -402,6 +426,10 @@ namespace Coffee.UIExtensions
{
m_Renderers.Add(UIParticleRenderer.AddRenderer(this, index));
}
if (!m_Renderers[index])
{
m_Renderers[index] = UIParticleRenderer.AddRenderer(this, index);
}
return m_Renderers[index];
}

View File

@@ -14,15 +14,14 @@ namespace Coffee.UIExtensions
internal class UIParticleRenderer : MaskableGraphic
{
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 MaterialPropertyBlock s_Mpb;
private static readonly List<UIParticleRenderer> s_Renderers = new List<UIParticleRenderer>();
private static readonly Vector3[] s_Corners = new Vector3[4];
private ParticleSystemRenderer _renderer;
private ParticleSystem _particleSystem;
internal int _prevParticleCount = 0;
//private ParticleSystem _emitter;
private int _prevParticleCount = 0;
private UIParticle _parent;
private int _index;
private bool _isTrail;
@@ -33,6 +32,7 @@ namespace Coffee.UIExtensions
private bool _delay = false;
private bool _prewarm = false;
private Material _currentMaterialForRendering;
private Bounds _lastBounds;
public override Texture mainTexture
{
@@ -49,6 +49,37 @@ namespace Coffee.UIExtensions
return false;
}
}
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)
{
@@ -123,6 +154,7 @@ namespace Coffee.UIExtensions
material = null;
workerMesh.Clear();
canvasRenderer.SetMesh(workerMesh);
_lastBounds = new Bounds();
enabled = false;
}
}
@@ -135,6 +167,9 @@ namespace Coffee.UIExtensions
gameObject.layer = parent.gameObject.layer;
_particleSystem = particleSystem;
#if UNITY_EDITOR
if (Application.isPlaying)
#endif
if (_particleSystem.isPlaying)
{
_particleSystem.Clear();
@@ -185,6 +220,7 @@ namespace Coffee.UIExtensions
Profiler.BeginSample("[UIParticleRenderer] Clear Mesh");
workerMesh.Clear();
canvasRenderer.SetMesh(workerMesh);
_lastBounds = new Bounds();
Profiler.EndSample();
return;
@@ -246,7 +282,15 @@ namespace Coffee.UIExtensions
Profiler.BeginSample("[UIParticleRenderer] Combine Mesh");
if (_parent.canSimulate)
{
s_CombineInstances[0].transform = canvasRenderer.transform.worldToLocalMatrix * GetWorldMatrix(psPos, scale);
if (_parent.absoluteMode)
{
s_CombineInstances[0].transform = canvasRenderer.transform.worldToLocalMatrix * GetWorldMatrix(psPos, scale);
}
else
{
var diff = _particleSystem.transform.position - _parent.transform.position;
s_CombineInstances[0].transform = canvasRenderer.transform.worldToLocalMatrix * Matrix4x4.Translate(diff.GetScaled(scale - Vector3.one)) * GetWorldMatrix(psPos, scale);
}
workerMesh.CombineMeshes(s_CombineInstances, true, true);
workerMesh.RecalculateBounds();
@@ -258,6 +302,7 @@ namespace Coffee.UIExtensions
extents.z = 0;
bounds.extents = extents;
workerMesh.bounds = bounds;
_lastBounds = bounds;
}
Profiler.EndSample();
@@ -275,6 +320,7 @@ namespace Coffee.UIExtensions
{
if (s_Renderers[i] == this) continue;
s_Renderers[i].canvasRenderer.SetMesh(workerMesh);
s_Renderers[i]._lastBounds = _lastBounds;
}
if (!_parent.canRender)
@@ -342,6 +388,17 @@ namespace Coffee.UIExtensions
protected override void UpdateGeometry()
{
}
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()
{
@@ -450,14 +507,6 @@ namespace Coffee.UIExtensions
_prewarm = false;
}
// Normal simulation for non-scaling or local spacing.
var isScaling = scale != Vector3.one;
if (!isScaling || _particleSystem.GetActualSimulationSpace() == ParticleSystemSimulationSpace.Local)
{
_particleSystem.Simulate(deltaTime, false, false, false);
return;
}
// Emitted particles found.
if (_prevParticleCount != _particleSystem.particleCount)
{

View File

@@ -62,7 +62,7 @@ namespace Coffee.UIExtensions
for (var i = 0; i < s_ActiveParticles.Count; i++)
{
var uip = s_ActiveParticles[i];
if (!uip.isPrimary || s_UpdatedGroupIds.Contains(uip.groupId)) continue;
if (!uip || !uip.canvas || !uip.isPrimary || s_UpdatedGroupIds.Contains(uip.groupId)) continue;
s_UpdatedGroupIds.Add(uip.groupId);
uip.UpdateTransformScale();
@@ -73,6 +73,8 @@ namespace Coffee.UIExtensions
for (var i = 0; i < s_ActiveParticles.Count; i++)
{
var uip = s_ActiveParticles[i];
if (!uip || !uip.canvas) continue;
uip.UpdateTransformScale();
if (!uip.useMeshSharing)
@@ -97,7 +99,10 @@ namespace Coffee.UIExtensions
// UpdateParticleCount.
for (var i = 0; i < s_ActiveParticles.Count; i++)
{
s_ActiveParticles[i].UpdateParticleCount();
var uip = s_ActiveParticles[i];
if (!uip || !uip.canvas) continue;
uip.UpdateParticleCount();
}
}

View File

@@ -2,7 +2,7 @@
"name": "com.coffee.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.",
"version": "4.0.0-preview.1",
"version": "4.1.5",
"unity": "2018.2",
"license": "MIT",
"repository": {