Compare commits

...

124 Commits

Author SHA1 Message Date
semantic-release-bot
7035583bdb chore(release): 4.7.2 [skip ci]
## [4.7.2](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.7.1...v4.7.2) (2024-06-21)

### Bug Fixes

* generated baking-camera object remains in the prefab or scene ([0bb8438](0bb8438301))
2024-06-21 05:22:49 +00:00
mob-sakai
0bb8438301 fix: generated baking-camera object remains in the prefab or scene 2024-06-21 14:21:53 +09:00
semantic-release-bot
e1b66d8d90 chore(release): 4.7.1 [skip ci]
## [4.7.1](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.7.0...v4.7.1) (2024-06-20)

### Bug Fixes

* despite not using the size module, particles become smaller based on their z position ([a8ed6e6](a8ed6e6858)), closes [#316](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/316)
2024-06-20 03:55:01 +00:00
mob-sakai
a8ed6e6858 fix: despite not using the size module, particles become smaller based on their z position
close #316
2024-06-20 12:51:02 +09:00
mob-sakai
3fc7d9dae4 docs: update license 2024-06-19 13:47:05 +09:00
semantic-release-bot
0322d7eb95 chore(release): 4.7.0 [skip ci]
# [4.7.0](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.6.8...v4.7.0) (2024-06-19)

### Bug Fixes

* `UIParticle.transform.localScale` does not scale particles ([1d40e24](1d40e24c74)), closes [#313](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/313)
* UIParticle is scaled by canvas size even when `AutoScalingMode.None` and `ScalingMode.Local` ([54a4b1c](54a4b1cdfd)), closes [#313](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/313)
* UIParticle is scaled incorrectly with nested canvases ([f26920f](f26920f982)), closes [#313](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/313)

### Features

* reset previous position on start play for world space simulation ([3880484](3880484ce5)), closes [#303](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/303)
* restore `Transform.localScale` when setting `autoScalingMode` to something other than `Transform` ([5505247](5505247a94))
2024-06-19 04:30:47 +00:00
mob-sakai
e7be0e77de fix demo 2024-06-19 13:23:40 +09:00
mob-sakai
3880484ce5 feat: reset previous position on start play for world space simulation
close #303
2024-06-19 11:07:29 +09:00
mob-sakai
1d40e24c74 fix: UIParticle.transform.localScale does not scale particles
close #313
2024-06-19 11:07:29 +09:00
mob-sakai
54a4b1cdfd fix: UIParticle is scaled by canvas size even when AutoScalingMode.None and ScalingMode.Local
close #313
2024-06-19 11:07:29 +09:00
mob-sakai
5505247a94 feat: restore Transform.localScale when setting autoScalingMode to something other than Transform 2024-06-19 11:07:29 +09:00
mob-sakai
f26920f982 fix: UIParticle is scaled incorrectly with nested canvases
close #313
2024-06-18 19:44:00 +09:00
mob-sakai
5a1e65ec56 refactor: refactor 2024-06-18 17:11:14 +09:00
semantic-release-bot
accd3f8410 chore(release): 4.6.8 [skip ci]
## [4.6.8](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.6.7...v4.6.8) (2024-06-14)

### Bug Fixes

* 'Resource ID out of range in GetResource' error in overlay rendering mode ([05286ce](05286cedfd)), closes [#308](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/308)
2024-06-14 01:48:23 +00:00
SAMYTHEBIGJUICY
05286cedfd fix: 'Resource ID out of range in GetResource' error in overlay rendering mode
close #308
2024-06-14 10:47:32 +09:00
semantic-release-bot
cbd9c960e2 chore(release): 4.6.7 [skip ci]
## [4.6.7](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.6.6...v4.6.7) (2024-05-24)

### Bug Fixes

* the ParticleSystem's localPosition drifts at certain scales due to floating-point precision issues ([e924eb4](e924eb4596)), closes [#299](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/299) [#312](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/312)
2024-05-24 08:38:56 +00:00
mob-sakai
e924eb4596 fix: the ParticleSystem's localPosition drifts at certain scales due to floating-point precision issues
close #299, close #312
2024-05-24 17:37:32 +09:00
semantic-release-bot
19989cf18c chore(release): 4.6.6 [skip ci]
## [4.6.6](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.6.5...v4.6.6) (2024-05-23)

### Bug Fixes

* fix release workflow ([30b0076](30b00762f6))
2024-05-23 11:04:05 +00:00
mob-sakai
30b00762f6 fix: fix release workflow 2024-05-23 20:03:17 +09:00
semantic-release-bot
154a04c022 chore(release): 4.6.5 [skip ci]
## [4.6.5](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.6.4...v4.6.5) (2024-05-23)

### Bug Fixes

* update workflows (for preview and v4) ([3eab097](3eab0979b9))
2024-05-23 08:50:10 +00:00
mob-sakai
3eab0979b9 fix: update workflows (for preview and v4) 2024-05-23 17:49:30 +09:00
semantic-release-bot
01e08eefbd chore(release): 4.6.4 [skip ci]
## [4.6.4](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.6.3...v4.6.4) (2024-05-22)

### Bug Fixes

* assertion failed on expression: 'ps->array_size()' ([1b5c359](1b5c359058)), closes [#278](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/278)
* lost Material.mainTexture when using AnimatableProperties ([ea04352](ea043524c0)), closes [#311](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/311)
* remove unnecessary code ([c37c014](c37c014864))
2024-05-22 10:53:55 +00:00
mob-sakai
a8af984d6f chore: fix release workflow 2024-05-22 19:53:16 +09:00
mob-sakai
1b5c359058 fix: assertion failed on expression: 'ps->array_size()'
close #278
2024-05-22 17:11:38 +09:00
mob-sakai
ea043524c0 fix: lost Material.mainTexture when using AnimatableProperties
close #311
2024-05-22 16:07:12 +09:00
mob-sakai
c37c014864 fix: remove unnecessary code 2024-04-05 21:02:45 +09:00
semantic-release-bot
dc81428921 chore(release): 4.6.3 [skip ci]
## [4.6.3](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.6.2...v4.6.3) (2024-04-04)

### Bug Fixes

* if only Trail Material is used, it will not be displayed ([2eff411](2eff411bd9)), closes [#294](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/294)
* if the UIParticle parents do not have Canvas, an exception is thrown in OnEnable ([e82c833](e82c833d04)), closes [#300](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/300)
* particle size too small due to auto scaling ([2ec3748](2ec3748336)), closes [#295](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/295)
2024-04-04 08:25:26 +00:00
mob-sakai
e82c833d04 fix: if the UIParticle parents do not have Canvas, an exception is thrown in OnEnable
close #300
2024-04-04 17:24:20 +09:00
mob-sakai
2ec3748336 fix: particle size too small due to auto scaling
close #295
2024-04-04 15:29:33 +09:00
mob-sakai
2eff411bd9 fix: if only Trail Material is used, it will not be displayed
close #294
2024-02-02 03:45:10 +09:00
mob-sakai
46c300b347 docs: update documents 2024-02-01 19:22:44 +09:00
mob-sakai
e1863f25d3 demo: update demos 2024-02-01 17:42:50 +09:00
mob-sakai
89289c052f test: update test workflow 2024-02-01 17:42:50 +09:00
semantic-release-bot
84ac11e6b7 chore(release): 4.6.2 [skip ci]
## [4.6.2](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.6.1...v4.6.2) (2024-02-01)

### Bug Fixes

* fix compile error in Unity 2021.1 or older ([fcae60b](fcae60bf29))
* fix demos ([ad20d12](ad20d128a2))
* fix warning ([7fd4a8e](7fd4a8e343))
2024-02-01 07:23:21 +00:00
mob-sakai
cc2be37b9e test: update test workflow 2024-02-01 16:22:52 +09:00
mob-sakai
ad20d128a2 fix: fix demos 2024-02-01 16:18:17 +09:00
mob-sakai
fcae60bf29 fix: fix compile error in Unity 2021.1 or older 2024-02-01 16:18:17 +09:00
mob-sakai
7fd4a8e343 fix: fix warning 2024-02-01 16:14:15 +09:00
mob-sakai
2052dda953 docs: update contributing 2024-02-01 16:14:11 +09:00
semantic-release-bot
e88bc54c2c chore(release): 4.6.1 [skip ci]
## [4.6.1](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.6.0...v4.6.1) (2024-01-26)

### Bug Fixes

* unintended scaling occurs when `AutoScalingMode=UIParticle` and `ScalingMode=Local` ([1627de1](1627de10eb)), closes [#292](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/292)
2024-01-26 11:41:10 +00:00
mob-sakai
1627de10eb fix: unintended scaling occurs when AutoScalingMode=UIParticle and ScalingMode=Local
close #292
2024-01-26 20:40:36 +09:00
semantic-release-bot
88890ff159 chore(release): 4.6.0 [skip ci]
# [4.6.0](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.5.2...v4.6.0) (2024-01-26)

### Bug Fixes

* fix abnormal mesh bounds error ([772bf50](772bf50d16)), closes [#213](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/213)
* fix warning ([93d3919](93d3919b6f))
* fix warning ([8a78ec1](8a78ec13ad))

### Features

* "[generated]" GameObjects on the hierarchy is disturbing ([7c42421](7c4242150b)), closes [#288](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/288)
* add explicit dependencies ([9a0187a](9a0187a72a))
* add icon ([0c1022c](0c1022c622))
* remove samples ([f53a7fa](f53a7faed3))
2024-01-26 09:56:34 +00:00
mob-sakai
25582dc51f docs: update readme 2024-01-26 18:55:20 +09:00
semantic-release-bot
76c6dcfd76 chore(release): 4.6.0-preview.1 [skip ci]
# [4.6.0-preview.1](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.5.2...v4.6.0-preview.1) (2024-01-24)

### Bug Fixes

* fix abnormal mesh bounds error ([772bf50](772bf50d16)), closes [#213](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/213)
* fix warning ([93d3919](93d3919b6f))
* fix warning ([8a78ec1](8a78ec13ad))

### Features

* "[generated]" GameObjects on the hierarchy is disturbing ([7c42421](7c4242150b)), closes [#288](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/288)
* add explicit dependencies ([9a0187a](9a0187a72a))
* add icon ([0c1022c](0c1022c622))
* remove samples ([f53a7fa](f53a7faed3))
2024-01-24 07:29:29 +00:00
wmltogether
772bf50d16 fix: fix abnormal mesh bounds error
close #213
2024-01-24 16:20:56 +09:00
mob-sakai
93d3919b6f fix: fix warning 2024-01-24 16:07:36 +09:00
mob-sakai
0c1022c622 feat: add icon 2024-01-24 00:40:12 +09:00
mob-sakai
c61d22d221 refactor: apply refactor 2024-01-23 23:27:46 +09:00
mob-sakai
cbe3105b0f refactor: fix package structure 2024-01-23 23:17:31 +09:00
mob-sakai
7c4242150b feat: "[generated]" GameObjects on the hierarchy is disturbing
close #288
2024-01-23 23:01:45 +09:00
mob-sakai
c6b25c73bf refactor: (remove code) sub emitters option is not work in editor playing 2024-01-23 19:55:30 +09:00
mob-sakai
2f4a963a56 chore: release workflow 2024-01-23 15:07:10 +09:00
mob-sakai
4c5b1287a4 docs: fix readme 2023-11-21 11:55:34 +09:00
mob-sakai
15e31abc3c chore: support CFXR for demo 2023-11-26 17:16:37 +09:00
mob-sakai
8a78ec13ad fix: fix warning 2023-11-26 17:15:26 +09:00
mob-sakai
f53a7faed3 feat: remove samples 2023-11-21 16:33:27 +09:00
mob-sakai
0af2042132 style: update package.json 2024-01-23 11:48:00 +09:00
mob-sakai
9a0187a72a feat: add explicit dependencies 2024-01-23 11:38:45 +09:00
mob-sakai
e4f5fde11c chore: remove workflow in the package 2024-01-23 12:39:27 +09:00
mob-sakai
974aff72d7 Add 'Packages/src/' from commit '32b93d3eeb52c6471244c324d0a6572b756c561a'
git-subtree-dir: Packages/src
git-subtree-mainline: 2aa8d41950
git-subtree-split: 32b93d3eeb
2024-01-23 14:55:04 +09:00
mob-sakai
2aa8d41950 init 2024-01-23 14:54:17 +09:00
semantic-release-bot
32b93d3eeb chore(release): 4.5.2 [skip ci]
## [4.5.2](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/4.5.1...4.5.2) (2024-01-18)

### Bug Fixes

* (editor) sometimes crashes when entering play mode ([b80c3e6](b80c3e6c9f))
2024-01-18 10:41:58 +00:00
mob-sakai
86de8b6e03 Merge pull request #289 from wmltogether/fix-deserialize-crash
Fix Editor sometimes crashes when entering Play Mode
2024-01-18 19:41:27 +09:00
wmltogether
b80c3e6c9f fix: (editor) sometimes crashes when entering play mode
If there are particle prefabs created using version 3.x in the project, there is a possibility that the editor may crash when entering Play Mode due to deserialization.
2024-01-18 19:40:12 +09:00
semantic-release-bot
6a1fef4150 chore(release): 4.5.1 [skip ci]
## [4.5.1](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/4.5.0...4.5.1) (2023-12-23)

### Bug Fixes

* fix material for mesh sharing group ([6126af9](6126af9f37))
* the changes made to the material used by the ParticleSystem are not immediately reflected ([3184ba9](3184ba94ae)), closes [#280](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/280)
2023-12-23 10:48:34 +00:00
mob-sakai
3184ba94ae fix: the changes made to the material used by the ParticleSystem are not immediately reflected
close #280
2023-12-23 19:43:50 +09:00
mob-sakai
6126af9f37 fix: fix material for mesh sharing group 2023-12-23 19:23:20 +09:00
semantic-release-bot
c6b816c312 chore(release): 4.5.0 [skip ci]
# [4.5.0](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/4.4.0...4.5.0) (2023-12-23)

### Bug Fixes

* incorrect rendering of world-space simulated particles while animating scale ([ac58475](ac58475539)), closes [#285](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/285)
* remove obsolete warning ([5d5eb34](5d5eb34590))

### Features

* Automatically generated objects are no longer editable (NotEditable). ([5607dc4](5607dc4eed))
* support IMeshModifier ([5c3232f](5c3232faf3)), closes [#282](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/282)
2023-12-23 07:32:51 +00:00
mob-sakai
5d5eb34590 fix: remove obsolete warning 2023-12-23 14:48:37 +09:00
mob-sakai
5c3232faf3 feat: support IMeshModifier
Custom vertex effects and CompositeCanvasRenderer are supported
close #282
2023-12-23 14:46:39 +09:00
mob-sakai
ac58475539 fix: incorrect rendering of world-space simulated particles while animating scale
close #285
2023-12-23 14:32:04 +09:00
mob-sakai
5607dc4eed feat: Automatically generated objects are no longer editable (NotEditable).
The automatically generated objects (UIParticleRenderer, UIParticleOverlayCamera) are not editable and will not be saved in scenes or prefabs.
2023-12-23 14:28:55 +09:00
mob-sakai
4e4b9eb2a7 doc: update readme 2023-11-09 14:18:16 +09:00
semantic-release-bot
3fac6e4773 chore(release): 4.4.0 [skip ci]
# [4.4.0](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/4.3.0...4.4.0) (2023-11-08)

### Features

* support 'Active Apply Color Space' for linear color space ([45c56bb](45c56bbd85))
2023-11-08 11:31:04 +00:00
mob-sakai
45c56bbd85 feat: support 'Active Apply Color Space' for linear color space 2023-11-08 20:24:38 +09:00
semantic-release-bot
2b8d3b1385 chore(release): 4.3.0 [skip ci]
# [4.3.0](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/4.2.2...4.3.0) (2023-11-08)

### Features

* added 'autoScalingMode (None, Transform.localScale, UIParticle.scale)' instead of 'autoScaling' ([107f901](107f901fe3))
* reset transform.localScale on upgrading v3.x to v4.x ([c710787](c710787b5b)), closes [#277](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/277)
2023-11-08 03:26:34 +00:00
mob-sakai
c710787b5b feat: reset transform.localScale on upgrading v3.x to v4.x
close #277
2023-11-08 11:53:16 +09:00
mob-sakai
107f901fe3 feat: added 'autoScalingMode (None, Transform.localScale, UIParticle.scale)' instead of 'autoScaling'
fixed issue when upgrading from 3.x to 4.x
2023-11-07 17:48:02 +09:00
semantic-release-bot
447996ce0f chore(release): 4.2.2 [skip ci]
## [4.2.2](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/4.2.1...4.2.2) (2023-10-25)

### Bug Fixes

* il2cpp code stripping bug ([73f6dad](73f6dad0f3)), closes [#269](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/269)
2023-10-25 17:23:55 +00:00
mob-sakai
73f6dad0f3 fix: il2cpp code stripping bug
close #269
2023-10-26 02:22:52 +09:00
semantic-release-bot
3c11209f17 chore(release): 4.2.1 [skip ci]
## [4.2.1](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/4.2.0...4.2.1) (2023-08-18)

### Bug Fixes

* autoScaling and PositionMode may be locked ([3f2f12d](3f2f12d2cf))
2023-08-18 13:50:36 +00:00
mob-sakai
3f2f12d2cf fix: autoScaling and PositionMode may be locked 2023-08-18 21:22:35 +09:00
semantic-release-bot
b9643b98ff chore(release): 4.2.0 [skip ci]
# [4.2.0](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/4.1.7...4.2.0) (2023-08-18)

### Bug Fixes

* assertion 'ps->array_size()' in UpdateMesh() when using trails of type ribbon ([f75fcce](f75fcce0da)), closes [#241](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/241)
* built-in shaders are no longer supported ([c2119c1](c2119c171a)), closes [#233](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/233) [#257](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/257)
* crash occurs when too many vertices are rendered ([723a04d](723a04d0cf))
* error: SerializedObject target has been destroyed ([e930516](e93051603e)), closes [#267](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/267)
* excessive particle emitted on move ParticleSystem for local space simulation and emission over distance ([2fe0bde](2fe0bde422)), closes [#265](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/265)
* fix typos ([52f2ef1](52f2ef1f24))
* generated GameObject will be named '[generated] *' ([9b2e5c1](9b2e5c1d10))
* inactive ParticleSystems are removed from the list on refresh ([4851a18](4851a1880e))
* mesh sharing not working ([8b4ca1a](8b4ca1add5)), closes [#236](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/236)
* nullptr exceptions when using nested UIParticle components in hierarchy ([e67e948](e67e9482e2)), closes [#246](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/246)
* nullReferenceException after copy-n-paste ([425aad0](425aad0cba)), closes [#258](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/258)
* remove unnecessary per-frame allocation. ([e92b514](e92b514624))
* scaling ParticleSystem puts prewarmed particles in wrong location ([fb31db4](fb31db47f2)), closes [#235](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/235)
* sub-emitters option is not work in editor playing ([b308b26](b308b26833)), closes [#231](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/231)
* the camera under UIParticle will be assigned as _orthoCamera ([c42f8c8](c42f8c8ab0))
* UIParticleAttractor attracts the particles at wrong position when in RelativeMode ([68d9925](68d9925a16)), closes [#262](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/262)

### Features

* 'AbsoluteMode' option is renamed to 'PositionMode' ([67eff61](67eff61073))
* 'AutoScaling' option will be imported from 'IgnoreCanvasScale' (for v3.x) ([4103041](410304125f))
* add 'AutoScaling' option for UIParticle ([35325c8](35325c8899))
* add 'UpdateMode' option for UIParticleAttractor ([903f702](903f702d7b)), closes [#250](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/250)
* add particle system getter and setter for attractor ([a4bcf93](a4bcf93022)), closes [#253](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/253)
* add public properties for UIParticleAttractor ([392ab6d](392ab6dd76)), closes [#253](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/253)
* add Start/StopEmission API for UIParticle ([e499836](e4998365c9)), closes [#240](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/240)
2023-08-18 08:54:23 +00:00
mob-sakai
b36a1571b3 chore: fix workflows 2023-08-18 17:52:48 +09:00
mob-sakai
c42f8c8ab0 fix: the camera under UIParticle will be assigned as _orthoCamera
Prevents unintended camera control
2023-08-18 17:45:04 +09:00
mob-sakai
9b2e5c1d10 fix: generated GameObject will be named '[generated] *'
These objects are automatically generated and are not stored in the scene or prefab (HideFlags.DontSave)
2023-08-18 17:45:04 +09:00
mob-sakai
821f08ff5c docs: add FAQ 2023-08-18 17:45:04 +09:00
mob-sakai
28d8698597 fix compile error on Unity 2021.1 2023-08-18 17:45:04 +09:00
mob-sakai
db28f171f7 docs: update docs 2023-08-18 15:08:24 +09:00
mob-sakai
410304125f feat: 'AutoScaling' option will be imported from 'IgnoreCanvasScale' (for v3.x) 2023-08-18 13:17:09 +09:00
mob-sakai
67eff61073 feat: 'AbsoluteMode' option is renamed to 'PositionMode'
AbsoluteMode property is obsolete
2023-08-18 13:17:09 +09:00
mob-sakai
4851a1880e fix: inactive ParticleSystems are removed from the list on refresh 2023-08-18 13:17:09 +09:00
mob-sakai
2fe0bde422 fix: excessive particle emitted on move ParticleSystem for local space simulation and emission over distance
close #265
2023-08-18 13:17:09 +09:00
mob-sakai
c2119c171a fix: built-in shaders are no longer supported
close #233, close #257

Use UI shaders instead.
If built-in non-UI shaders are used, an error is displayed in the inspector.
2023-08-18 13:17:09 +09:00
mob-sakai
3df190382a resharp 2023-08-18 13:17:09 +09:00
mob-sakai
35325c8899 feat: add 'AutoScaling' option for UIParticle
Transform.lossyScale (=world scale) is automatically set to (1, 1, 1).
It prevents the root-Canvas scale from affecting the hierarchy-scaled ParticleSystem.
This option works in reverse of ’IgnoreCanvasScaler’ option in v3.x.
2023-08-18 11:48:05 +09:00
mob-sakai
903f702d7b feat: add 'UpdateMode' option for UIParticleAttractor
close #250
2023-08-18 11:48:05 +09:00
mob-sakai
e93051603e fix: error: SerializedObject target has been destroyed
close #267
2023-08-18 11:48:05 +09:00
mob-sakai
e4998365c9 feat: add Start/StopEmission API for UIParticle
close #240
2023-08-18 11:48:05 +09:00
mob-sakai
68d9925a16 fix: UIParticleAttractor attracts the particles at wrong position when in RelativeMode
close #262
2023-08-18 11:48:05 +09:00
mob-sakai
392ab6dd76 feat: add public properties for UIParticleAttractor
close #253
2023-08-18 11:48:05 +09:00
mob-sakai
f75fcce0da fix: assertion 'ps->array_size()' in UpdateMesh() when using trails of type ribbon
close #241
2023-08-18 11:48:05 +09:00
mob-sakai
fb31db47f2 fix: scaling ParticleSystem puts prewarmed particles in wrong location
close #235
2023-08-18 11:47:40 +09:00
mob-sakai
425aad0cba fix: nullReferenceException after copy-n-paste
close #258
2023-08-18 11:47:40 +09:00
mob-sakai
8b4ca1add5 fix: mesh sharing not working
close #236
2023-08-18 11:47:40 +09:00
mob-sakai
b308b26833 fix: sub-emitters option is not work in editor playing
close #231
2023-08-18 11:47:40 +09:00
mob-sakai
e67e9482e2 fix: nullptr exceptions when using nested UIParticle components in hierarchy
close #246
2023-08-18 11:47:11 +09:00
mob-sakai
723a04d0cf fix: crash occurs when too many vertices are rendered 2023-08-18 11:47:11 +09:00
mob-sakai
52f2ef1f24 fix: fix typos 2023-08-15 09:40:11 +09:00
Jake O'Connor
e92b514624 fix: remove unnecessary per-frame allocation. 2023-08-15 09:40:11 +09:00
AndreevWezom
a4bcf93022 feat: add particle system getter and setter for attractor
close #253
2023-08-15 09:40:11 +09:00
semantic-release-bot
a499f0c046 chore(release): 4.1.7 [skip ci]
## [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](bdeeabbbe1))
2022-08-30 00:42:14 +00:00
takashi.sakai
447c83dbbc docs: add shader sample 2022-08-30 09:40:59 +09:00
Bamdad Bastani
bdeeabbbe1 fix: the annoying empty black scene overlay box shown even when nothing is selected 2022-08-30 09:40:00 +09:00
semantic-release-bot
5e6da2e158 chore(release): 4.1.6 [skip ci]
## [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](f60d6dfe60)), closes [#213](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/213) [#218](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/218)
2022-08-10 07:46:41 +00:00
takashi.sakai
f60d6dfe60 fix: fix abnormal mesh bounds error
close #213, close #218
2022-08-10 16:45:50 +09:00
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
227 changed files with 9859 additions and 12183 deletions

208
.editorconfig Normal file
View File

@@ -0,0 +1,208 @@
root = true
[*.json]
charset = utf-8
end_of_line = lf
indent_style = space
indent_size = 2
trim_trailing_whitespace = true
insert_final_newline = true
[*.asmdef]
charset = utf-8
end_of_line = lf
indent_style = space
indent_size = 4
trim_trailing_whitespace = true
insert_final_newline = true
# C# files
[*.cs]
charset = utf-8
end_of_line = lf
indent_style = space
indent_size = 4
trim_trailing_whitespace = true
insert_final_newline = true
csharp_style_implicit_object_creation_when_type_is_apparent = false
resharper_object_creation_when_type_evident = explicitly_typed
# Keep
csharp_keep_existing_attribute_arrangement = true
csharp_keep_existing_embedded_arrangement = true
csharp_keep_user_linebreaks = true
csharp_keep_existing_linebreaks = true
csharp_place_simple_embedded_statement_on_same_line = false
csharp_place_simple_blocks_on_single_line = false
csharp_keep_existing_initializer_arrangement = true
csharp_keep_existing_arrangement = true
# Standard properties
end_of_line = lf
insert_final_newline = true
# Brace preferences
csharp_brace_style = next_line
csharp_braces_for_ifelse = required_for_multiline_statement
csharp_braces_for_for = required
csharp_braces_for_foreach = required
csharp_braces_for_while = required
csharp_braces_for_dowhile = required
csharp_braces_for_using = required
csharp_case_block_braces = next_line
csharp_initializer_braces = next_line
# New line preferences
csharp_new_line_before_open_brace = all
csharp_new_line_before_else = true
csharp_new_line_before_catch = true
csharp_new_line_before_finally = true
csharp_new_line_before_members_in_object_initializers = true
csharp_new_line_before_members_in_anonymous_types = true
csharp_new_line_between_query_expression_clauses = true
# Indentation preferences
csharp_indent_block_contents = true
csharp_indent_braces = false
csharp_indent_case_contents = true
csharp_indent_case_contents_when_block = false
csharp_indent_switch_labels = true
csharp_indent_labels = one_less_than_current
# Modifier preferences
csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:suggestion
# avoid this. unless absolutely necessary
dotnet_style_qualification_for_field = false:suggestion
dotnet_style_qualification_for_property = false:suggestion
dotnet_style_qualification_for_method = false:suggestion
dotnet_style_qualification_for_event = false:suggestion
# Types: use keywords instead of BCL types, and permit var only when the type is clear
csharp_style_var_for_built_in_types = true:suggestion
csharp_style_var_when_type_is_apparent = true:none
csharp_style_var_elsewhere = true:suggestion
dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
dotnet_style_predefined_type_for_member_access = true:suggestion
# Arguments
csharp_arguments_literal = named:suggestion
csharp_arguments_string_literal = named:suggestion
# Naming: public and protected fields -> camelCase
dotnet_naming_rule.protected_public_fields.severity = suggestion
dotnet_naming_rule.protected_public_fields.symbols = protected_public_fields
dotnet_naming_rule.protected_public_fields.style = camel_case
dotnet_naming_symbols.protected_public_fields.applicable_kinds = field, event
dotnet_naming_symbols.protected_public_fields.applicable_accessibilities = public, protected
dotnet_naming_style.camel_case.capitalization = camel_case
# Naming: properties -> camelCase
dotnet_naming_rule.properties.severity = suggestion
dotnet_naming_rule.properties.symbols = properties
dotnet_naming_rule.properties.style = camel_case
dotnet_naming_symbols.properties.applicable_kinds = property
# Naming: constant fields -> k_PascalCase
dotnet_naming_rule.constant_fields.severity = suggestion
dotnet_naming_rule.constant_fields.symbols = constant_fields
dotnet_naming_rule.constant_fields.style = k_pascal_case
dotnet_naming_symbols.constant_fields.applicable_kinds = field
dotnet_naming_symbols.constant_fields.required_modifiers = const
dotnet_naming_style.k_pascal_case.required_prefix = k_
dotnet_naming_style.k_pascal_case.capitalization = pascal_case
# Naming: static fields -> s_PascalCase
dotnet_naming_rule.static_fields_should_have_prefix.severity = suggestion
dotnet_naming_rule.static_fields_should_have_prefix.symbols = static_fields
dotnet_naming_rule.static_fields_should_have_prefix.style = s_pascal_case
dotnet_naming_symbols.static_fields.applicable_kinds = field, property
dotnet_naming_symbols.static_fields.required_modifiers = static
dotnet_naming_symbols.static_fields.applicable_accessibilities = private, internal, private_protected
dotnet_naming_style.s_pascal_case.required_prefix = s_
dotnet_naming_style.s_pascal_case.capitalization = pascal_case
# Naming: internal and private fields -> _camelCase
dotnet_naming_rule.private_internal_fields.severity = suggestion
dotnet_naming_rule.private_internal_fields.symbols = private_internal_fields
dotnet_naming_rule.private_internal_fields.style = _camel_case
dotnet_naming_symbols.private_internal_fields.applicable_kinds = field
dotnet_naming_symbols.private_internal_fields.applicable_accessibilities = private, internal
dotnet_naming_style._camel_case.required_prefix = _
dotnet_naming_style._camel_case.capitalization = camel_case
# Code style defaults
dotnet_sort_system_directives_first = true
csharp_preserve_single_line_statements = false:none
csharp_prefer_static_local_function = true:suggestion
csharp_prefer_simple_using_statement = false:none
csharp_style_prefer_switch_expression = true:suggestion
dotnet_style_readonly_field = true:suggestion
# Expression-level preferences
dotnet_style_object_initializer = true:suggestion
dotnet_style_collection_initializer = true:suggestion
dotnet_style_explicit_tuple_names = true:suggestion
dotnet_style_coalesce_expression = true:suggestion
dotnet_style_null_propagation = true:suggestion
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
dotnet_style_prefer_inferred_tuple_names = true:suggestion
dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
dotnet_style_prefer_auto_properties = true:suggestion
dotnet_style_prefer_conditional_expression_over_assignment = true:silent
dotnet_style_prefer_conditional_expression_over_return = true:silent
csharp_prefer_simple_default_expression = true:suggestion
# Expression-bodied members
csharp_style_expression_bodied_accessors = when_on_single_line:suggestion
csharp_style_expression_bodied_methods = false:suggestion
csharp_style_expression_bodied_constructors = false:suggestion
csharp_style_expression_bodied_operators = false:suggestion
csharp_style_expression_bodied_properties = when_on_single_line:suggestion
csharp_style_expression_bodied_indexers = false:suggestion
csharp_style_expression_bodied_lambdas = when_on_single_line:silent
csharp_style_expression_bodied_local_functions = false:suggestion
# Pattern matching
csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
csharp_style_inlined_variable_declaration = true:suggestion
# Null checking preferences
csharp_style_throw_expression = true:suggestion
csharp_style_conditional_delegate_call = true:suggestion
# Other features
csharp_style_prefer_index_operator = false:none
csharp_style_prefer_range_operator = false:none
csharp_style_pattern_local_over_anonymous_function = false:none
# Space preferences
csharp_space_after_cast = false
csharp_space_after_colon_in_inheritance_clause = true
csharp_space_after_comma = true
csharp_space_after_dot = false
csharp_space_after_keywords_in_control_flow_statements = true
csharp_space_after_semicolon_in_for_statement = true
csharp_space_around_binary_operators = before_and_after
csharp_space_around_declaration_statements = do_not_ignore
csharp_space_before_colon_in_inheritance_clause = true
csharp_space_before_comma = false
csharp_space_before_dot = false
csharp_space_before_open_square_brackets = false
csharp_space_before_semicolon_in_for_statement = false
csharp_space_between_empty_square_brackets = false
csharp_space_between_method_call_empty_parameter_list_parentheses = false
csharp_space_between_method_call_name_and_opening_parenthesis = false
csharp_space_between_method_call_parameter_list_parentheses = false
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
csharp_space_between_method_declaration_name_and_open_parenthesis = false
csharp_space_between_method_declaration_parameter_list_parentheses = false
csharp_space_between_parentheses = false
csharp_space_between_square_brackets = false
# ReSharper inspection severities
resharper_check_namespace_highlighting = none
resharper_for_can_be_converted_to_foreach_highlighting = none
resharper_xmldoc_indent_text = ZeroIndent

View File

@@ -1,24 +1,103 @@
name: release
name: 🔖 Release
on:
workflow_dispatch:
push:
branches:
- preview
- main
- v*.x
- release
- release-preview
- release-v4
tags-ignore:
- "**"
jobs:
release:
name: 🔖 Release (${{ github.ref_name }})
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
issues: write
outputs:
channel: ${{ steps.release.outputs.new_release_channel }}
released: ${{ steps.release.outputs.new_release_published }}
tag: ${{ steps.release.outputs.new_release_git_tag }}
version: ${{ steps.release.outputs.new_release_version }}
merge_to: ${{ steps.summary.outputs.merge_to }}
split_to: ${{ steps.summary.outputs.split_to }}
steps:
- uses: actions/checkout@v2
- name: 🚚 Checkout (${{ github.ref_name }})
uses: actions/checkout@v4
- uses: cycjimmy/semantic-release-action@v2
- name: 🔖 Run semantic release
uses: cycjimmy/semantic-release-action@v4
id: release
with:
working_directory: Packages/src
extra_plugins: |
@semantic-release/changelog
@semantic-release/git
env:
GITHUB_TOKEN: ${{ github.token }}
- id: summary
run: |
echo "🔖 New release published: '${{ steps.release.outputs.new_release_published }}'" | tee -a $GITHUB_STEP_SUMMARY
echo "🔖 New release version: '${{ steps.release.outputs.new_release_version }}'" | tee -a $GITHUB_STEP_SUMMARY
echo "🔖 New release channel: '${{ steps.release.outputs.new_release_channel }}'" | tee -a $GITHUB_STEP_SUMMARY
echo "🔖 New release git tag: '${{ steps.release.outputs.new_release_git_tag }}'" | tee -a $GITHUB_STEP_SUMMARY
if [ '${{ steps.release.outputs.new_release_published }}' = 'false' ]; then
echo "No new release published." | tee -a $GITHUB_STEP_SUMMARY
elif [ '${{ github.ref_name }}' = 'release' ]; then
echo "merge_to=develop" | tee -a $GITHUB_OUTPUT
echo "split_to=main" | tee -a $GITHUB_OUTPUT
elif [ '${{ github.ref_name }}' = 'release-preview' ]; then
echo "merge_to=develop-preview" | tee -a $GITHUB_OUTPUT
echo "split_to=preview" | tee -a $GITHUB_OUTPUT
elif [ '${{ github.ref_name }}' = 'release-4.x' ]; then
echo "merge_to=develop-4.x" | tee -a $GITHUB_OUTPUT
echo "split_to=4.x" | tee -a $GITHUB_OUTPUT
fi
merge-to:
if: needs.release.outputs.merge_to != ''
needs: release
name: 🔀 Merge to ${{ needs.release.outputs.merge_to }}
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: 🚚 Checkout (${{ needs.release.outputs.merge_to }})
uses: actions/checkout@v4
with:
ref: ${{ needs.release.outputs.merge_to }}
fetch-depth: 0
- name: 🔀 Merge '${{ needs.release.outputs.tag }}' into '${{ needs.release.outputs.merge_to }}'
run: |
git config --local user.email "github-actions[bot]@users.noreply.github.com"
git config --local user.name "github-actions[bot]"
git merge ${{ needs.release.outputs.tag }}
git push origin ${{ needs.release.outputs.merge_to }}
split-to:
if: needs.release.outputs.split_to != ''
needs: release
name: 🔀 Split package to ${{ needs.release.outputs.split_to }}
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: 🚚 Checkout (${{ needs.release.outputs.tag }})
uses: actions/checkout@v4
with:
ref: ${{ needs.release.outputs.tag }}
fetch-depth: 0
- name: 🔀 Split subtree 'Packages/src' to '${{ needs.release.outputs.split_to }}'
run: |
split_to=${{ needs.release.outputs.split_to }}
git branch $split_to origin/$split_to
git subtree split --prefix=Packages/src --branch $split_to
git tag ${{ needs.release.outputs.version }} $split_to
git push origin ${{ needs.release.outputs.version }} $split_to:$split_to

View File

@@ -1,13 +1,26 @@
# Secrets
# UNITY_LICENSE:
name: test
# Required secrets
# UNITY_LICENSE: The contents of Unity license file
# UNITY_EMAIL: Unity user email to login
# UNITY_PASSWORD: Unity user password to login
name: 🧪 Test
env:
# MINIMUM_VERSION: The minimum version of Unity.
MINIMUM_VERSION: 2019.4
# EXCLUDE_FILTER: The excluded versions of Unity.
EXCLUDE_FILTER: '(2020.2.0)'
on:
workflow_dispatch:
push:
branches:
- develop
- develop-preview
- develop-4.x
tags:
- "!*"
paths-ignore:
- "*.md"
pull_request:
types:
- opened
@@ -15,55 +28,68 @@ on:
jobs:
setup:
name: ⚙️ Setup
runs-on: ubuntu-latest
outputs:
versions: ${{ steps.setup.outputs.versions }}
unityVersions: ${{ steps.setup.outputs.unityVersions }}
steps:
- id: setup
- name: ⚙️ Find target Unity versions
id: setup
run: |
VERSIONS=`npx unity-changeset list --versions --all --latest-patch --min 2018.3 --json`
echo "==== Target Unity Versions ===="
echo "${VERSIONS}"
echo "::set-output name=versions::${VERSIONS}"
LATEST_VERSIONS=`npx unity-changeset list --versions --latest-patch --min ${MINIMUM_VERSION} --json --all`
# ADDITIONAL_VERSIONS=`npx unity-changeset list --versions --grep '0f' --min ${MINIMUM_VERSION} --json`
ADDITIONAL_VERSIONS=[]
VERSIONS=`echo "[${LATEST_VERSIONS}, ${ADDITIONAL_VERSIONS}]" \
| jq -c '[ flatten | sort | unique | .[] | select( test("${{ env.EXCLUDE_FILTER }}") | not ) ]'`
echo "unityVersions=${VERSIONS}" | tee $GITHUB_OUTPUT
test:
name: 🧪 Run tests
runs-on: ubuntu-latest
env:
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }}
permissions:
checks: write
contents: read
needs: setup
strategy:
fail-fast: false
max-parallel: 4
matrix:
version: ${{ fromJson(needs.setup.outputs.versions) }}
unityVersion: ${{ fromJson(needs.setup.outputs.unityVersions) }}
steps:
# Checkout sandbox project
- uses: actions/checkout@v2
with:
ref: sandbox
submodules: true
fetch-depth: 0
- name: 🚚 Checkout
uses: actions/checkout@v4
# Update package submodule
- name: "Update package submodule"
working-directory: Packages/dev
run: git checkout ${{ github.sha }}
# Cache
- uses: actions/cache@v2
- name: 📥 Cache library
uses: actions/cache@v4
with:
path: Library
key: Library-${{ matrix.version }}-${{ github.sha }}
key: Library-${{ matrix.unityVersion }}-${{ github.sha }}
restore-keys: |
Library-${{ matrix.version }}-
Library-${{ matrix.unityVersion }}-
Library-
# Run tests
- name: "Run tests"
uses: game-ci/unity-test-runner@v2
- name: 🛠️ Build Unity Project
uses: game-ci/unity-builder@v4
timeout-minutes: 45
with:
customImage: mobsakai/unity3d:${{ matrix.version }}
customImage: ghcr.io/mob-sakai/unity3d:${{ matrix.unityVersion }}
targetPlatform: StandaloneLinux64
allowDirtyBuild: true
customParameters: -nographics
# unityVersion: ${{ matrix.version }}
checkName: ${{ matrix.version }} Test Results
- name: 🧪 Run tests
uses: game-ci/unity-test-runner@v4
timeout-minutes: 45
with:
customImage: ghcr.io/mob-sakai/unity3d:${{ matrix.unityVersion }}
# unityVersion: ${{ matrix.unityVersion }}
customParameters: -nographics
checkName: ${{ matrix.unityVersion }} Test Results
githubToken: ${{ github.token }}
env:
UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }}
coverageOptions: "dontClear;generateHtmlReport;generateBadgeReport;pathFilters:+**/Packages/src/**;assemblyFilters:+<packages>,-*.Editor,-*.Test"

31
.gitignore vendored Normal file
View File

@@ -0,0 +1,31 @@
# Windows
Thumbs.db
Desktop.ini
/*.csproj
/*.sln
# macOS
.DS_Store
# Vim
*.swp
# Unity
/Logs
/Library
/Temp
Assets/Plugins.meta
Assets/JMO Assets.meta
Assets/JMO Assets
Assets/EffectExamples/
Assets/EffectExamples.meta
Assets/Plugins/
# VS
.vs/
.vscode/
.idea/
obj/
bin/
UserSettings/
*.app

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: f0b370726e57248da97c1c2f3bfd8bdf
guid: 7c9f7735cc2f24a7ca1c23043e63a6be
folderAsset: yes
DefaultImporter:
externalObjects: {}

View File

@@ -0,0 +1,116 @@
using System;
using System.Linq;
using System.Reflection;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using Object = UnityEngine.Object;
namespace Coffee.UIExtensions.Demo
{
public class CFX_Demo_With_UIParticle : MonoBehaviour
{
private MonoBehaviour _demo;
private string _demoType;
private Toggle _spawnOnUI;
private UIParticle _uiParticle;
// Start is called before the first frame update
private void Start()
{
_uiParticle = GetComponentInChildren<UIParticle>();
_spawnOnUI = GetComponentInChildren<Toggle>();
_demo = FindObjectOfType("CFX_Demo_New") as MonoBehaviour
?? FindObjectOfType("WFX_Demo_New") as MonoBehaviour
?? FindObjectOfType("CFXR_Demo") as MonoBehaviour;
_demoType = _demo?.GetType().Name;
SetCanvasWidth(800);
SetCanvasRenderOverlay(true);
}
// Update is called once per frame
private void Update()
{
if (!_spawnOnUI.isOn || !_demo || !Input.GetMouseButtonDown(0)) return;
if (_demoType == "CFX_Demo_New" || _demoType == "WFX_Demo_New")
{
SpawnParticleCFX();
}
else if (_demoType == "CFXR_Demo")
{
SpawnParticleCFXR();
}
}
private void SpawnParticleCFXR()
{
var particle = _demo.GetType()
.GetField("currentEffect", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public)
?.GetValue(_demo) as GameObject;
if (!particle) return;
var instance = Instantiate(particle);
foreach (var c in instance.GetComponentsInChildren<MonoBehaviour>())
{
if (c.GetType().Name == "CFXR_Effect")
{
c.enabled = false;
}
}
_uiParticle.SetParticleSystemInstance(instance, true);
}
private void SpawnParticleCFX()
{
var particle = _demo.GetType()
.GetMethod("spawnParticle", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public)
?.Invoke(_demo, Array.Empty<object>()) as GameObject;
if (!particle) return;
particle.transform.localScale = Vector3.one;
_uiParticle.SetParticleSystemInstance(particle, true);
}
private static Object FindObjectOfType(string typeName)
{
var type = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(x => x.GetTypes())
.FirstOrDefault(x => x.Name == typeName);
return type == null ? null : FindObjectOfType(type);
}
public void SetCanvasWidth(int width)
{
var scaler = GetComponentInParent<CanvasScaler>();
scaler.screenMatchMode = CanvasScaler.ScreenMatchMode.MatchWidthOrHeight;
scaler.matchWidthOrHeight = 0;
var resolution = scaler.referenceResolution;
resolution.x = width;
scaler.referenceResolution = resolution;
}
public void SetCanvasRenderOverlay(bool enable)
{
var canvas = GetComponentInParent<Canvas>();
if (enable)
{
canvas.renderMode = RenderMode.ScreenSpaceOverlay;
}
else
{
canvas.worldCamera = Camera.main;
canvas.renderMode = RenderMode.ScreenSpaceCamera;
canvas.planeDistance = 5;
}
}
public void LoadScene(string scene)
{
SceneManager.LoadScene(scene);
}
}
}

View File

@@ -1,4 +1,4 @@
Cartoon FX & War FX Demo
===
Please import assets "Cartoon FX Free" and/or "War FX Free" from Unity asset store.
Please import assets "Cartoon FX Free" and/or "War FX Free" from Unity asset store.

View File

@@ -0,0 +1,84 @@
using UnityEngine;
using UnityEngine.Serialization;
namespace Coffee.UIExtensions.Demo
{
public class UIParticle_PerformanceDemo : MonoBehaviour
{
[FormerlySerializedAs("copyOrigin")]
[SerializeField]
private GameObject m_CopyOrigin;
[FormerlySerializedAs("copyCount")]
[SerializeField]
public int m_CopyCount;
[FormerlySerializedAs("root")]
[SerializeField]
public Canvas m_RootCanvas;
private void Start()
{
Application.targetFrameRate = 60;
if (m_CopyOrigin)
{
m_CopyOrigin.SetActive(false);
var parent = m_CopyOrigin.transform.parent;
for (var i = 0; i < m_CopyCount; i++)
{
var go = Instantiate(m_CopyOrigin, parent, false);
go.name = string.Format("{0} {1}", m_CopyOrigin.name, i + 1);
go.hideFlags = HideFlags.DontSave;
go.SetActive(true);
}
}
}
public void UIParticle_Enable(bool flag)
{
foreach (var uip in m_RootCanvas.GetComponentsInChildren<UIParticle>(true))
{
uip.enabled = flag;
}
if (!flag)
{
foreach (var ps in FindObjectsOfType<ParticleSystem>())
{
ps.Play(false);
}
}
}
public void UIParticle_MeshSharing(bool flag)
{
foreach (var uip in m_RootCanvas.GetComponentsInChildren<UIParticle>(true))
{
uip.meshSharing = flag
? UIParticle.MeshSharing.Auto
: UIParticle.MeshSharing.None;
}
}
public void UIParticle_RandomGroup(bool flag)
{
foreach (var uip in m_RootCanvas.GetComponentsInChildren<UIParticle>(true))
{
uip.groupMaxId = flag
? 4
: 0;
}
}
public void ParticleSystem_SetScale(float scale)
{
foreach (var ps in FindObjectsOfType<ParticleSystem>())
{
ps.transform.localScale = new Vector3(scale, scale, scale);
}
}
}
}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: c5a6b37697e71473cb1ecc90047622d0
guid: 64db617a76e9a4f1e90d0731175c1f7b
folderAsset: yes
DefaultImporter:
externalObjects: {}

View File

@@ -0,0 +1,33 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 194d2f2eb25c64ec0af5c323c74eb518, type: 3}
m_Name: NanoMonitor
m_EditorClassIdentifier:
m_NanoMonitorEnabled: 1
m_BootSceneNameRegex: .*
m_DevelopmentBuildOnly: 1
m_EnabledInEditor: 1
m_AlwaysIncludeAssembly: 1
m_InstantiateOnLoad: 1
m_Prefab: {fileID: 7211429669315726685, guid: b73940fc30a2f4eb9a73783e9c1f8da6,
type: 3}
m_Opened: 1
m_Interval: 0.5
m_Anchor: 1
m_CustomMonitorItems:
- m_Format: Screen:{0}x{1}
m_Arg0:
m_Path: UnityEngine.Screen, UnityEngine.CoreModule;width
m_Arg1:
m_Path: UnityEngine.Screen, UnityEngine.CoreModule;height
m_Arg2:
m_Path:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 86087a0847f384b538391745dad4565c
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 784696794bc6345bc80bf49623581c2e
guid: b73940fc30a2f4eb9a73783e9c1f8da6
PrefabImporter:
externalObjects: {}
userData:

View File

@@ -0,0 +1,20 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 94e8c16a26d334eafa227ee444387432, type: 3}
m_Name: SimpleSceneNavigator
m_EditorClassIdentifier:
m_NavigatorEnabled: 1
m_EnabledInEditor: 1
m_AlwaysIncludeAssembly: 1
m_InstantiateOnLoad: 1
m_Prefab: {fileID: 7211429669315726685, guid: 46deb9632f6a14713b8460bd01e879c9,
type: 3}

View File

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

View File

@@ -0,0 +1,513 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &3877588430955763108
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 3877588430955763111}
- component: {fileID: 3877588430955763105}
- component: {fileID: 3877588430955763110}
m_Layer: 5
m_Name: Text
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &3877588430955763111
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3877588430955763108}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 3877588431231610297}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &3877588430955763105
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3877588430955763108}
m_CullTransparentMesh: 0
--- !u!114 &3877588430955763110
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3877588430955763108}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
m_RaycastTarget: 1
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_FontData:
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
m_FontSize: 14
m_FontStyle: 0
m_BestFit: 0
m_MinSize: 10
m_MaxSize: 40
m_Alignment: 4
m_AlignByGeometry: 0
m_RichText: 1
m_HorizontalOverflow: 1
m_VerticalOverflow: 1
m_LineSpacing: 1
m_Text: '>>'
--- !u!1 &3877588431231610301
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 3877588431231610297}
- component: {fileID: 3877588431231610302}
- component: {fileID: 3877588431231610303}
- component: {fileID: 3877588431231610300}
m_Layer: 5
m_Name: Button - >>
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &3877588431231610297
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3877588431231610301}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children:
- {fileID: 3877588430955763111}
m_Father: {fileID: 7211429669315725985}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 1, y: 1}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 30, y: 30}
m_Pivot: {x: 1, y: 1}
--- !u!222 &3877588431231610302
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3877588431231610301}
m_CullTransparentMesh: 0
--- !u!114 &3877588431231610303
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3877588431231610301}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0}
m_Type: 1
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1
--- !u!114 &3877588431231610300
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3877588431231610301}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Navigation:
m_Mode: 3
m_SelectOnUp: {fileID: 0}
m_SelectOnDown: {fileID: 0}
m_SelectOnLeft: {fileID: 0}
m_SelectOnRight: {fileID: 0}
m_Transition: 1
m_Colors:
m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
m_ColorMultiplier: 1
m_FadeDuration: 0.1
m_SpriteState:
m_HighlightedSprite: {fileID: 0}
m_PressedSprite: {fileID: 0}
m_SelectedSprite: {fileID: 0}
m_DisabledSprite: {fileID: 0}
m_AnimationTriggers:
m_NormalTrigger: Normal
m_HighlightedTrigger: Highlighted
m_PressedTrigger: Pressed
m_SelectedTrigger: Selected
m_DisabledTrigger: Disabled
m_Interactable: 1
m_TargetGraphic: {fileID: 3877588431231610303}
m_OnClick:
m_PersistentCalls:
m_Calls: []
--- !u!1 &3877588432219069602
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 3877588432219069614}
- component: {fileID: 3877588432219069615}
- component: {fileID: 3877588432219069612}
- component: {fileID: 3877588432219069613}
m_Layer: 5
m_Name: Button - <<
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &3877588432219069614
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3877588432219069602}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children:
- {fileID: 1738594088889562266}
m_Father: {fileID: 7211429669315725985}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 1}
m_AnchorMax: {x: 0, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 30, y: 30}
m_Pivot: {x: 0, y: 1}
--- !u!222 &3877588432219069615
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3877588432219069602}
m_CullTransparentMesh: 0
--- !u!114 &3877588432219069612
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3877588432219069602}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0}
m_Type: 1
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1
--- !u!114 &3877588432219069613
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3877588432219069602}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Navigation:
m_Mode: 3
m_SelectOnUp: {fileID: 0}
m_SelectOnDown: {fileID: 0}
m_SelectOnLeft: {fileID: 0}
m_SelectOnRight: {fileID: 0}
m_Transition: 1
m_Colors:
m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
m_ColorMultiplier: 1
m_FadeDuration: 0.1
m_SpriteState:
m_HighlightedSprite: {fileID: 0}
m_PressedSprite: {fileID: 0}
m_SelectedSprite: {fileID: 0}
m_DisabledSprite: {fileID: 0}
m_AnimationTriggers:
m_NormalTrigger: Normal
m_HighlightedTrigger: Highlighted
m_PressedTrigger: Pressed
m_SelectedTrigger: Selected
m_DisabledTrigger: Disabled
m_Interactable: 1
m_TargetGraphic: {fileID: 3877588432219069612}
m_OnClick:
m_PersistentCalls:
m_Calls: []
--- !u!1 &7211429669315726685
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 7211429669315725985}
- component: {fileID: 7211429669315726686}
- component: {fileID: 7211429669315726687}
- component: {fileID: 7143702096253919615}
- component: {fileID: 3330778306119167604}
m_Layer: 5
m_Name: SimpleSceneNavigator
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &7211429669315725985
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7211429669315726685}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 0, y: 0, z: 0}
m_Children:
- {fileID: 3877588432219069614}
- {fileID: 3877588431231610297}
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0, y: 0}
--- !u!223 &7211429669315726686
Canvas:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7211429669315726685}
m_Enabled: 1
serializedVersion: 3
m_RenderMode: 0
m_Camera: {fileID: 0}
m_PlaneDistance: 100
m_PixelPerfect: 0
m_ReceivesEvents: 1
m_OverrideSorting: 0
m_OverridePixelPerfect: 0
m_SortingBucketNormalizedSize: 0
m_AdditionalShaderChannelsFlag: 0
m_SortingLayerID: 0
m_SortingOrder: 32000
m_TargetDisplay: 0
--- !u!114 &7211429669315726687
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7211429669315726685}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 0cd44c1031e13a943bb63640046fad76, type: 3}
m_Name:
m_EditorClassIdentifier:
m_UiScaleMode: 1
m_ReferencePixelsPerUnit: 100
m_ScaleFactor: 1
m_ReferenceResolution: {x: 600, y: 40}
m_ScreenMatchMode: 0
m_MatchWidthOrHeight: 0
m_PhysicalUnit: 3
m_FallbackScreenDPI: 96
m_DefaultSpriteDPI: 96
m_DynamicPixelsPerUnit: 1
--- !u!114 &7143702096253919615
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7211429669315726685}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: dc42784cf147c0c48a680349fa168899, type: 3}
m_Name:
m_EditorClassIdentifier:
m_IgnoreReversedGraphics: 1
m_BlockingObjects: 0
m_BlockingMask:
serializedVersion: 2
m_Bits: 4294967295
--- !u!114 &3330778306119167604
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7211429669315726685}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: e7db36469bd2a46658ff432d65cb62ca, type: 3}
m_Name:
m_EditorClassIdentifier:
m_PrevButton: {fileID: 3877588432219069613}
m_NextButton: {fileID: 3877588431231610300}
m_PrevName: {fileID: 0}
m_NextName: {fileID: 0}
--- !u!1 &8570858711609111474
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1738594088889562266}
- component: {fileID: 5485386222362727379}
- component: {fileID: 3877588430751452752}
m_Layer: 5
m_Name: Text
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &1738594088889562266
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8570858711609111474}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 3877588432219069614}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &5485386222362727379
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8570858711609111474}
m_CullTransparentMesh: 0
--- !u!114 &3877588430751452752
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8570858711609111474}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
m_RaycastTarget: 1
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_FontData:
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
m_FontSize: 14
m_FontStyle: 0
m_BestFit: 0
m_MinSize: 10
m_MaxSize: 40
m_Alignment: 4
m_AlignByGeometry: 0
m_RichText: 1
m_HorizontalOverflow: 1
m_VerticalOverflow: 1
m_LineSpacing: 1
m_Text: <<

View File

@@ -1,6 +1,6 @@
fileFormatVersion: 2
guid: be075f23fcc314d319e4f4ebfa6eefdd
TextScriptImporter:
guid: 46deb9632f6a14713b8460bd01e879c9
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:

1
Assets/Samples Symbolic link
View File

@@ -0,0 +1 @@
../Packages/src/Samples~

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: b888c253a15224f1fa518bed74028211
guid: 2132c9464acf94912a959f8cc6a68fa6
folderAsset: yes
DefaultImporter:
externalObjects: {}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: fa6e3b593bf274861b2eab47082d9b1e
guid: 57d832714402a4bc5a0ed550741823ad
folderAsset: yes
DefaultImporter:
externalObjects: {}

View File

@@ -1,7 +1,11 @@
{
"name": "Coffee.NanoMonitor",
"references": [],
"optionalUnityReferences": [],
"name": "Coffee.UIParticle.Tests",
"references": [
"Coffee.UIParticle"
],
"optionalUnityReferences": [
"TestAssemblies"
],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 3d6cc132218a845708ce317bd33e5500
guid: 0253956e76ec342d49f1377578eb86be
AssemblyDefinitionImporter:
externalObjects: {}
userData:

8
Assets/Tests/Editor.meta Normal file
View File

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

View File

@@ -0,0 +1,19 @@
{
"name": "Coffee.UIParticle.Editor.Tests",
"references": [
"Coffee.UIParticle",
"Coffee.UIParticle.Editor"
],
"optionalUnityReferences": [
"TestAssemblies"
],
"includePlatforms": [
"Editor"
],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": false,
"defineConstraints": []
}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 78daa55fa55814a33a3377d6ede8c43d
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,26 @@
using System.Collections;
using NUnit.Framework;
using UnityEngine.TestTools;
namespace Coffee.UIParticle.Editor.Tests
{
public class NewTestScript
{
// A Test behaves as an ordinary method
[Test]
public void NewTestScriptSimplePasses()
{
// Use the Assert class to test conditions
}
// A UnityTest behaves like a coroutine in Play Mode. In Edit Mode you can use
// `yield return null;` to skip a frame.
[UnityTest]
public IEnumerator NewTestScriptWithEnumeratorPasses()
{
// Use the Assert class to test conditions.
// Use yield to skip a frame.
yield return null;
}
}
}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 19e83f45e7d5648f2bd10122dc7fed14
guid: 5623180b85e024006b9a6772c3f241c5
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -0,0 +1,26 @@
using System.Collections;
using NUnit.Framework;
using UnityEngine.TestTools;
namespace Coffee.UIParticle.Tests
{
public class NewTestScript
{
// A Test behaves as an ordinary method
[Test]
public void NewTestScriptSimplePasses()
{
// Use the Assert class to test conditions
}
// A UnityTest behaves like a coroutine in Play Mode. In Edit Mode you can use
// `yield return null;` to skip a frame.
[UnityTest]
public IEnumerator NewTestScriptWithEnumeratorPasses()
{
// Use the Assert class to test conditions.
// Use yield to skip a frame.
yield return null;
}
}
}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 5c50c6434f4ad4488bfc5b0928dbb4c4
guid: d52f7d64d782c421284267dd1c197210
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -1,30 +0,0 @@
# Contributing
## How to Contribute
#### Code of Conduct
This repository has adopted the Contributor Covenant as it's
Code of Conduct. It is expected that participants adhere to it.
#### Proposing a Change
If you are unsure about whether or not a change is desired,
you can create an issue. This is useful because it creates
the possibility for a discussion that's visible to everyone.
When fixing a bug it is fine to submit a pull request right away.
#### Sending a Pull Request
Steps to be performed to submit a pull request:
1. Fork the repository and create your branch from `develop`.
2. If you have fixed a bug or added code that should be tested, add tests.
3. Click `Window > Generals > Test Runner` to test
4. Commit with a massage based on [Angular Commit Message Conventions](https://gist.github.com/stephenparish/9941e89d80e2bc58a153).
5. Fill out the description, link any related issues and submit your pull request.
#### License
By contributing to this repository, you agree that your contributions will be licensed under its MIT license.

8
Packages/manifest.json Normal file
View File

@@ -0,0 +1,8 @@
{
"dependencies": {
"com.unity.ide.rider": "3.0.27",
"com.unity.test-framework": "1.1.33",
"com.unity.modules.animation": "1.0.0",
"com.unity.modules.physics": "1.0.0"
}
}

View File

@@ -0,0 +1,85 @@
{
"dependencies": {
"com.coffee.ui-particle": {
"version": "file:src",
"depth": 0,
"source": "embedded",
"dependencies": {
"com.unity.ugui": "1.0.0",
"com.unity.modules.particlesystem": "1.0.0"
}
},
"com.unity.ext.nunit": {
"version": "1.0.6",
"depth": 1,
"source": "registry",
"dependencies": {},
"url": "https://packages.unity.com"
},
"com.unity.ide.rider": {
"version": "3.0.27",
"depth": 0,
"source": "registry",
"dependencies": {
"com.unity.ext.nunit": "1.0.6"
},
"url": "https://packages.unity.com"
},
"com.unity.test-framework": {
"version": "1.1.33",
"depth": 0,
"source": "registry",
"dependencies": {
"com.unity.ext.nunit": "1.0.6",
"com.unity.modules.imgui": "1.0.0",
"com.unity.modules.jsonserialize": "1.0.0"
},
"url": "https://packages.unity.com"
},
"com.unity.ugui": {
"version": "1.0.0",
"depth": 1,
"source": "builtin",
"dependencies": {
"com.unity.modules.ui": "1.0.0",
"com.unity.modules.imgui": "1.0.0"
}
},
"com.unity.modules.animation": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.imgui": {
"version": "1.0.0",
"depth": 1,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.jsonserialize": {
"version": "1.0.0",
"depth": 1,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.particlesystem": {
"version": "1.0.0",
"depth": 1,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.physics": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.ui": {
"version": "1.0.0",
"depth": 2,
"source": "builtin",
"dependencies": {}
}
}
}

View File

@@ -26,9 +26,9 @@ A clear and concise description of what you expected to happen.
If applicable, add screenshots to help explain your problem.
**Environment (please complete the following information):**
- Version [e.g. 1.0.0]
- Version [e.g. 4.0.0]
- Platform: [e.g. Editor(Windows/Mac), Standalone(Windows/Mac), iOS, Android, WebGL]
- Unity version: [e.g. 2018.2.8f1]
- Unity version: [e.g. 2022.3.0f1]
- Build options: [e.g. IL2CPP, .Net 4.x, LWRP]
**Additional context**

View File

@@ -0,0 +1,9 @@
---
name: Pull Request
about: Create a pull request
title: ''
assignees: mob-sakai
---
**NOTE: Create a pull request to merge into `develop` branch**

View File

@@ -1,14 +1,12 @@
{
"branches": [
"+([0-9])?(.{+([0-9]),x}).x",
"master",
"main",
"release",
"release-4.x",
{
"name": "preview",
"name": "release-preview",
"prerelease": true
}
],
"tagFormat": "${version}",
"plugins": [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",

View File

@@ -1,3 +1,251 @@
## [4.7.2](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.7.1...v4.7.2) (2024-06-21)
### Bug Fixes
* generated baking-camera object remains in the prefab or scene ([0bb8438](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/0bb843830197d8c1252232928becc211c0ada08d))
## [4.7.1](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.7.0...v4.7.1) (2024-06-20)
### Bug Fixes
* despite not using the size module, particles become smaller based on their z position ([a8ed6e6](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/a8ed6e68584e1d9e45ed852eefcc03979ea7e0e1)), closes [#316](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/316)
# [4.7.0](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.6.8...v4.7.0) (2024-06-19)
### Bug Fixes
* `UIParticle.transform.localScale` does not scale particles ([1d40e24](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/1d40e24c742741e97f03c55468ccb1e505341133)), closes [#313](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/313)
* UIParticle is scaled by canvas size even when `AutoScalingMode.None` and `ScalingMode.Local` ([54a4b1c](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/54a4b1cdfd06400c7be89c1ee704bb42a659c7c2)), closes [#313](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/313)
* UIParticle is scaled incorrectly with nested canvases ([f26920f](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/f26920f9825547222a4afbb31cc5dc5a002c3e9b)), closes [#313](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/313)
### Features
* reset previous position on start play for world space simulation ([3880484](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/3880484ce5190c42fc79c81d0b69e3fbeda09dd0)), closes [#303](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/303)
* restore `Transform.localScale` when setting `autoScalingMode` to something other than `Transform` ([5505247](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/5505247a94a929ff89635fde512a9b95691e0043))
## [4.6.8](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.6.7...v4.6.8) (2024-06-14)
### Bug Fixes
* 'Resource ID out of range in GetResource' error in overlay rendering mode ([05286ce](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/05286cedfd17b1a0cb90a5e918513644f47cd831)), closes [#308](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/308)
## [4.6.7](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.6.6...v4.6.7) (2024-05-24)
### Bug Fixes
* the ParticleSystem's localPosition drifts at certain scales due to floating-point precision issues ([e924eb4](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/e924eb45968a112347471cabaeabc274e4c37ce4)), closes [#299](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/299) [#312](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/312)
## [4.6.6](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.6.5...v4.6.6) (2024-05-23)
### Bug Fixes
* fix release workflow ([30b0076](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/30b00762f6da166c043587798b1552f27b4cc604))
## [4.6.5](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.6.4...v4.6.5) (2024-05-23)
### Bug Fixes
* update workflows (for preview and v4) ([3eab097](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/3eab0979b9b85919b804442ab05735b7120eade5))
## [4.6.4](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.6.3...v4.6.4) (2024-05-22)
### Bug Fixes
* assertion failed on expression: 'ps->array_size()' ([1b5c359](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/1b5c359058289895caf5f245fe09abb643bc38eb)), closes [#278](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/278)
* lost Material.mainTexture when using AnimatableProperties ([ea04352](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/ea043524c0b00f67cba26a1f9ea537ee4a56d6ff)), closes [#311](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/311)
* remove unnecessary code ([c37c014](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/c37c01486499773e3d7e8296c95bb4c3fae94abb))
## [4.6.3](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.6.2...v4.6.3) (2024-04-04)
### Bug Fixes
* if only Trail Material is used, it will not be displayed ([2eff411](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/2eff411bd97eb4e6947d29a02b85b414bfdaee3a)), closes [#294](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/294)
* if the UIParticle parents do not have Canvas, an exception is thrown in OnEnable ([e82c833](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/e82c833d04b819f103984931ba29a3616ef50908)), closes [#300](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/300)
* particle size too small due to auto scaling ([2ec3748](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/2ec374833614d64406e7c3207ca5fe234a749dcb)), closes [#295](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/295)
## [4.6.2](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.6.1...v4.6.2) (2024-02-01)
### Bug Fixes
* fix compile error in Unity 2021.1 or older ([fcae60b](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/fcae60bf29079bac07463bd3a86f8644151d72ba))
* fix demos ([ad20d12](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/ad20d128a2ad033d9f30b98f0a0dab6091f5aa19))
* fix warning ([7fd4a8e](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/7fd4a8e343ce587dffa9db5ff186061b3ebb38a6))
## [4.6.1](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.6.0...v4.6.1) (2024-01-26)
### Bug Fixes
* unintended scaling occurs when `AutoScalingMode=UIParticle` and `ScalingMode=Local` ([1627de1](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/1627de10eb1e742a015603ae9939071665a5bd89)), closes [#292](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/292)
# [4.6.0](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.5.2...v4.6.0) (2024-01-26)
### Bug Fixes
* fix abnormal mesh bounds error ([772bf50](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/772bf50d168982bd401c30e58172e0a60fbafe46)), closes [#213](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/213)
* fix warning ([93d3919](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/93d3919b6fb6ac186b3e99f8baaef9a044f583f2))
* fix warning ([8a78ec1](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/8a78ec13ad2aad9138a22b67c332871e064a38cc))
### Features
* "[generated]" GameObjects on the hierarchy is disturbing ([7c42421](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/7c4242150b591daf64390588afa27efa27368af3)), closes [#288](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/288)
* add explicit dependencies ([9a0187a](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/9a0187a72a35d378ff7be965bfcb7475f423fe0f))
* add icon ([0c1022c](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/0c1022c6224394713f62b41e5e4ef0c289610ae1))
* remove samples ([f53a7fa](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/f53a7faed3ee73ac22d745a778284e818624b510))
# [4.6.0-preview.1](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.5.2...v4.6.0-preview.1) (2024-01-24)
### Bug Fixes
* fix abnormal mesh bounds error ([772bf50](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/772bf50d168982bd401c30e58172e0a60fbafe46)), closes [#213](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/213)
* fix warning ([93d3919](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/93d3919b6fb6ac186b3e99f8baaef9a044f583f2))
* fix warning ([8a78ec1](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/8a78ec13ad2aad9138a22b67c332871e064a38cc))
### Features
* "[generated]" GameObjects on the hierarchy is disturbing ([7c42421](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/7c4242150b591daf64390588afa27efa27368af3)), closes [#288](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/288)
* add explicit dependencies ([9a0187a](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/9a0187a72a35d378ff7be965bfcb7475f423fe0f))
* add icon ([0c1022c](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/0c1022c6224394713f62b41e5e4ef0c289610ae1))
* remove samples ([f53a7fa](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/f53a7faed3ee73ac22d745a778284e818624b510))
## [4.5.2](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/4.5.1...4.5.2) (2024-01-18)
### Bug Fixes
* (editor) sometimes crashes when entering play mode ([b80c3e6](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/b80c3e6c9fdd2a8fb72ff233edb85df2e3dbba3d))
## [4.5.1](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/4.5.0...4.5.1) (2023-12-23)
### Bug Fixes
* fix material for mesh sharing group ([6126af9](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/6126af9f376dd4c100a1b9d19d9499bdef7d5566))
* the changes made to the material used by the ParticleSystem are not immediately reflected ([3184ba9](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/3184ba94ae08264223c0c71443ad70acc1a1ccb2)), closes [#280](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/280)
# [4.5.0](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/4.4.0...4.5.0) (2023-12-23)
### Bug Fixes
* incorrect rendering of world-space simulated particles while animating scale ([ac58475](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/ac584755393d87bda2e80d9653370b7e4c68912f)), closes [#285](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/285)
* remove obsolete warning ([5d5eb34](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/5d5eb34590b7cefb0e4ac26c0441e104176ce522))
### Features
* Automatically generated objects are no longer editable (NotEditable). ([5607dc4](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/5607dc4eed0c086b4651941953df6c7d535712e0))
* support IMeshModifier ([5c3232f](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/5c3232faf3d2cfad1e3e1a9349b8346c7982a608)), closes [#282](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/282)
# [4.4.0](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/4.3.0...4.4.0) (2023-11-08)
### Features
* support 'Active Apply Color Space' for linear color space ([45c56bb](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/45c56bbd850202365751ea019baf5131b2eb9fbe))
# [4.3.0](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/4.2.2...4.3.0) (2023-11-08)
### Features
* added 'autoScalingMode (None, Transform.localScale, UIParticle.scale)' instead of 'autoScaling' ([107f901](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/107f901fe3232223322681edc4bf908642474298))
* reset transform.localScale on upgrading v3.x to v4.x ([c710787](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/c710787b5ba496cf73e7eb43458bb3958139baa9)), closes [#277](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/277)
## [4.2.2](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/4.2.1...4.2.2) (2023-10-25)
### Bug Fixes
* il2cpp code stripping bug ([73f6dad](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/73f6dad0f33641a76ddd05ffc6812ced3f8a276d)), closes [#269](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/269)
## [4.2.1](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/4.2.0...4.2.1) (2023-08-18)
### Bug Fixes
* autoScaling and PositionMode may be locked ([3f2f12d](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/3f2f12d2cf7541118c02830ec9fdea8183357487))
# [4.2.0](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/4.1.7...4.2.0) (2023-08-18)
### Bug Fixes
* assertion 'ps->array_size()' in UpdateMesh() when using trails of type ribbon ([f75fcce](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/f75fcce0dae0bc166bd01d36a150aded1fd721f3)), closes [#241](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/241)
* built-in shaders are no longer supported ([c2119c1](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/c2119c171a1262431eac7fea6bf3125db2bcaaca)), closes [#233](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/233) [#257](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/257)
* crash occurs when too many vertices are rendered ([723a04d](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/723a04d0cfd156715a3c92b6d6bd75fdc1862c28))
* error: SerializedObject target has been destroyed ([e930516](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/e93051603e121732c92bcd89ded48087c2b0d7fb)), closes [#267](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/267)
* excessive particle emitted on move ParticleSystem for local space simulation and emission over distance ([2fe0bde](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/2fe0bde422f9769dfedaf6b053ea07f773646679)), closes [#265](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/265)
* fix typos ([52f2ef1](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/52f2ef1f2471a2e1c29fca96255c04b222d9c848))
* generated GameObject will be named '[generated] *' ([9b2e5c1](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/9b2e5c1d1024e091de6d18a4578cd18b43563e48))
* inactive ParticleSystems are removed from the list on refresh ([4851a18](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/4851a1880eef9f385dd9db644ea7e544f95da4fc))
* mesh sharing not working ([8b4ca1a](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/8b4ca1add5c409601e840253e1c0dbcdbf536da8)), closes [#236](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/236)
* nullptr exceptions when using nested UIParticle components in hierarchy ([e67e948](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/e67e9482e2cb840b16e2cfe76e04f7423fcbd3a3)), closes [#246](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/246)
* nullReferenceException after copy-n-paste ([425aad0](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/425aad0cbab475635c72bee84ecbf3f2acedccc2)), closes [#258](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/258)
* remove unnecessary per-frame allocation. ([e92b514](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/e92b514624cc362e53ddeae5ade20fa732f94c7c))
* scaling ParticleSystem puts prewarmed particles in wrong location ([fb31db4](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/fb31db47f2debb3aadbdc4d1b88d0efd9c4ad7bd)), closes [#235](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/235)
* sub-emitters option is not work in editor playing ([b308b26](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/b308b2683372662bb834b6f6d23ea3435a68d1b3)), closes [#231](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/231)
* the camera under UIParticle will be assigned as _orthoCamera ([c42f8c8](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/c42f8c8ab0ff033689349a81e02a4808e071a8a2))
* UIParticleAttractor attracts the particles at wrong position when in RelativeMode ([68d9925](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/68d9925a16237df3c7b07b4781172cbd03425421)), closes [#262](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/262)
### Features
* 'AbsoluteMode' option is renamed to 'PositionMode' ([67eff61](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/67eff610736344ba0122163ff5ee63b25c43f555))
* 'AutoScaling' option will be imported from 'IgnoreCanvasScale' (for v3.x) ([4103041](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/410304125f3f25f3f543c7bc01dcc661eab00609))
* add 'AutoScaling' option for UIParticle ([35325c8](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/35325c88996fa6aea19a6dd1395c05884e1f84ae))
* add 'UpdateMode' option for UIParticleAttractor ([903f702](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/903f702d7be38228841a5a693e3afdceb4a59d9f)), closes [#250](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/250)
* add particle system getter and setter for attractor ([a4bcf93](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/a4bcf93022d2729f3d2a74a2cac4f52e68641b18)), closes [#253](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/253)
* add public properties for UIParticleAttractor ([392ab6d](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/392ab6dd76c36e815320d3a50744d19faa631260)), closes [#253](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/253)
* add Start/StopEmission API for UIParticle ([e499836](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/e4998365c9825fa385e0a317768ce073a1f15b48)), closes [#240](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/240)
## [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)
### 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)

View File

@@ -81,4 +81,4 @@ Community Impact Guidelines were inspired by [Mozilla's code of conduct enforcem
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at https://www.contributor-covenant.org/translations.
https://www.contributor-covenant.org/faq. Translations are available at https://www.contributor-covenant.org/translations.

View File

@@ -0,0 +1,43 @@
# Contributing
## How to Contribute
#### Code of Conduct
This repository has adopted the Contributor Covenant as it's
Code of Conduct. It is expected that participants adhere to it.
#### Proposing a Change
If you are unsure about whether or not a change is desired,
you can create an issue. This is useful because it creates
the possibility for a discussion that's visible to everyone.
When fixing a bug it is fine to submit a pull request right away.
#### Sending a Pull Request
Steps to be performed to submit a pull request:
1. Fork the repository.
2. Clone the repository.
3. Checkout `develop` branch.
4. Develop the package.
5. Test the package with the test runner (`Window > Generals > Test Runner`).
6. Commit with a message based
on [Angular Commit Message Conventions](https://gist.github.com/stephenparish/9941e89d80e2bc58a153) as follows:
- `fix:` fix a bug
- `feat:` new feature
- `docs:` changes only in documentation
- `style:` changes only in formatting, white-space, etc
- `refactor:` changes only in code structure (extract method, rename variable, move method, etc)
- `perf:` changes only in code performance
- `test:` add or update tests
- `chore:` changes to the build process or auxiliary tools and libraries such as documentation generation
7. Create a pull request on GitHub. Fill out the description, link any related issues and submit your pull request.
#### License
By contributing to this repository, you agree that your contributions will be licensed under its MIT license.

View File

@@ -0,0 +1,143 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEditor;
using UnityEngine;
namespace Coffee.UIExtensions
{
internal static class AnimatablePropertyEditor
{
private static readonly GUIContent s_ContentNothing = new GUIContent("Nothing");
private static readonly List<string> s_ActiveNames = new List<string>();
private static readonly StringBuilder s_Sb = new StringBuilder();
private static readonly HashSet<string> s_Names = new HashSet<string>();
private static string CollectActiveNames(SerializedProperty sp, List<string> result)
{
result.Clear();
for (var i = 0; i < sp.arraySize; i++)
{
var spName = sp.GetArrayElementAtIndex(i).FindPropertyRelative("m_Name");
if (spName == null) continue;
result.Add(spName.stringValue);
}
s_Sb.Length = 0;
if (result.Count == 0)
{
s_Sb.Append("Nothing");
}
else
{
result.Aggregate(s_Sb, (a, b) => s_Sb.AppendFormat("{0}, ", b));
s_Sb.Length -= 2;
}
return s_Sb.ToString();
}
public static void Draw(SerializedProperty sp, Material[] mats)
{
bool isClicked;
using (new EditorGUILayout.HorizontalScope(GUILayout.ExpandWidth(false)))
{
var pos = EditorGUILayout.GetControlRect(true);
var label = new GUIContent(sp.displayName, sp.tooltip);
var rect = EditorGUI.PrefixLabel(pos, label);
var text = sp.hasMultipleDifferentValues
? "-"
: CollectActiveNames(sp, s_ActiveNames);
isClicked = GUI.Button(rect, text, EditorStyles.popup);
}
if (!isClicked) return;
var gm = new GenericMenu();
gm.AddItem(s_ContentNothing, s_ActiveNames.Count == 0, () =>
{
sp.ClearArray();
sp.serializedObject.ApplyModifiedProperties();
});
if (!sp.hasMultipleDifferentValues)
{
for (var i = 0; i < sp.arraySize; i++)
{
var p = sp.GetArrayElementAtIndex(i);
var name = p.FindPropertyRelative("m_Name").stringValue;
var type = (AnimatableProperty.ShaderPropertyType)p.FindPropertyRelative("m_Type").intValue;
AddMenu(gm, sp, new ShaderProperty(name, type), false);
}
}
s_Names.Clear();
for (var j = 0; j < mats.Length; j++)
{
var mat = mats[j];
if (!mat || !mat.shader) continue;
for (var i = 0; i < ShaderUtil.GetPropertyCount(mat.shader); i++)
{
var name = ShaderUtil.GetPropertyName(mat.shader, i);
var type = (AnimatableProperty.ShaderPropertyType)ShaderUtil.GetPropertyType(mat.shader, i);
if (s_Names.Contains(name)) continue;
s_Names.Add(name);
AddMenu(gm, sp, new ShaderProperty(name, type), true);
if (type != AnimatableProperty.ShaderPropertyType.Texture) continue;
AddMenu(gm, sp, new ShaderProperty($"{name}_ST"), true);
AddMenu(gm, sp, new ShaderProperty($"{name}_HDR"), true);
AddMenu(gm, sp, new ShaderProperty($"{name}_TexelSize"), true);
}
}
gm.ShowAsContext();
}
private static void AddMenu(GenericMenu menu, SerializedProperty sp, ShaderProperty prop, bool add)
{
if (add && s_ActiveNames.Contains(prop.name)) return;
var label = new GUIContent($"{prop.name} ({prop.type})");
menu.AddItem(label, s_ActiveNames.Contains(prop.name), () =>
{
var index = s_ActiveNames.IndexOf(prop.name);
if (0 <= index)
{
sp.DeleteArrayElementAtIndex(index);
}
else
{
sp.InsertArrayElementAtIndex(sp.arraySize);
var p = sp.GetArrayElementAtIndex(sp.arraySize - 1);
p.FindPropertyRelative("m_Name").stringValue = prop.name;
p.FindPropertyRelative("m_Type").intValue = (int)prop.type;
}
sp.serializedObject.ApplyModifiedProperties();
});
}
private struct ShaderProperty
{
public readonly string name;
public readonly AnimatableProperty.ShaderPropertyType type;
public ShaderProperty(string name)
{
this.name = name;
type = AnimatableProperty.ShaderPropertyType.Vector;
}
public ShaderProperty(string name, AnimatableProperty.ShaderPropertyType type)
{
this.name = name;
this.type = type;
}
}
}
}

View File

@@ -1,18 +1,23 @@
#if UNITY_2019_3_11 || UNITY_2019_3_12 || UNITY_2019_3_13 || UNITY_2019_3_14 || UNITY_2019_3_15 || UNITY_2019_4_OR_NEWER
#define SERIALIZE_FIELD_MASKABLE
#endif
using UnityEditor;
using UnityEditor.UI;
using UnityEngine;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using UnityEditor;
using UnityEditor.UI;
using UnityEditorInternal;
using UnityEngine;
using UnityEngine.UI;
using System;
using Coffee.UIParticleExtensions;
#if UNITY_2021_2_OR_NEWER
using UnityEditor.Overlays;
#else
using System;
using System.Reflection;
using Object = UnityEngine.Object;
#endif
#if UNITY_2021_2_OR_NEWER
using UnityEditor.SceneManagement;
#elif UNITY_2018_3_OR_NEWER
using UnityEditor.Experimental.SceneManagement;
#endif
namespace Coffee.UIExtensions
@@ -23,7 +28,10 @@ namespace Coffee.UIExtensions
{
#if UNITY_2021_2_OR_NEWER
#if UNITY_2022_1_OR_NEWER
[Overlay(typeof(SceneView), "Scene View/UI Particles", "UI Particles", true, defaultDockPosition = DockPosition.Bottom, defaultDockZone = DockZone.Floating, defaultLayout = Layout.Panel)]
[Overlay(typeof(SceneView), "Scene View/UI Particles", "UI Particles", true,
defaultDockPosition = DockPosition.Bottom,
defaultDockZone = DockZone.Floating,
defaultLayout = Layout.Panel)]
#else
[Overlay(typeof(SceneView), "Scene View/UI Particles", "UI Particles", true)]
#endif
@@ -35,7 +43,7 @@ namespace Coffee.UIExtensions
{
if (visible)
{
WindowFunction(null, null);
WindowFunction();
}
}
}
@@ -53,24 +61,23 @@ namespace Coffee.UIExtensions
private static readonly GUIContent s_ContentRandom = new GUIContent("Random");
private static readonly GUIContent s_ContentScale = new GUIContent("Scale");
private static SerializedObject s_SerializedObject;
private static bool s_XYZMode;
#if !SERIALIZE_FIELD_MASKABLE
private SerializedProperty m_Maskable;
#endif
private SerializedProperty m_Scale3D;
private SerializedProperty m_AnimatableProperties;
private SerializedProperty m_MeshSharing;
private SerializedProperty m_GroupId;
private SerializedProperty m_GroupMaxId;
private SerializedProperty m_AbsoluteMode;
private SerializedProperty _maskable;
private SerializedProperty _scale3D;
private SerializedProperty _animatableProperties;
private SerializedProperty _meshSharing;
private SerializedProperty _groupId;
private SerializedProperty _groupMaxId;
private SerializedProperty _positionMode;
private SerializedProperty _autoScalingMode;
private ReorderableList _ro;
static private bool _xyzMode;
private bool _showMax;
private static readonly HashSet<Shader> s_Shaders = new HashSet<Shader>();
#if UNITY_2018 || UNITY_2019
private static readonly List<ParticleSystemVertexStream> s_Streams = new List<ParticleSystemVertexStream>();
#endif
private static readonly List<string> s_MaskablePropertyNames = new List<string>
{
"_Stencil",
@@ -78,21 +85,20 @@ namespace Coffee.UIExtensions
"_StencilOp",
"_StencilWriteMask",
"_StencilReadMask",
"_ColorMask",
"_ColorMask"
};
[InitializeOnLoadMethod]
static void Init()
private static void Init()
{
#if !UNITY_2021_2_OR_NEWER
var miSceneViewOverlayWindow = Type.GetType("UnityEditor.SceneViewOverlay, UnityEditor")
.GetMethods(BindingFlags.Public | BindingFlags.Static)
?.GetMethods(BindingFlags.Public | BindingFlags.Static)
.First(x => x.Name == "Window" && 5 <= x.GetParameters().Length);
var windowFunction = (Action<UnityEngine.Object, SceneView>)WindowFunction;
var windowFunction = (Action<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));
var windowTitle = new GUIContent(ObjectNames.NicifyVariableName(nameof(UIParticle)));
#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 };
@@ -102,7 +108,7 @@ namespace Coffee.UIExtensions
#endif
#if UNITY_2019_1_OR_NEWER
SceneView.duringSceneGui += _ => miSceneViewOverlayWindow.Invoke(null, sceneViewArgs);
SceneView.duringSceneGui += _ =>
#else
SceneView.onSceneGUIDelegate += _ =>
#endif
@@ -114,25 +120,22 @@ namespace Coffee.UIExtensions
};
#endif
Func<SerializedObject> createSerializeObject = () =>
SerializedObject CreateSerializeObject()
{
var uiParticles = Selection.gameObjects
.Select(x => x.GetComponent<ParticleSystem>())
.Where(x => x)
.Select(x => x.GetComponentInParent<UIParticle>())
.Where(x => x)
.Concat(
Selection.gameObjects
.Select(x => x.GetComponent<UIParticle>())
.Where(x => x)
)
.Distinct()
.ToArray();
return uiParticles.Any() ? new SerializedObject(uiParticles) : null;
};
var uiParticles = Selection.gameObjects.Select(x => x.GetComponent<ParticleSystem>())
.Where(x => x)
.Select(x => x.GetComponentInParent<UIParticle>(true))
.Where(x => x && x.canvas)
.Concat(Selection.gameObjects.Select(x => x.GetComponent<UIParticle>())
.Where(x => x && x.canvas))
.Distinct()
.OfType<Object>()
.ToArray();
return 0 < uiParticles.Length ? new SerializedObject(uiParticles) : null;
}
s_SerializedObject = createSerializeObject();
Selection.selectionChanged += () => s_SerializedObject = createSerializeObject();
s_SerializedObject = CreateSerializeObject();
Selection.selectionChanged += () => s_SerializedObject = CreateSerializeObject();
}
//################################
@@ -145,69 +148,71 @@ namespace Coffee.UIExtensions
{
base.OnEnable();
m_Maskable = serializedObject.FindProperty("m_Maskable");
m_Scale3D = serializedObject.FindProperty("m_Scale3D");
m_AnimatableProperties = serializedObject.FindProperty("m_AnimatableProperties");
m_MeshSharing = serializedObject.FindProperty("m_MeshSharing");
m_GroupId = serializedObject.FindProperty("m_GroupId");
m_GroupMaxId = serializedObject.FindProperty("m_GroupMaxId");
m_AbsoluteMode = serializedObject.FindProperty("m_AbsoluteMode");
_maskable = serializedObject.FindProperty("m_Maskable");
_scale3D = serializedObject.FindProperty("m_Scale3D");
_animatableProperties = serializedObject.FindProperty("m_AnimatableProperties");
_meshSharing = serializedObject.FindProperty("m_MeshSharing");
_groupId = serializedObject.FindProperty("m_GroupId");
_groupMaxId = serializedObject.FindProperty("m_GroupMaxId");
_positionMode = serializedObject.FindProperty("m_PositionMode");
_autoScalingMode = serializedObject.FindProperty("m_AutoScalingMode");
var sp = serializedObject.FindProperty("m_Particles");
_ro = new ReorderableList(sp.serializedObject, sp, true, true, true, true);
_ro.elementHeight = EditorGUIUtility.singleLineHeight * 3 + 4;
_ro.elementHeightCallback = _ => 3 * (EditorGUIUtility.singleLineHeight + 2);
_ro.drawElementCallback = (rect, index, active, focused) =>
_ro = new ReorderableList(sp.serializedObject, sp, true, true, true, true)
{
EditorGUI.BeginDisabledGroup(sp.hasMultipleDifferentValues);
rect.y += 1;
rect.height = EditorGUIUtility.singleLineHeight;
var p = sp.GetArrayElementAtIndex(index);
EditorGUI.ObjectField(rect, p, GUIContent.none);
rect.x += 15;
rect.width -= 15;
var ps = p.objectReferenceValue as ParticleSystem;
var materials = ps
? new SerializedObject(ps.GetComponent<ParticleSystemRenderer>()).FindProperty("m_Materials")
: null;
rect.y += rect.height + 1;
MaterialField(rect, s_ContentMaterial, materials, 0);
rect.y += rect.height + 1;
MaterialField(rect, s_ContentTrailMaterial, materials, 1);
EditorGUI.EndDisabledGroup();
if (materials != null)
elementHeight = EditorGUIUtility.singleLineHeight * 3 + 4,
elementHeightCallback = _ => 3 * (EditorGUIUtility.singleLineHeight + 2),
drawElementCallback = (rect, index, _, __) =>
{
materials.serializedObject.ApplyModifiedProperties();
}
};
_ro.drawHeaderCallback = rect =>
{
#if !UNITY_2019_3_OR_NEWER
rect.y -= 1;
#endif
EditorGUI.LabelField(new Rect(rect.x, rect.y, 150, rect.height), s_ContentRenderingOrder);
if (GUI.Button(new Rect(rect.width - 35, rect.y, 60, rect.height), s_ContentRefresh, EditorStyles.miniButton))
{
foreach (UIParticle t in targets)
EditorGUI.BeginDisabledGroup(sp.hasMultipleDifferentValues);
rect.y += 1;
rect.height = EditorGUIUtility.singleLineHeight;
var p = sp.GetArrayElementAtIndex(index);
EditorGUI.ObjectField(rect, p, GUIContent.none);
rect.x += 15;
rect.width -= 15;
var ps = p.objectReferenceValue as ParticleSystem;
var materials = ps
? new SerializedObject(ps.GetComponent<ParticleSystemRenderer>()).FindProperty("m_Materials")
: null;
rect.y += rect.height + 1;
MaterialField(rect, s_ContentMaterial, materials, 0);
rect.y += rect.height + 1;
MaterialField(rect, s_ContentTrailMaterial, materials, 1);
EditorGUI.EndDisabledGroup();
if (materials != null && materials.serializedObject.hasModifiedProperties)
{
t.RefreshParticles();
materials.serializedObject.ApplyModifiedProperties();
}
}
};
_ro.onReorderCallback = _ =>
{
foreach (UIParticle t in targets)
},
drawHeaderCallback = rect =>
{
t.RefreshParticles(t.particles);
#if !UNITY_2019_3_OR_NEWER
rect.y -= 1;
#endif
var pos = new Rect(rect.x, rect.y, 150, rect.height);
EditorGUI.LabelField(pos, s_ContentRenderingOrder);
pos = new Rect(rect.width - 35, rect.y, 60, rect.height);
if (GUI.Button(pos, s_ContentRefresh, EditorStyles.miniButton))
{
foreach (var uip in targets.OfType<UIParticle>())
{
uip.RefreshParticles();
EditorUtility.SetDirty(uip);
}
}
}
};
// On select UIParticle, refresh particles.
foreach (UIParticle t in targets)
if (!Application.isPlaying)
{
if (Application.isPlaying || PrefabUtility.GetPrefabAssetType(t) != PrefabAssetType.NotAPrefab) continue;
t.RefreshParticles(t.particles);
foreach (var uip in targets.OfType<UIParticle>())
{
if (PrefabUtility.GetPrefabAssetType(uip) != PrefabAssetType.NotAPrefab) continue;
uip.RefreshParticles(uip.particles);
}
}
}
@@ -231,16 +236,16 @@ namespace Coffee.UIExtensions
public override void OnInspectorGUI()
{
var current = target as UIParticle;
if (current == null) return;
if (!current) return;
serializedObject.Update();
// Maskable
EditorGUILayout.PropertyField(m_Maskable);
EditorGUILayout.PropertyField(_maskable);
// Scale
EditorGUI.BeginDisabledGroup(!m_MeshSharing.hasMultipleDifferentValues && m_MeshSharing.intValue == 4);
_xyzMode = DrawFloatOrVector3Field(m_Scale3D, _xyzMode);
EditorGUI.BeginDisabledGroup(!_meshSharing.hasMultipleDifferentValues && _meshSharing.intValue == 4);
s_XYZMode = DrawFloatOrVector3Field(_scale3D, s_XYZMode);
EditorGUI.EndDisabledGroup();
// AnimatableProperties
@@ -250,12 +255,11 @@ namespace Coffee.UIExtensions
.Where(x => x)
.ToArray();
// Animated properties
AnimatedPropertiesEditor.DrawAnimatableProperties(m_AnimatableProperties, mats);
AnimatablePropertyEditor.Draw(_animatableProperties, mats);
// Mesh sharing
EditorGUI.BeginChangeCheck();
_showMax = DrawMeshSharing(m_MeshSharing, m_GroupId, m_GroupMaxId, _showMax);
_showMax = DrawMeshSharing(_meshSharing, _groupId, _groupMaxId, _showMax);
if (EditorGUI.EndChangeCheck())
{
serializedObject.ApplyModifiedProperties();
@@ -265,16 +269,42 @@ namespace Coffee.UIExtensions
}
}
// Absolute Mode
EditorGUILayout.PropertyField(m_AbsoluteMode);
// Position Mode
EditorGUILayout.PropertyField(_positionMode);
// Auto Scaling
DrawAutoScaling(_autoScalingMode, targets.OfType<UIParticle>());
// 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);
}
}
// Non-UI built-in shader is not supported.
foreach (var mat in current.materials)
{
if (!mat || !mat.shader) continue;
var shader = mat.shader;
if (IsBuiltInObject(shader) && !shader.name.StartsWith("UI/"))
{
EditorGUILayout.HelpBox(
$"Built-in shader '{shader.name}' in '{mat.name}' is not supported.\n" +
"Use UI shaders instead.",
MessageType.Error);
}
}
// Does the shader support UI masks?
if (current.maskable && current.GetComponentInParent<Mask>())
if (current.maskable && current.GetComponentInParent<Mask>(false))
{
foreach (var mat in current.materials)
{
@@ -286,21 +316,28 @@ namespace Coffee.UIExtensions
{
if (mat.HasProperty(propName)) continue;
EditorGUILayout.HelpBox(string.Format("Shader '{0}' doesn't have '{1}' property. This graphic cannot be masked.", shader.name, propName), MessageType.Warning);
EditorGUILayout.HelpBox(
$"Shader '{shader.name}' doesn't have '{propName}' property." +
"\nThis graphic cannot be masked.",
MessageType.Warning);
break;
}
}
}
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."))
var label = "This UIParticle component should be removed. The UIParticle for trails is no longer needed.";
#pragma warning disable CS0612
if (FixButton(current.m_IsTrail, label))
#pragma warning restore CS0612
{
DestroyUIParticle(current);
}
// #203: When using linear color space, the particle colors are not output correctly.
// To fix, set 'Apply Active Color Space' in renderer module to false.
#if UNITY_2018 || UNITY_2019
// (2018, 2019) Check to use 'TEXCOORD*.zw' components as custom vertex stream.
var allPsRenderers = targets.OfType<UIParticle>()
.SelectMany(x => x.particles)
.Where(x => x)
@@ -308,29 +345,34 @@ namespace Coffee.UIExtensions
.ToArray();
if (0 < allPsRenderers.Length)
{
var so = new SerializedObject(allPsRenderers);
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 == false) continue;
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);
EditorGUILayout.HelpBox(
$"ParticleSystem '{psr.name}' uses 'TEXCOORD*.zw' components as custom vertex stream.\n" +
"UIParticle does not support it (See README.md).",
MessageType.Warning);
}
s_Streams.Clear();
}
}
#endif
}
private bool IsBuiltInObject(Object obj)
{
return AssetDatabase.TryGetGUIDAndLocalFileIdentifier(obj, out var guid, out long _)
&& Regex.IsMatch(guid, "^0{16}.0{15}$", RegexOptions.Compiled);
}
#if UNITY_2018 || UNITY_2019
private static int GetUsedComponentCount(ParticleSystemVertexStream s)
{
switch (s)
@@ -386,10 +428,13 @@ namespace Coffee.UIExtensions
case ParticleSystemVertexStream.Custom2XYZW:
return 4;
}
return 3;
}
#endif
private static bool DrawMeshSharing(SerializedProperty spMeshSharing, SerializedProperty spGroupId, SerializedProperty spGroupMaxId, bool showMax)
private static bool DrawMeshSharing(SerializedProperty spMeshSharing, SerializedProperty spGroupId,
SerializedProperty spGroupMaxId, bool showMax)
{
showMax |= spGroupId.intValue != spGroupMaxId.intValue ||
spGroupId.hasMultipleDifferentValues ||
@@ -401,7 +446,10 @@ namespace Coffee.UIExtensions
EditorGUI.BeginChangeCheck();
showMax = GUILayout.Toggle(showMax, s_ContentRandom, EditorStyles.miniButton, GUILayout.Width(60));
if (EditorGUI.EndChangeCheck() && !showMax)
{
spGroupMaxId.intValue = spGroupId.intValue;
}
EditorGUILayout.EndHorizontal();
EditorGUI.BeginDisabledGroup(spMeshSharing.intValue == 0);
@@ -414,57 +462,70 @@ namespace Coffee.UIExtensions
else if (spMeshSharing.intValue == 1 || spMeshSharing.intValue == 4)
{
EditorGUI.BeginDisabledGroup(true);
EditorGUILayout.ObjectField("Primary", UIParticleUpdater.GetPrimary(spGroupId.intValue), typeof(UIParticle), false);
var obj = UIParticleUpdater.GetPrimary(spGroupId.intValue);
EditorGUILayout.ObjectField("Primary", obj, typeof(UIParticle), false);
EditorGUI.EndDisabledGroup();
}
EditorGUI.indentLevel--;
EditorGUI.EndDisabledGroup();
return showMax;
}
private static void WindowFunction(UnityEngine.Object target, SceneView sceneView)
private static void DrawAutoScaling(SerializedProperty prop, IEnumerable<UIParticle> uiParticles)
{
EditorGUILayout.PropertyField(prop);
}
#if UNITY_2021_2_OR_NEWER
private static void WindowFunction()
#else
private static void WindowFunction(Object _, SceneView __)
#endif
{
try
{
if (s_SerializedObject.targetObjects.Any(x => !x)) return;
if (s_SerializedObject == null || !s_SerializedObject.targetObject) return;
var uiParticles = s_SerializedObject.targetObjects.OfType<UIParticle>().ToArray();
if (uiParticles.Any(x => !x || !x.canvas)) return;
s_SerializedObject.Update();
using (new EditorGUILayout.VerticalScope(GUILayout.Width(220f)))
{
var labelWidth = EditorGUIUtility.labelWidth;
EditorGUIUtility.labelWidth = 100;
_xyzMode = DrawFloatOrVector3Field(s_SerializedObject.FindProperty("m_Scale3D"), _xyzMode);
EditorGUILayout.PropertyField(s_SerializedObject.FindProperty("m_AbsoluteMode"));
EditorGUILayout.PropertyField(s_SerializedObject.FindProperty("m_Enabled"));
s_XYZMode = DrawFloatOrVector3Field(s_SerializedObject.FindProperty("m_Scale3D"), s_XYZMode);
EditorGUILayout.PropertyField(s_SerializedObject.FindProperty("m_PositionMode"));
DrawAutoScaling(s_SerializedObject.FindProperty("m_AutoScalingMode"), uiParticles);
EditorGUIUtility.labelWidth = labelWidth;
}
s_SerializedObject.ApplyModifiedProperties();
}
catch
{
// ignored
}
}
private void DestroyUIParticle(UIParticle p, bool ignoreCurrent = false)
{
if (!p || ignoreCurrent && target == p) return;
if (!p || (ignoreCurrent && target == p)) return;
var cr = p.canvasRenderer;
DestroyImmediate(p);
DestroyImmediate(cr);
#if UNITY_2021_2_OR_NEWER
var stage = UnityEditor.SceneManagement.PrefabStageUtility.GetCurrentPrefabStage();
#elif UNITY_2018_3_OR_NEWER
var stage = UnityEditor.Experimental.SceneManagement.PrefabStageUtility.GetCurrentPrefabStage();
#endif
#if UNITY_2018_3_OR_NEWER
var stage = PrefabStageUtility.GetCurrentPrefabStage();
if (stage != null && stage.scene.isLoaded)
{
#if UNITY_2020_1_OR_NEWER
string prefabAssetPath = stage.assetPath;
var prefabAssetPath = stage.assetPath;
#else
string prefabAssetPath = stage.prefabAssetPath;
var prefabAssetPath = stage.prefabAssetPath;
#endif
PrefabUtility.SaveAsPrefabAsset(stage.prefabContentsRoot, prefabAssetPath);
}
@@ -513,7 +574,10 @@ namespace Coffee.UIExtensions
EditorGUI.BeginChangeCheck();
showXyz = GUILayout.Toggle(showXyz, s_Content3D, EditorStyles.miniButton, GUILayout.Width(30));
if (EditorGUI.EndChangeCheck() && !showXyz)
{
z.floatValue = y.floatValue = x.floatValue;
}
EditorGUILayout.EndHorizontal();
return showXyz;

View File

@@ -34,10 +34,10 @@ namespace Coffee.UIExtensions
ps.transform.SetParent(uiParticle.transform, false);
ps.transform.localPosition = Vector3.zero;
// Assign default material.
// Assign default material (UIAdditive).
var renderer = ps.GetComponent<ParticleSystemRenderer>();
var defaultMat = AssetDatabase.GetBuiltinExtraResource<Material>("Default-Particle.mat");
renderer.material = defaultMat ? defaultMat : renderer.material;
var path = AssetDatabase.GUIDToAssetPath("9944483a3e009401ba5dcc42f14d5c63");
renderer.material = AssetDatabase.LoadAssetAtPath<Material>(path);
// Refresh particles.
uiParticle.RefreshParticles();

8
Packages/src/Icons.meta Normal file
View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 418 B

View File

@@ -0,0 +1,127 @@
fileFormatVersion: 2
guid: 5f0675613942149309588d556e33d990
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 12
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 0
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 2
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 64
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Server
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,7 +1,7 @@
Copyright 2018-2022 mob-sakai
Copyright 2018-2024 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:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

483
Packages/src/README.md Normal file
View File

@@ -0,0 +1,483 @@
# Particle Effect For UGUI (UI Particle)
This package provides a component to render particle effects for uGUI in Unity 2018.2 or later.
The particle rendering is maskable and sortable, without the need for an extra Camera, RenderTexture, or Canvas.
[![](https://img.shields.io/npm/v/com.coffee.ui-particle?label=openupm&registry_uri=https://package.openupm.com)](https://openupm.com/packages/com.coffee.ui-particle/)
[![](https://img.shields.io/github/v/release/mob-sakai/ParticleEffectForUGUI?include_prereleases)](https://github.com/mob-sakai/ParticleEffectForUGUI/releases)
[![](https://img.shields.io/github/license/mob-sakai/ParticleEffectForUGUI.svg)](https://github.com/mob-sakai/ParticleEffectForUGUI/blob/main/LICENSE.txt)
![](https://img.shields.io/badge/Unity-2018.2+-57b9d3.svg?style=flat&logo=unity)
![](https://github.com/mob-sakai/ParticleEffectForUGUI/actions/workflows/test.yml/badge.svg?branch=develop)
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-orange.svg)](http://makeapullrequest.com)
[![](https://img.shields.io/twitter/follow/mob_sakai.svg?label=Follow&style=social)](https://twitter.com/intent/follow?screen_name=mob_sakai)
<< [📝 Description](#-description) | [🎮 Demo](#-demo) | [⚙ Installation](#-installation) | [🚀 Usage](#-usage) | [🛠 Development Note](#-development-note) | [🤝 Contributing](#-contributing) >>
<br><br>
## 📝 Description
![](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
CanvasRenderer.
You can render, mask, and sort your ParticleSystems for UI without the necessity of an additional Camera, RenderTexture,
or Canvas.
### Features
* Easy to use: The package is ready to use out of the box.
* Sort particle effects and other UI by sibling index.
* No extra Camera, RenderTexture, or Canvas required.
* Masking options for Mask or RectMask2D.
* Support for the Trail module.
* Support for CanvasGroup alpha.
* No allocations needed to render particles.
* Compatibility with overlay, camera space, and world space.
* Support for Universal Render Pipeline (URP) and High Definition Render Pipeline (HDRP).
* Support for disabling `Enter Play Mode Options > Reload Domain`.
* Support for changing material property with AnimationClip (AnimatableProperty).
![AnimatableProperty.gif][AnimatableProperty.gif]
* [4.0.0+] Support for 8+ materials.
* [4.0.0+] Correct world space particle position adjustment when changing window size for standalone platforms (Windows,
MacOSX, and Linux).
* [4.0.0+] Adaptive scaling for UI.
* [4.0.0+] Mesh sharing group to improve performance.
![MeshSharing.gif][MeshSharing.gif]
* [4.0.0+] Particle attractor component.
![ParticleAttractor.gif][ParticleAttractor.gif]
* [4.1.0+] Relative/Absolute particle position mode.
![AbsolutePosition.gif][AbsolutePosition.gif]
[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>
## 🎮 Demo
* [WebGL Demo](https://mob-sakai.github.io/demos/UIParticle_Demo/index.html)
> ![](https://user-images.githubusercontent.com/12690315/174311768-1843a5f2-f776-491b-aaa8-2a131a8b6a16.gif)
* [WebGL Demo (Cartoon FX & War FX)](https://mob-sakai.github.io/Demos/ParticleEffectForUGUI_CFX)
* [Cartoon FX Free][CFX] & [War FX][WFX] (by [Jean Moreno (JMO)][JMO]) with UIParticle
> ![](https://user-images.githubusercontent.com/12690315/91664766-3e07ac00-eb2c-11ea-978b-ef723be80619.gif)
[CFX]: https://assetstore.unity.com/packages/vfx/particles/cartoon-fx-free-109565
[WFX]: https://assetstore.unity.com/packages/vfx/particles/war-fx-5669
[JMO]: https://assetstore.unity.com/publishers/1669
<br><br>
## ⚙ Installation
_This package requires Unity 2018.3 or later._
#### Install via OpenUPM
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.
If you have [openupm-cli](https://github.com/openupm/openupm-cli) installed, then run the following command in your
project's directory:
```sh
openupm add com.coffee.ui-particle
```
#### Install via UPM (using Git URL)
Navigate to your project's Packages folder and open the `manifest.json` file. Then add this package somewhere in
the `dependencies` block:
```json
{
"dependencies": {
"com.coffee.ui-particle": "https://github.com/mob-sakai/ParticleEffectForUGUI.git",
...
}
}
```
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.6.0",`
Or, use [UpmGitExtension](https://github.com/mob-sakai/UpmGitExtension) to install and update the package.
<br><br>
## 🚀 Usage
### UIParticle Component
`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)
- **Maskable**: Does this graphic allow masking.
- **Scale**: Scale the rendering. 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,
use this to mark the changes.
- **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.
- **Position Mode**: Emission position mode.
- **Absolute:** Emit from the world position of the `ParticleSystem`.
- **Relative:** Emit from the scaled position of the `ParticleSystem`.
- **Auto Scaling**: `Transform.lossyScale` (=world scale) will be set to `(1, 1, 1)` on update. It prevents the
root-Canvas scale from affecting the hierarchy-scaled `ParticleSystem`.
- **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
and z-position.
<br><br>
#### Basic Usage
1. Select `GameObject/UI/ParticleSystem` to create UIParticle with a ParticleSystem.
![particle](https://user-images.githubusercontent.com/12690315/95007361-cad0e880-0649-11eb-8835-f145d62c5977.png)
2. Adjust the ParticleSystem as you like.
![particle1](https://user-images.githubusercontent.com/12690315/95007359-ca385200-0649-11eb-8383-627c9750bda8.png)
<br>
#### With Your Existing ParticleSystem Prefab
1. Select `GameObject/UI/ParticleSystem (Empty)` to create UIParticle.
![empty](https://user-images.githubusercontent.com/12690315/95007362-cb697f00-0649-11eb-8a09-29b0a13791e4.png)
2. Drag and drop your ParticleSystem prefab onto UIParticle.
![particle3](https://user-images.githubusercontent.com/12690315/95007356-c6a4cb00-0649-11eb-9316-562f4bce3f31.png)
<br>
#### With `Mask` or `RectMask2D` Component
If you want to mask particles, set a stencil-supported shader (such as `UI/UIAdditive`) to the material for
ParticleSystem.
If you use some custom shaders, see
the [How to Make a Custom Shader to Support Mask/RectMask2D Component](#how-to-make-a-custom-shader-to-support-maskrectmask2d-component)
section.
![](https://user-images.githubusercontent.com/12690315/95017591-3b512700-0695-11eb-864e-04166ea1809a.png)
<br><br>
### Script usage
```cs
// Instant ParticleSystem prefab with UIParticle on runtime.
var go = GameObject.Instantiate(prefab);
var uiParticle = go.AddComponent<UIParticle>();
// Control by ParticleSystem.
particleSystem.Play();
particleSystem.Emit(10);
// Control by UIParticle.
uiParticle.Play();
uiParticle.Stop();
```
<br><br>
### UIParticleAttractor component
`UIParticleAttractor` attracts particles generated by the specified ParticleSystem.
![](https://github.com/mob-sakai/ParticleEffectForUGUI/assets/12690315/ea6ae0ed-f9a8-437c-8baa-47526303391e)
![](https://user-images.githubusercontent.com/12690315/174311027-462929a4-13f0-4ec4-86ea-9c832f2eecf1.gif)
- **Particle System**: Attracts particles generated by the specified particle system.
- **Destination Radius**: Once the particle is within the radius, the particle lifetime will become 0, and `OnAttracted`
will be called.
- **Delay Rate**: Delay to start attracting. It is a percentage of the particle's start lifetime.
- **Max Speed**: Maximum speed of attracting. If this value is too small, attracting may not be completed by the end of
the lifetime, and `OnAttracted` may not be called.
- **Movement**: Attracting movement type. (`Linear`, `Smooth`, `Sphere`)
- **Update Mode**: Update mode.
- **Normal:** Update with scaled delta time.
- **Unscaled Time:** Update with unscaled delta time.
- **OnAttracted**: An event called when attracting is complete (per particle).
<br><br>
## 🛠 Development Note
### Compares the Baking mesh approach with the conventional approach
- **Baking mesh approach (=UIParticle)**
![](https://user-images.githubusercontent.com/12690315/41765089-0302b9a2-763e-11e8-88b3-b6ffa306bbb0.gif)
- ✅ Rendered as is.
- ✅ Maskable.
- ✅ Sortable.
- ✅ Less objects.
- **Do nothing (=Plain ParticleSystem)**
![](https://user-images.githubusercontent.com/12690315/41765090-0329828a-763e-11e8-8d8a-f1d269ea3bc7.gif)
- ✅ Rendered as is.
- ❌ Looks like a glitch.
- ❌ Not maskable.
- ❌ Not sortable.
- **Convert particle to UIVertex (=[UIParticleSystem][UIParticleSystem])**
![](https://user-images.githubusercontent.com/12690315/41765088-02deb9c6-763e-11e8-98d0-9e0c1766ef39.gif)
- ✅ Maskable.
- ✅ Sortable.
- ❌ Adjustment is difficult.
- ❌ Requires UI shaders.
- ❌ Difficult to adjust scale.
- ❌ Force hierarchy scalling.
- ❌ Simulation results are incorrect.
- ❌ Trail, rotation of transform, time scaling are not supported.
- ❌ Generate heavy GC every frame.
- **Use Canvas to sort (Sorting By Canvas )**
![](https://user-images.githubusercontent.com/12690315/41765087-02b866ea-763e-11e8-8c33-081c9ad852f8.gif)
- ✅ Rendered as is.
- ✅ Sortable.
- ❌ You must to manage sorting orders.
- ❌ Not maskable.
- ❌ More batches.
- ❌ Requires Canvas.
- **Use RenderTexture**
![](https://user-images.githubusercontent.com/12690315/41765085-0291b3e2-763e-11e8-827b-72e5ee9bc556.gif)
- ✅ Maskable.
- ✅ Sortable.
- ❌ Requires Camera and RenderTexture.
- ❌ Difficult to adjust position and size.
- ❌ Quality depends on the RenderTexture's setting.
[UIParticleSystem]: https://forum.unity.com/threads/free-script-particle-systems-in-ui-screen-space-overlay.406862/
#### [Performance test results](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/193#issuecomment-1160028374)
| 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 |
### 🔍 FAQ: Why Are My UIParticles Not Displayed Correctly?
If `ParticleSystem` alone displays particles correctly but `UIParticle` does not, please check the following points:
- [Shader Limitation](#shader-limitation)
- `UIParticle` does not support all built-in shaders except for `UI/Default`.
- Most cases can be solved by using `UI/Additive` or `UI/Default`.
- Particles are not masked
- `UIParticle` is maskable.
- Set `Mask` or `RectMask2D` component properly.
- [Use maskable/clipable shader](#how-to-make-a-custom-shader-to-support-maskrectmask2d-component) (such
as `UI/Additive` or `UI/Default`)
- Particles are too small
- If particles are small enough, they will not appear on the screen.
- Increase the `Scale` value.
- If you don't want to change the apparent size depending on the resolution, try the `Auto Scaling` option.
- Particles are too many
- No more than 65535 vertices can be displayed (for mesh combination limitations).
- Please set `Emission` module and `Max Particles` of ParticleSystem properly.
- Particles are emitted off-screen.
- When `Position Mode = Relative`, particles are emitted from the scaled position of the ParticleSystem, not from
the screen point of the ParticleSystem.
- Place the ParticleSystem in the proper position or try `Position Mode = Absolute`.
- Attaching `UIParticle` to the same object as `ParticleSystem`
- `Transform.localScale` will be overridden by the `Auto Scaling` option.
- It is recommended to place `ParticleSystem` under `UIParticle`.
- If `Transform.localScale` contains 0, rendering will be skipped.
- Displayed particles are in the correct position but too large/too small
- Adjust `ParticleSystem.renderer.Min/MaxParticleSize`.
<br>
### Shader Limitation
The use of UI shaders is recommended.
- If you need a simple Additive shader, use the `UI/Additive` shader instead.
- If you need a simple alpha-blend shader, use the `UI/Default` shader instead.
- If your custom shader does not work properly with UIParticle, consider creating a custom UI shader.
#### Built-in shaders are not supported
`UIParticle` does not support all built-in shaders except for `UI/Default`.
If their use is detected, an error is displayed in the inspector.
Use UI shaders instead.
#### (Unity 2018 or 2019) UV.zw components will be discarded
UIParticleRenderer renders the particles based on UIVertex.
Therefore, only the xy components are available for each UV in the shader. (zw components will be discarded).
So unfortunately, UIParticles will not work well with some shaders.
#### (Unity 2018 or 2019) Custom vertex streams
When using custom vertex streams, you can fill zw components with "unnecessary" data.
Refer to [this issue](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/191) for more information.
<br>
### Overheads
UIParticle has some overheads, and the batching depends on uGUI.
When improving performance, keep the following in mind:
- If you are displaying a large number of the same effect, consider the `Mesh Sharing` feature in
the [UIParticle Component](#uiparticle-component).
- If you don't like the uniform output, consider the `Random Group` feature.
![](https://user-images.githubusercontent.com/12690315/174311048-c882df81-6c34-4eba-b0aa-5645457692f1.gif)
- If you are using multiple materials, you will have more draw calls.
- Consider a single material, atlasing the sprites, and using `Sprite` mode in the `Texture Sheet Animation` module
in the 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>
## 🤝 Contributing
### Issues
Issues are incredibly valuable to this project:
- Ideas provide a valuable source of contributions that others can make.
- Problems help identify areas where this project needs improvement.
- Questions indicate where contributors can enhance the user experience.
### Pull Requests
Pull requests offer a fantastic way to contribute your ideas to this repository.
Please refer to [CONTRIBUTING.md](https://github.com/mob-sakai/ParticleEffectForUGUI/blob/main/CONTRIBUTING.md)
and [develop branch](https://github.com/mob-sakai/ParticleEffectForUGUI/tree/develop) for guidelines.
### Support
This is an open-source project developed during my spare time.
If you appreciate it, consider supporting me.
Your support allows me to dedicate more time to development. 😊
[![](https://user-images.githubusercontent.com/12690315/50731629-3b18b480-11ad-11e9-8fad-4b13f27969c1.png)](https://www.patreon.com/join/2343451?)
[![](https://user-images.githubusercontent.com/12690315/66942881-03686280-f085-11e9-9586-fc0b6011029f.png)](https://github.com/users/mob-sakai/sponsorship)
<br><br>
## License
* MIT
## Author
* ![](https://user-images.githubusercontent.com/12690315/96986908-434a0b80-155d-11eb-8275-85138ab90afa.png) [mob-sakai](https://github.com/mob-sakai) [![](https://img.shields.io/twitter/follow/mob_sakai.svg?label=Follow&style=social)](https://twitter.com/intent/follow?screen_name=mob_sakai) ![GitHub followers](https://img.shields.io/github/followers/mob-sakai?style=social)
## See Also
* GitHub page : https://github.com/mob-sakai/ParticleEffectForUGUI
* Releases : https://github.com/mob-sakai/ParticleEffectForUGUI/releases
* Issue tracker : https://github.com/mob-sakai/ParticleEffectForUGUI/issues
* Change log : https://github.com/mob-sakai/ParticleEffectForUGUI/blob/main/CHANGELOG.md

View File

@@ -1,8 +1,9 @@
using UnityEngine;
using System;
using UnityEngine;
namespace Coffee.UIExtensions
{
[System.Serializable]
[Serializable]
public class AnimatableProperty : ISerializationCallbackReceiver
{
public enum ShaderPropertyType
@@ -11,16 +12,22 @@ namespace Coffee.UIExtensions
Vector,
Float,
Range,
Texture,
Texture
}
[SerializeField] string m_Name = "";
[SerializeField] ShaderPropertyType m_Type = ShaderPropertyType.Vector;
[SerializeField] private string m_Name = "";
[SerializeField] private ShaderPropertyType m_Type = ShaderPropertyType.Vector;
public int id { get; private set; }
public ShaderPropertyType type
public ShaderPropertyType type => m_Type;
void ISerializationCallbackReceiver.OnBeforeSerialize()
{
get { return m_Type; }
}
void ISerializationCallbackReceiver.OnAfterDeserialize()
{
id = Shader.PropertyToID(m_Name);
}
public void UpdateMaterialProperties(Material material, MaterialPropertyBlock mpb)
@@ -31,35 +38,38 @@ namespace Coffee.UIExtensions
{
case ShaderPropertyType.Color:
var color = mpb.GetColor(id);
if (color != default(Color))
if (color != default)
{
material.SetColor(id, color);
}
break;
case ShaderPropertyType.Vector:
var vector = mpb.GetVector(id);
if (vector != default(Vector4))
if (vector != default)
{
material.SetVector(id, vector);
}
break;
case ShaderPropertyType.Float:
case ShaderPropertyType.Range:
var value = mpb.GetFloat(id);
if (value != default(float))
if (!Mathf.Approximately(value, 0))
{
material.SetFloat(id, value);
}
break;
case ShaderPropertyType.Texture:
var tex = mpb.GetTexture(id);
if (tex != default(Texture))
{
material.SetTexture(id, tex);
}
break;
}
}
public void OnBeforeSerialize()
{
}
public void OnAfterDeserialize()
{
id = Shader.PropertyToID(m_Name);
}
}
}

View File

@@ -1,4 +1,4 @@
using System.Collections.Generic;
using System.Collections.Generic;
using UnityEngine;
namespace Coffee.UIParticleExtensions
@@ -7,26 +7,31 @@ namespace Coffee.UIParticleExtensions
{
private static readonly List<MatEntry> s_Entries = new List<MatEntry>();
public static Material Add(Material baseMat, Texture texture, int id)
public static Material Add(Material baseMat, Texture texture, int id, int props)
{
MatEntry e;
for (var i = 0; i < s_Entries.Count; ++i)
for (var i = 0; i < s_Entries.Count; i++)
{
e = s_Entries[i];
if (e.baseMat != baseMat || e.texture != texture || e.id != id) continue;
if (e.baseMat != baseMat || e.texture != texture || e.id != id || e.props != props) continue;
++e.count;
return e.customMat;
}
e = new MatEntry();
e.count = 1;
e.baseMat = baseMat;
e.texture = texture;
e.id = id;
e.customMat = new Material(baseMat);
e.customMat.hideFlags = HideFlags.HideAndDontSave;
if (texture)
e.customMat.mainTexture = texture;
e = new MatEntry
{
count = 1,
baseMat = baseMat,
texture = texture,
id = id,
props = props,
customMat = new Material(baseMat)
{
name = $"{baseMat.name}_{id}",
hideFlags = HideFlags.DontSave | HideFlags.NotEditable,
mainTexture = texture ? texture : baseMat.mainTexture
}
};
s_Entries.Add(e);
//Debug.LogFormat(">>>> ModifiedMaterial.Add -> count = count:{0}, mat:{1}, tex:{2}, id:{3}", s_Entries.Count, baseMat, texture, id);
return e.customMat;
@@ -43,7 +48,8 @@ namespace Coffee.UIParticleExtensions
if (--e.count == 0)
{
//Debug.LogFormat(">>>> ModifiedMaterial.Remove -> count:{0}, mat:{1}, tex:{2}, id:{3}", s_Entries.Count - 1, e.customMat, e.texture, e.id);
DestroyImmediate(e.customMat);
Misc.DestroyImmediate(e.customMat);
e.customMat = null;
e.baseMat = null;
e.texture = null;
s_Entries.RemoveAt(i);
@@ -53,22 +59,14 @@ namespace Coffee.UIParticleExtensions
}
}
private static void DestroyImmediate(Object obj)
{
if (!obj) return;
if (Application.isEditor)
Object.DestroyImmediate(obj);
else
Object.Destroy(obj);
}
private class MatEntry
{
public Material baseMat;
public Material customMat;
public int count;
public Texture texture;
public Material customMat;
public int id;
public int props;
public Texture texture;
}
}
}

View File

@@ -0,0 +1,626 @@
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using Coffee.UIParticleExtensions;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Serialization;
using UnityEngine.UI;
using Random = UnityEngine.Random;
[assembly: InternalsVisibleTo("Coffee.UIParticle.Editor")]
namespace Coffee.UIExtensions
{
/// <summary>
/// Render maskable and sortable particle effect ,without Camera, RenderTexture or Canvas.
/// </summary>
[ExecuteAlways]
[RequireComponent(typeof(RectTransform))]
[RequireComponent(typeof(CanvasRenderer))]
public class UIParticle : MaskableGraphic, ISerializationCallbackReceiver
{
public enum AutoScalingMode
{
None,
UIParticle,
Transform
}
public enum MeshSharing
{
None,
Auto,
Primary,
PrimarySimulator,
Replica
}
public enum PositionMode
{
Relative,
Absolute
}
[HideInInspector]
[SerializeField]
internal bool m_IsTrail;
[HideInInspector]
[FormerlySerializedAs("m_IgnoreParent")]
[SerializeField]
private bool m_IgnoreCanvasScaler;
[HideInInspector]
[SerializeField]
private bool m_AbsoluteMode;
[Tooltip("Particle effect scale")]
[SerializeField]
private Vector3 m_Scale3D = new Vector3(10, 10, 10);
[Tooltip("Animatable material properties.\n" +
"If you want to change the material properties of the ParticleSystem in Animation, enable it.")]
[SerializeField]
internal AnimatableProperty[] m_AnimatableProperties = new AnimatableProperty[0];
[Tooltip("Particles")]
[SerializeField]
private List<ParticleSystem> m_Particles = new List<ParticleSystem>();
[Tooltip("Mesh sharing.\n" +
"None: disable mesh sharing.\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" +
"Replica: render simulation results provided by the primary.")]
[SerializeField]
private MeshSharing m_MeshSharing = MeshSharing.None;
[Tooltip("Mesh sharing group ID.\n" +
"If non-zero is specified, particle simulation results are shared within the group.")]
[SerializeField]
private int m_GroupId;
[SerializeField]
private int m_GroupMaxId;
[Tooltip("Relative: The particles will be emitted from the scaled position of ParticleSystem.\n" +
"Absolute: The particles will be emitted from the world position of ParticleSystem.")]
[SerializeField]
private PositionMode m_PositionMode = PositionMode.Relative;
[SerializeField]
[Tooltip("Prevent the root-Canvas scale from affecting the hierarchy-scaled ParticleSystem.")]
private bool m_AutoScaling = true;
[SerializeField]
[Tooltip("Transform: Transform.lossyScale (=world scale) will be set to (1, 1, 1)." +
"UIParticle: UIParticle.scale will be adjusted.")]
private AutoScalingMode m_AutoScalingMode = AutoScalingMode.Transform;
private readonly List<UIParticleRenderer> _renderers = new List<UIParticleRenderer>();
private int _groupId;
private Camera _bakeCamera;
private DrivenRectTransformTracker _tracker;
private Vector3 _storedScale;
private bool _isScaleStored;
/// <summary>
/// Should this graphic be considered a target for ray-casting?
/// </summary>
public override bool raycastTarget
{
get => false;
set { }
}
/// <summary>
/// Mesh sharing.
/// 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.
/// </summary>
public MeshSharing meshSharing
{
get => m_MeshSharing;
set => m_MeshSharing = value;
}
/// <summary>
/// Mesh sharing group ID.
/// If non-zero is specified, particle simulation results are shared within the group.
/// </summary>
public int groupId
{
get => _groupId;
set
{
if (m_GroupId == value) return;
m_GroupId = value;
if (m_GroupId != m_GroupMaxId)
{
ResetGroupId();
}
}
}
public int groupMaxId
{
get => m_GroupMaxId;
set
{
if (m_GroupMaxId == value) return;
m_GroupMaxId = value;
ResetGroupId();
}
}
/// <summary>
/// Particle position mode.
/// 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.
/// </summary>
public PositionMode positionMode
{
get => m_PositionMode;
set => m_PositionMode = value;
}
/// <summary>
/// Particle position mode.
/// 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.
/// </summary>
public bool absoluteMode
{
get => m_PositionMode == PositionMode.Absolute;
set => positionMode = value ? PositionMode.Absolute : PositionMode.Relative;
}
/// <summary>
/// Prevents the root-Canvas scale from affecting the hierarchy-scaled ParticleSystem.
/// </summary>
[Obsolete("The autoScaling is now obsolete. Please use the autoScalingMode instead.", false)]
public bool autoScaling
{
get => m_AutoScalingMode != AutoScalingMode.None;
set => autoScalingMode = value ? AutoScalingMode.Transform : AutoScalingMode.None;
}
/// <summary>
/// Auto scaling mode.
/// Transform: Transform.lossyScale (=world scale) will be set to (1, 1, 1).
/// UIParticle: UIParticle.scale will be adjusted.
/// </summary>
public AutoScalingMode autoScalingMode
{
get => m_AutoScalingMode;
set
{
if (m_AutoScalingMode == value) return;
m_AutoScalingMode = value;
if (autoScalingMode != AutoScalingMode.Transform && _isScaleStored)
{
transform.localScale = _storedScale;
_isScaleStored = false;
}
}
}
internal bool useMeshSharing => m_MeshSharing != MeshSharing.None;
internal bool isPrimary =>
m_MeshSharing == MeshSharing.Primary
|| m_MeshSharing == MeshSharing.PrimarySimulator;
internal bool canSimulate =>
m_MeshSharing == MeshSharing.None
|| m_MeshSharing == MeshSharing.Auto
|| m_MeshSharing == MeshSharing.Primary
|| m_MeshSharing == MeshSharing.PrimarySimulator;
internal bool canRender =>
m_MeshSharing == MeshSharing.None
|| m_MeshSharing == MeshSharing.Auto
|| m_MeshSharing == MeshSharing.Primary
|| m_MeshSharing == MeshSharing.Replica;
/// <summary>
/// Particle effect scale.
/// </summary>
public float scale
{
get => m_Scale3D.x;
set => m_Scale3D = new Vector3(value, value, value);
}
/// <summary>
/// Particle effect scale.
/// </summary>
public Vector3 scale3D
{
get => m_Scale3D;
set => m_Scale3D = value;
}
/// <summary>
/// Particle effect scale.
/// </summary>
public Vector3 scale3DForCalc => autoScalingMode == AutoScalingMode.Transform
? m_Scale3D
: m_Scale3D.GetScaled(canvasScale, transform.localScale);
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;
}
}
}
public override Material materialForRendering => null;
/// <summary>
/// Paused.
/// </summary>
public bool isPaused { get; private set; }
public Vector3 parentScale { get; private set; }
public Vector3 canvasScale { get; private set; }
protected override void OnEnable()
{
_isScaleStored = false;
ResetGroupId();
UIParticleUpdater.Register(this);
RegisterDirtyMaterialCallback(UpdateRendererMaterial);
if (0 < particles.Count)
{
RefreshParticles(particles);
}
else
{
RefreshParticles();
}
base.OnEnable();
}
/// <summary>
/// This function is called when the behaviour becomes disabled.
/// </summary>
protected override void OnDisable()
{
_tracker.Clear();
if (autoScalingMode == AutoScalingMode.Transform && _isScaleStored)
{
transform.localScale = _storedScale;
}
_isScaleStored = false;
UIParticleUpdater.Unregister(this);
_renderers.ForEach(r => r.Reset());
UnregisterDirtyMaterialCallback(UpdateRendererMaterial);
base.OnDisable();
}
/// <summary>
/// Callback for when properties have been changed by animation.
/// </summary>
protected override void OnDidApplyAnimationProperties()
{
}
void ISerializationCallbackReceiver.OnBeforeSerialize()
{
}
void ISerializationCallbackReceiver.OnAfterDeserialize()
{
if (m_IgnoreCanvasScaler || m_AutoScaling)
{
m_IgnoreCanvasScaler = false;
m_AutoScaling = false;
m_AutoScalingMode = AutoScalingMode.Transform;
}
if (m_AbsoluteMode)
{
m_AbsoluteMode = false;
m_PositionMode = PositionMode.Absolute;
}
}
public void Play()
{
particles.Exec(p => p.Simulate(0, false, true));
isPaused = false;
}
public void Pause()
{
particles.Exec(p => p.Pause());
isPaused = true;
}
public void Resume()
{
isPaused = false;
}
public void Stop()
{
particles.Exec(p => p.Stop());
isPaused = true;
}
public void StartEmission()
{
particles.Exec(p =>
{
var emission = p.emission;
emission.enabled = true;
});
}
public void StopEmission()
{
particles.Exec(p =>
{
var emission = p.emission;
emission.enabled = false;
});
}
public void Clear()
{
particles.Exec(p => p.Clear());
isPaused = true;
}
public void SetParticleSystemInstance(GameObject instance)
{
SetParticleSystemInstance(instance, true);
}
public void SetParticleSystemInstance(GameObject instance, bool destroyOldParticles)
{
if (!instance) return;
foreach (Transform child in transform)
{
var go = child.gameObject;
go.SetActive(false);
if (destroyOldParticles)
{
Misc.Destroy(go);
}
}
var tr = instance.transform;
tr.SetParent(transform, false);
tr.localPosition = Vector3.zero;
RefreshParticles(instance);
}
public void SetParticleSystemPrefab(GameObject prefab)
{
if (!prefab) return;
SetParticleSystemInstance(Instantiate(prefab.gameObject), true);
}
public void RefreshParticles()
{
RefreshParticles(gameObject);
}
private void RefreshParticles(GameObject root)
{
if (!root) return;
root.GetComponentsInChildren(true, particles);
particles.RemoveAll(x => x.GetComponentInParent<UIParticle>(true) != this);
for (var i = 0; i < particles.Count; i++)
{
var ps = particles[i];
var tsa = ps.textureSheetAnimation;
if (tsa.mode == ParticleSystemAnimationMode.Sprites && tsa.uvChannelMask == 0)
{
tsa.uvChannelMask = UVChannelFlags.UV0;
}
}
RefreshParticles(particles);
}
public void RefreshParticles(List<ParticleSystem> particles)
{
// #246: Nullptr exceptions when using nested UIParticle components in hierarchy
_renderers.Clear();
foreach (Transform child in transform)
{
var uiParticleRenderer = child.GetComponent<UIParticleRenderer>();
if (uiParticleRenderer != null)
{
_renderers.Add(uiParticleRenderer);
}
}
for (var i = 0; i < _renderers.Count; i++)
{
_renderers[i].Reset(i);
}
var j = 0;
for (var i = 0; i < particles.Count; i++)
{
var ps = particles[i];
if (!ps) continue;
GetRenderer(j++).Set(this, ps, false);
if (ps.trails.enabled)
{
GetRenderer(j++).Set(this, ps, true);
}
}
}
internal void UpdateTransformScale()
{
_tracker.Clear();
canvasScale = canvas.rootCanvas.transform.localScale.Inverse();
parentScale = transform.parent.lossyScale;
if (autoScalingMode != AutoScalingMode.Transform)
{
if (_isScaleStored)
{
transform.localScale = _storedScale;
}
_isScaleStored = false;
return;
}
var currentScale = transform.localScale;
_storedScale = currentScale;
_isScaleStored = true;
_tracker.Add(this, rectTransform, DrivenTransformProperties.Scale);
var newScale = parentScale.Inverse();
if (currentScale != newScale)
{
transform.localScale = newScale;
}
}
internal void UpdateRenderers()
{
if (!isActiveAndEnabled) return;
for (var i = 0; i < _renderers.Count; i++)
{
var r = _renderers[i];
if (!r)
{
RefreshParticles(particles);
break;
}
}
var bakeCamera = GetBakeCamera();
for (var i = 0; i < _renderers.Count; i++)
{
var r = _renderers[i];
if (!r) continue;
r.UpdateMesh(bakeCamera);
}
}
internal void ResetGroupId()
{
_groupId = m_GroupId == m_GroupMaxId
? m_GroupId
: Random.Range(m_GroupId, m_GroupMaxId + 1);
}
protected override void UpdateMaterial()
{
}
/// <summary>
/// Call to update the geometry of the Graphic onto the CanvasRenderer.
/// </summary>
protected override void UpdateGeometry()
{
}
private void UpdateRendererMaterial()
{
for (var i = 0; i < _renderers.Count; i++)
{
var r = _renderers[i];
if (!r) continue;
r.maskable = maskable;
r.SetMaterialDirty();
}
}
internal UIParticleRenderer GetRenderer(int index)
{
if (_renderers.Count <= index)
{
_renderers.Add(UIParticleRenderer.AddRenderer(this, index));
}
if (!_renderers[index])
{
_renderers[index] = UIParticleRenderer.AddRenderer(this, index);
}
return _renderers[index];
}
private Camera GetBakeCamera()
{
if (!canvas) return Camera.main;
if (_bakeCamera) return _bakeCamera;
// Find existing baking camera.
var childCount = transform.childCount;
for (var i = 0; i < childCount; i++)
{
if (transform.GetChild(i).TryGetComponent<Camera>(out var cam)
&& cam.name == "[generated] UIParticle BakingCamera")
{
_bakeCamera = cam;
break;
}
}
// Create baking camera.
if (!_bakeCamera)
{
var go = new GameObject("[generated] UIParticle BakingCamera")
{
hideFlags = HideFlags.HideAndDontSave
};
go.SetActive(false);
go.transform.SetParent(transform, false);
_bakeCamera = go.AddComponent<Camera>();
}
// Setup baking camera.
_bakeCamera.enabled = false;
_bakeCamera.orthographicSize = 1000;
_bakeCamera.transform.SetPositionAndRotation(new Vector3(0, 0, -1000), Quaternion.identity);
_bakeCamera.orthographic = true;
_bakeCamera.farClipPlane = 2000f;
_bakeCamera.clearFlags = CameraClearFlags.Nothing;
_bakeCamera.cullingMask = 0; // Nothing
_bakeCamera.allowHDR = false;
_bakeCamera.allowMSAA = false;
_bakeCamera.renderingPath = RenderingPath.Forward;
_bakeCamera.useOcclusionCulling = false;
return _bakeCamera;
}
}
}

View File

@@ -5,7 +5,7 @@ MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
icon: {fileID: 2800000, guid: 5f0675613942149309588d556e33d990, type: 3}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,7 +1,7 @@
using UnityEngine;
using Coffee.UIParticleExtensions;
using UnityEngine.Events;
using System;
using Coffee.UIParticleExtensions;
using UnityEngine;
using UnityEngine.Events;
namespace Coffee.UIExtensions
{
@@ -12,7 +12,13 @@ namespace Coffee.UIExtensions
{
Linear,
Smooth,
Sphere,
Sphere
}
public enum UpdateMode
{
Normal,
UnscaledTime
}
[SerializeField]
@@ -24,7 +30,7 @@ namespace Coffee.UIExtensions
[Range(0f, 0.95f)]
[SerializeField]
private float m_DelayRate = 0;
private float m_DelayRate;
[Range(0.001f, 100f)]
[SerializeField]
@@ -33,70 +39,84 @@ namespace Coffee.UIExtensions
[SerializeField]
private Movement m_Movement;
[SerializeField]
private UpdateMode m_UpdateMode;
[SerializeField]
private UnityEvent m_OnAttracted;
private UIParticle _uiParticle;
public float destinationRadius
{
get => m_DestinationRadius;
set => m_DestinationRadius = Mathf.Clamp(value, 0.1f, 10f);
}
public float delay
{
get
{
return m_DelayRate;
}
set
{
m_DelayRate = value;
}
get => m_DelayRate;
set => m_DelayRate = value;
}
public float maxSpeed
{
get
{
return m_MaxSpeed;
}
set
{
m_MaxSpeed = value;
}
get => m_MaxSpeed;
set => m_MaxSpeed = value;
}
public Movement movement
{
get
{
return m_Movement;
}
get => m_Movement;
set => m_Movement = value;
}
public UpdateMode updateMode
{
get => m_UpdateMode;
set => m_UpdateMode = value;
}
public UnityEvent onAttracted
{
get => m_OnAttracted;
set => m_OnAttracted = value;
}
/// <summary>
/// The target ParticleSystem to attract.
/// </summary>
#if UNITY_EDITOR
public new ParticleSystem particleSystem
#else
public ParticleSystem particleSystem
#endif
{
get => m_ParticleSystem;
set
{
m_Movement = value;
m_ParticleSystem = value;
ApplyParticleSystem();
}
}
private UIParticle _uiParticle;
private void OnEnable()
{
if (m_ParticleSystem == null)
{
Debug.LogError("No particle system attached to particle attractor script", this);
enabled = false;
return;
}
_uiParticle = m_ParticleSystem.GetComponentInParent<UIParticle>();
if (_uiParticle && !_uiParticle.particles.Contains(m_ParticleSystem))
{
_uiParticle = null;
}
ApplyParticleSystem();
UIParticleUpdater.Register(this);
}
private void OnDisable()
{
_uiParticle = null;
UIParticleUpdater.Unregister(this);
}
private void OnDestroy()
{
_uiParticle = null;
m_ParticleSystem = null;
}
internal void Attract()
{
if (m_ParticleSystem == null) return;
@@ -128,6 +148,7 @@ namespace Coffee.UIExtensions
Debug.LogException(e);
}
}
continue;
}
@@ -154,36 +175,52 @@ namespace Coffee.UIExtensions
var psPos = m_ParticleSystem.transform.position;
var attractorPos = transform.position;
var dstPos = attractorPos;
if (m_ParticleSystem.main.simulationSpace == ParticleSystemSimulationSpace.Local)
var isLocalSpace = m_ParticleSystem.IsLocalSpace();
if (isLocalSpace)
{
dstPos = m_ParticleSystem.transform.InverseTransformPoint(dstPos);
if (isUI)
{
dstPos = dstPos.GetScaled(_uiParticle.transform.localScale, _uiParticle.scale3D.Inverse());
}
}
else
if (isUI)
{
#if UNITY_EDITOR
if (!Application.isPlaying && isUI)
var inverseScale = _uiParticle.parentScale.Inverse();
var scale3d = _uiParticle.scale3DForCalc;
dstPos = dstPos.GetScaled(inverseScale, scale3d.Inverse());
// Relative mode
if (_uiParticle.positionMode == UIParticle.PositionMode.Relative)
{
var diff = dstPos - psPos;
diff = diff.GetScaled(_uiParticle.transform.localScale, _uiParticle.scale3D.Inverse());
return psPos + diff;
var diff = _uiParticle.transform.position - psPos;
diff.Scale(scale3d - inverseScale);
diff.Scale(scale3d.Inverse());
dstPos += diff;
}
#if UNITY_EDITOR
if (!Application.isPlaying && !isLocalSpace)
{
dstPos += psPos - psPos.GetScaled(inverseScale, scale3d.Inverse());
}
#endif
if (isUI)
{
dstPos.Scale(_uiParticle.transform.localScale);
dstPos.Scale(_uiParticle.scale3D.Inverse());
}
}
return dstPos;
}
private Vector3 GetAttractedPosition(Vector3 current, Vector3 target, float duration, float time)
{
var speed = m_MaxSpeed;
switch (m_UpdateMode)
{
case UpdateMode.Normal:
speed *= 60 * Time.deltaTime;
break;
case UpdateMode.UnscaledTime:
speed *= 60 * Time.unscaledDeltaTime;
break;
}
switch (m_Movement)
{
case Movement.Linear:
@@ -200,5 +237,26 @@ namespace Coffee.UIExtensions
return Vector3.MoveTowards(current, target, speed);
}
private void ApplyParticleSystem()
{
_uiParticle = null;
if (m_ParticleSystem == null)
{
#if UNITY_EDITOR
if (Application.isPlaying)
#endif
{
Debug.LogError("No particle system attached to particle attractor script", this);
}
return;
}
_uiParticle = m_ParticleSystem.GetComponentInParent<UIParticle>(true);
if (_uiParticle && !_uiParticle.particles.Contains(m_ParticleSystem))
{
_uiParticle = null;
}
}
}
}
}

Some files were not shown because too many files have changed in this diff Show More