Compare commits

..

54 Commits

Author SHA1 Message Date
mob-sakai
67c7e816a7 fix: when using mesh sharing, the Transform.scale of the primary UIParticle affects the replicas.
close #333

NOTE: This fix may cause changes in the rendering of existing UIParticles.
2024-09-26 18:15:42 +09:00
semantic-release-bot
109caed657 chore(release): 4.9.1 [skip ci]
## [4.9.1](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.9.0...v4.9.1) (2024-08-07)

### Bug Fixes

* ParticleSystem trails gain offset on parent canvas change ([2a1cd50](2a1cd502b4)), closes [#323](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/323)
2024-08-07 17:13:07 +00:00
mob-sakai
2a1cd502b4 fix: ParticleSystem trails gain offset on parent canvas change
close #323
2024-08-08 02:00:40 +09:00
mob-sakai
78d0219235 update demo 2024-07-18 14:56:49 +09:00
semantic-release-bot
de5c617d12 chore(release): 4.9.0 [skip ci]
# [4.9.0](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.8.1...v4.9.0) (2024-07-18)

### Features

* ParticleAttractor supports multiple ParticleSystems ([3834780](3834780fdb))
2024-07-18 05:09:44 +00:00
mob-sakai
15f9d92567 demos: update demo 2024-07-18 13:40:58 +09:00
mob-sakai
55fb8a0076 demos: webgl setting 2024-07-18 12:53:36 +09:00
mob-sakai
e6d8e43966 docs: update readme 2024-07-18 09:33:42 +09:00
mob-sakai
10a7fb4b7b refactor: refactor multiple attractor
- Convert 'm_ParticleSystem' to 'm_ParticleSystems'
- Collect parent UIParticles on attract
- Improve performance
2024-07-18 00:56:13 +09:00
dogramacigokhan
3834780fdb feat: ParticleAttractor supports multiple ParticleSystems 2024-07-18 00:56:13 +09:00
semantic-release-bot
307ed1bf01 chore(release): 4.8.1 [skip ci]
## [4.8.1](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.8.0...v4.8.1) (2024-06-27)

### Bug Fixes

* remove debug code ([669deb4](669deb41d4))
2024-06-27 09:27:20 +00:00
mob-sakai
669deb41d4 fix: remove debug code 2024-06-27 18:26:47 +09:00
semantic-release-bot
24e0e8697d chore(release): 4.8.0 [skip ci]
# [4.8.0](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.7.2...v4.8.0) (2024-06-27)

### Bug Fixes

* generated baking-camera object remains in the prefab or scene (again) ([de35cba](de35cba34c))
* SetParticleSystemInstance/Prefab APIs destroy generated objects ([ae3f3a8](ae3f3a8e62))

### Features

* add 'custom view' option. ([a703c29](a703c2921c))
* remove overlay window (editor) ([8358170](835817049f))
* restore `Transform.localScale` when setting `autoScalingMode` to something other than `Transform` (again) ([88a970d](88a970d93a))
* the rendering order list in inspector is now more compact ([be90172](be901724e0))
2024-06-27 06:40:30 +00:00
mob-sakai
3e3e35beca test scene for custom view size 2024-06-27 15:34:17 +09:00
mob-sakai
a182709472 refactor 2024-06-27 14:12:53 +09:00
mob-sakai
be901724e0 feat: the rendering order list in inspector is now more compact 2024-06-27 10:48:34 +09:00
mob-sakai
88a970d93a feat: restore Transform.localScale when setting autoScalingMode to something other than Transform (again) 2024-06-27 10:48:27 +09:00
mob-sakai
a703c2921c feat: add 'custom view' option.
Use this if the particles are not displayed correctly due to min/max particle size.
2024-06-27 10:48:05 +09:00
mob-sakai
de35cba34c fix: generated baking-camera object remains in the prefab or scene (again) 2024-06-27 10:46:25 +09:00
mob-sakai
ae3f3a8e62 fix: SetParticleSystemInstance/Prefab APIs destroy generated objects
# Conflicts:
#	Packages/src/Runtime/UIParticle.cs
2024-06-27 10:46:10 +09:00
mob-sakai
835817049f feat: remove overlay window (editor) 2024-06-27 10:44:13 +09:00
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
58 changed files with 24076 additions and 8296 deletions

View File

@@ -25,6 +25,7 @@ indent_size = 4
trim_trailing_whitespace = true
insert_final_newline = true
csharp_style_namespace_declarations = block_scoped
csharp_style_implicit_object_creation_when_type_is_apparent = false
resharper_object_creation_when_type_evident = explicitly_typed
@@ -86,6 +87,9 @@ 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
#
resharper_keep_existing_embedded_arrangement = true
# Arguments
csharp_arguments_literal = named:suggestion
csharp_arguments_string_literal = named:suggestion
@@ -134,7 +138,7 @@ 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_preserve_single_line_statements = false
csharp_prefer_static_local_function = true:suggestion
csharp_prefer_simple_using_statement = false:none
csharp_style_prefer_switch_expression = true:suggestion
@@ -186,7 +190,7 @@ 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_around_declaration_statements = false
csharp_space_before_colon_in_inheritance_clause = true
csharp_space_before_comma = false
csharp_space_before_dot = false

View File

@@ -4,8 +4,9 @@ on:
workflow_dispatch:
push:
branches:
- preview
- release
- release-preview
- release-v4
tags-ignore:
- "**"
@@ -22,7 +23,8 @@ jobs:
released: ${{ steps.release.outputs.new_release_published }}
tag: ${{ steps.release.outputs.new_release_git_tag }}
version: ${{ steps.release.outputs.new_release_version }}
notes: ${{ steps.release.outputs.new_release_notes }}
merge_to: ${{ steps.summary.outputs.merge_to }}
split_to: ${{ steps.summary.outputs.split_to }}
steps:
- name: 🚚 Checkout (${{ github.ref_name }})
uses: actions/checkout@v4
@@ -38,38 +40,51 @@ jobs:
env:
GITHUB_TOKEN: ${{ github.token }}
- run: |
- 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
echo '${{ steps.release.outputs.new_release_notes }}' | 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-develop:
if: needs.release.outputs.released == 'true'
merge-to:
if: needs.release.outputs.merge_to != ''
needs: release
name: 🔀 Merge to develop
name: 🔀 Merge to ${{ needs.release.outputs.merge_to }}
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: 🚚 Checkout (develop)
- name: 🚚 Checkout (${{ needs.release.outputs.merge_to }})
uses: actions/checkout@v4
with:
ref: develop
ref: ${{ needs.release.outputs.merge_to }}
fetch-depth: 0
- name: 🔀 Merge '${{ needs.release.outputs.tag }}' into 'develop'
- 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 develop
git push origin ${{ needs.release.outputs.merge_to }}
split-to-main:
if: needs.release.outputs.released == 'true'
split-to:
if: needs.release.outputs.split_to != ''
needs: release
name: 🔀 Split package
name: 🔀 Split package to ${{ needs.release.outputs.split_to }}
runs-on: ubuntu-latest
permissions:
contents: write
@@ -79,9 +94,10 @@ jobs:
with:
ref: ${{ needs.release.outputs.tag }}
fetch-depth: 0
- name: 🔀 Split subtree 'Packages/src' to 'main'
- name: 🔀 Split subtree 'Packages/src' to '${{ needs.release.outputs.split_to }}'
run: |
git branch main origin/main
git subtree split --prefix=Packages/src --branch main
git tag ${{ needs.release.outputs.version }} main
git push origin ${{ needs.release.outputs.version }} main:main
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

@@ -7,6 +7,7 @@ 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:
@@ -14,6 +15,8 @@ on:
push:
branches:
- develop
- develop-preview
- develop-4.x
tags:
- "!*"
paths-ignore:
@@ -35,7 +38,8 @@ jobs:
run: |
echo "==== Target Unity 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=`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 ) ]'`
@@ -54,6 +58,7 @@ jobs:
needs: setup
strategy:
fail-fast: false
max-parallel: 4
matrix:
unityVersion: ${{ fromJson(needs.setup.outputs.unityVersions) }}
steps:

1
.gitignore vendored
View File

@@ -28,3 +28,4 @@ Assets/Plugins/
obj/
bin/
UserSettings/
*.app

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +0,0 @@
fileFormatVersion: 2
guid: a81f9cd434f104e1fad7ffa20eb7a3d4
DefaultImporter:
userData:

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

@@ -0,0 +1,42 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 8
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: UI-Cloud
m_Shader: {fileID: 4800000, guid: 6b5e4f608f0684d10a4673a7e1cee0f3, type: 3}
m_ValidKeywords: []
m_InvalidKeywords:
- _COLORMODE_MULTIPRY
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _MainTex:
m_Texture: {fileID: 2800000, guid: 48901c5d75f8c456aa8f4cd3a6b0160e, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Ints: []
m_Floats:
- _ColorMask: 15
- _ColorMode: 0
- _DstBlend: 10
- _SrcBlend: 1
- _Stencil: 0
- _StencilComp: 8
- _StencilOp: 0
- _StencilReadMask: 255
- _StencilWriteMask: 255
- _UseUIAlphaClip: 0
m_Colors:
- _Color: {r: 1, g: 1, b: 1, a: 1}
m_BuildTextureStacks: []

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

View File

@@ -0,0 +1,147 @@
fileFormatVersion: 2
guid: 48901c5d75f8c456aa8f4cd3a6b0160e
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
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMasterTextureLimit: 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: 1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
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: 0
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 1
cookieLightType: 1
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 256
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 256
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Android
maxTextureSize: 256
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 1
- serializedVersion: 3
buildTarget: WebGL
maxTextureSize: 256
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Server
maxTextureSize: 256
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID: 5e97eb03825dee720800000000000000
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
nameFileIdTable: {}
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,177 @@
Shader "UI/Color"
{
Properties
{
_MainTex ("Main Texture", 2D) = "white" {}
_Color ("Tint", Color) = (1,1,1,1)
[KeywordEnum(Multipry, Additive, Subtract, Fill)] _ColorMode ("Color Mode", Int) = 0
[Enum(UnityEngine.Rendering.BlendMode)] _SrcBlend ("Src Blend Mode", Int) = 1
[Enum(UnityEngine.Rendering.BlendMode)] _DstBlend ("Dst Blend Mode", Int) = 10
_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
{
"Queue"="Transparent"
"IgnoreProjector"="True"
"RenderType"="Transparent"
"PreviewType"="Plane"
"CanUseSpriteAtlas"="True"
}
Stencil
{
Ref [_Stencil]
Comp [_StencilComp]
Pass [_StencilOp]
ReadMask [_StencilReadMask]
WriteMask [_StencilWriteMask]
}
Cull Off
Lighting Off
ZWrite Off
ZTest [unity_GUIZTestMode]
Blend [_SrcBlend] [_DstBlend]
ColorMask [_ColorMask]
Pass
{
Name "Default"
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 2.0
#include "UnityCG.cginc"
#include "UnityUI.cginc"
#pragma multi_compile_local _ UNITY_UI_CLIP_RECT
#pragma multi_compile_local _ UNITY_UI_ALPHACLIP
sampler2D _MainTex;
fixed4 _Color;
fixed4 _TextureSampleAdd;
float4 _ClipRect;
float4 _MainTex_ST;
float _UIMaskSoftnessX;
float _UIMaskSoftnessY;
int _UIVertexColorAlwaysGammaSpace;
int _ColorMode;
struct appdata_t
{
float4 vertex : POSITION;
float4 color : COLOR;
float2 texcoord : TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct v2f
{
float4 vertex : SV_POSITION;
fixed4 color : COLOR;
float2 texcoord : TEXCOORD0;
float4 worldPosition : TEXCOORD1;
float4 mask : TEXCOORD2;
UNITY_VERTEX_OUTPUT_STEREO
};
v2f vert(appdata_t v)
{
v2f OUT;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT);
float4 vPosition = UnityObjectToClipPos(v.vertex);
OUT.worldPosition = v.vertex;
OUT.vertex = vPosition;
float2 pixelSize = vPosition.w;
pixelSize /= float2(1, 1) * abs(mul((float2x2)UNITY_MATRIX_P, _ScreenParams.xy));
float4 clampedRect = clamp(_ClipRect, -2e10, 2e10);
float2 maskUV = (v.vertex.xy - clampedRect.xy) / (clampedRect.zw - clampedRect.xy);
OUT.texcoord = TRANSFORM_TEX(v.texcoord.xy, _MainTex);
OUT.mask = float4(v.vertex.xy * 2 - clampedRect.xy - clampedRect.zw,
0.25 / (0.25 * half2(_UIMaskSoftnessX, _UIMaskSoftnessY) + abs(pixelSize.xy)));
if (_UIVertexColorAlwaysGammaSpace)
{
if (!IsGammaSpace())
{
v.color.rgb = GammaToLinearSpace(v.color.rgb);
}
}
OUT.color = v.color * _Color;
return OUT;
}
half4 apply_color(half4 color, const half4 factor, const int mode)
{
const half3 c = factor.rgb * color.a;
// Mode 1: Additive
if (mode == 1)
{
color.rgb += c;
}
// Mode 2: Subtract
else if (mode == 2)
{
color.rgb -= c;
}
// Mode 3: Replace
else if (mode == 3)
{
color.rgb = c;
}
// Default: Multiply
else
{
color.rgb *= c;
}
return color * factor.a;
}
fixed4 frag(v2f IN) : SV_Target
{
//Round up the alpha color coming from the interpolator (to 1.0/256.0 steps)
//The incoming alpha could have numerical instability, which makes it very sensible to
//HDR color transparency blend, when it blends with the world's texture.
const half alphaPrecision = half(0xff);
const half invAlphaPrecision = half(1.0 / alphaPrecision);
float2 uv = IN.texcoord;
IN.color.a = round(IN.color.a * alphaPrecision) * invAlphaPrecision;
half4 color = tex2D(_MainTex, uv) + _TextureSampleAdd;
#if UNITY_UI_CLIP_RECT
half2 m = saturate((_ClipRect.zw - _ClipRect.xy - abs(IN.mask.xy)) * IN.mask.zw);
color.a *= m.x * m.y;
#endif
#if UNITY_UI_ALPHACLIP
clip (color.a - 0.001);
#endif
// Apply color mode.
color = apply_color(color, IN.color, _ColorMode);
return color;
}
ENDCG
}
}
}

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 6b5e4f608f0684d10a4673a7e1cee0f3
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
preprocessorOverride: 0
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,42 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 8
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: UI-Star-Add
m_Shader: {fileID: 4800000, guid: 6b5e4f608f0684d10a4673a7e1cee0f3, type: 3}
m_ValidKeywords: []
m_InvalidKeywords:
- _COLORMODE_MULTIPRY
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _MainTex:
m_Texture: {fileID: 2800000, guid: 8412a67c0342348169bea68bf9315a14, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Ints: []
m_Floats:
- _ColorMask: 15
- _ColorMode: 0
- _DstBlend: 1
- _SrcBlend: 1
- _Stencil: 0
- _StencilComp: 8
- _StencilOp: 0
- _StencilReadMask: 255
- _StencilWriteMask: 255
- _UseUIAlphaClip: 0
m_Colors:
- _Color: {r: 1, g: 1, b: 1, a: 1}
m_BuildTextureStacks: []

View File

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

View File

@@ -0,0 +1,42 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 8
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: UI-Star
m_Shader: {fileID: 4800000, guid: 6b5e4f608f0684d10a4673a7e1cee0f3, type: 3}
m_ValidKeywords: []
m_InvalidKeywords:
- _COLORMODE_MULTIPRY
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _MainTex:
m_Texture: {fileID: 2800000, guid: 8412a67c0342348169bea68bf9315a14, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Ints: []
m_Floats:
- _ColorMask: 15
- _ColorMode: 0
- _DstBlend: 10
- _SrcBlend: 1
- _Stencil: 0
- _StencilComp: 8
- _StencilOp: 0
- _StencilReadMask: 255
- _StencilWriteMask: 255
- _UseUIAlphaClip: 0
m_Colors:
- _Color: {r: 1, g: 1, b: 1, a: 1}
m_BuildTextureStacks: []

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -0,0 +1,147 @@
fileFormatVersion: 2
guid: 8412a67c0342348169bea68bf9315a14
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
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMasterTextureLimit: 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: 1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
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: 2
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 1
cookieLightType: 1
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 128
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 128
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Android
maxTextureSize: 128
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 1
- serializedVersion: 3
buildTarget: WebGL
maxTextureSize: 128
resizeAlgorithm: 0
textureFormat: 63
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 1
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Server
maxTextureSize: 128
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID: 5e97eb03825dee720800000000000000
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
nameFileIdTable: {}
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,42 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 8
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: UI-StretchTrait
m_Shader: {fileID: 4800000, guid: 6b5e4f608f0684d10a4673a7e1cee0f3, type: 3}
m_ValidKeywords: []
m_InvalidKeywords:
- _COLORMODE_MULTIPRY
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _MainTex:
m_Texture: {fileID: 2800000, guid: 7d5844d14c31c4ca88cf5653c09ec1f3, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Ints: []
m_Floats:
- _ColorMask: 15
- _ColorMode: 0
- _DstBlend: 1
- _SrcBlend: 1
- _Stencil: 0
- _StencilComp: 8
- _StencilOp: 0
- _StencilReadMask: 255
- _StencilWriteMask: 255
- _UseUIAlphaClip: 0
m_Colors:
- _Color: {r: 1, g: 1, b: 1, a: 1}
m_BuildTextureStacks: []

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

View File

@@ -0,0 +1,147 @@
fileFormatVersion: 2
guid: 7d5844d14c31c4ca88cf5653c09ec1f3
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
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMasterTextureLimit: 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: 1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
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: 2
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 1
cookieLightType: 1
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 64
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 64
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Android
maxTextureSize: 64
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 1
- serializedVersion: 3
buildTarget: WebGL
maxTextureSize: 64
resizeAlgorithm: 0
textureFormat: 63
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 1
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Server
maxTextureSize: 64
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID: 5e97eb03825dee720800000000000000
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
nameFileIdTable: {}
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -46,7 +46,11 @@ namespace Coffee.UIExtensions.Demo
if (!flag)
{
#if UNITY_2023_1_OR_NEWER
foreach (var ps in FindObjectsByType<ParticleSystem>(FindObjectsInactive.Include, FindObjectsSortMode.None))
#else
foreach (var ps in FindObjectsOfType<ParticleSystem>())
#endif
{
ps.Play(false);
}
@@ -75,7 +79,11 @@ namespace Coffee.UIExtensions.Demo
public void ParticleSystem_SetScale(float scale)
{
#if UNITY_2023_1_OR_NEWER
foreach (var ps in FindObjectsByType<ParticleSystem>(FindObjectsInactive.Include, FindObjectsSortMode.None))
#else
foreach (var ps in FindObjectsOfType<ParticleSystem>())
#endif
{
ps.transform.localScale = new Vector3(scale, scale, scale);
}

File diff suppressed because it is too large Load Diff

View File

@@ -14,15 +14,15 @@ MonoBehaviour:
m_EditorClassIdentifier:
m_NanoMonitorEnabled: 1
m_BootSceneNameRegex: .*
m_DevelopmentBuildOnly: 1
m_DevelopmentBuildOnly: 0
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_Anchor: 0
m_Width: 750
m_CustomMonitorItems:
- m_Format: Screen:{0}x{1}
m_Arg0:
@@ -31,3 +31,10 @@ MonoBehaviour:
m_Path: UnityEngine.Screen, UnityEngine.CoreModule;height
m_Arg2:
m_Path:
- m_Format: UIParticles:{0} Materials:{1}
m_Arg0:
m_Path: Coffee.UIExtensions.UIParticleUpdater, Coffee.UIParticle;uiParticleCount
m_Arg1:
m_Path: Coffee.UIParticleInternal.MaterialRepository, Coffee.UIParticle;count
m_Arg2:
m_Path:

File diff suppressed because it is too large Load Diff

View File

@@ -1,20 +0,0 @@
%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

@@ -1,513 +0,0 @@
%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,7 @@
{
"dependencies": {
"com.unity.ide.rider": "3.0.27",
"com.coffee.nano-monitor": "https://github.com/mob-sakai/Coffee.Internal.git?path=Packages/NanoMonitor",
"com.unity.ide.rider": "3.0.31",
"com.unity.test-framework": "1.1.33",
"com.unity.modules.animation": "1.0.0",
"com.unity.modules.physics": "1.0.0"

View File

@@ -1,5 +1,14 @@
{
"dependencies": {
"com.coffee.nano-monitor": {
"version": "https://github.com/mob-sakai/Coffee.Internal.git?path=Packages/NanoMonitor",
"depth": 0,
"source": "git",
"dependencies": {
"com.unity.ugui": "1.0.0"
},
"hash": "c51e4514c9ab944915a639433ee52342e55a644e"
},
"com.coffee.ui-particle": {
"version": "file:src",
"depth": 0,
@@ -17,7 +26,7 @@
"url": "https://packages.unity.com"
},
"com.unity.ide.rider": {
"version": "3.0.27",
"version": "3.0.31",
"depth": 0,
"source": "registry",
"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

@@ -1,9 +1,10 @@
{
"branches": [
"release",
"release-4.x",
{
"name": "preview",
"prerelease": true
"name": "release-preview",
"prerelease": "preview"
}
],
"plugins": [

View File

@@ -1,3 +1,115 @@
## [4.9.1](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.9.0...v4.9.1) (2024-08-07)
### Bug Fixes
* ParticleSystem trails gain offset on parent canvas change ([2a1cd50](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/2a1cd502b452b5b56edf8bcfe91adf99d1bb5147)), closes [#323](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/323)
# [4.9.0](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.8.1...v4.9.0) (2024-07-18)
### Features
* ParticleAttractor supports multiple ParticleSystems ([3834780](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/3834780fdb43443fe6e1ef89df54d26a24d62a91))
## [4.8.1](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.8.0...v4.8.1) (2024-06-27)
### Bug Fixes
* remove debug code ([669deb4](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/669deb41d4ac589d9db93b29bc8e95383e7f28a5))
# [4.8.0](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.7.2...v4.8.0) (2024-06-27)
### Bug Fixes
* generated baking-camera object remains in the prefab or scene (again) ([de35cba](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/de35cba34c6312c1405ed522e9927c620c78e72d))
* SetParticleSystemInstance/Prefab APIs destroy generated objects ([ae3f3a8](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/ae3f3a8e62cc733420354d237ab765ac777127c8))
### Features
* add 'custom view' option. ([a703c29](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/a703c2921ca08c2280d0c8fde01e4c0b33b5c69e))
* remove overlay window (editor) ([8358170](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/835817049f4fcf00dd2bf98dbada14f041ad3544))
* restore `Transform.localScale` when setting `autoScalingMode` to something other than `Transform` (again) ([88a970d](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/88a970d93a2b69cf011d86bd1807569e90538e0e))
* the rendering order list in inspector is now more compact ([be90172](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/be901724e064befacf617f4940b0331e1d31e1ca))
## [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)

View File

@@ -31,35 +31,35 @@ namespace Coffee.UIExtensions
}
else
{
result.Aggregate(s_Sb, (a, b) => s_Sb.AppendFormat("{0}, ", b));
result.Aggregate(s_Sb, (a, b) =>
{
s_Sb.Append(b);
return s_Sb.Append(", ");
});
s_Sb.Length -= 2;
}
return s_Sb.ToString();
}
public static void Draw(SerializedProperty sp, Material[] mats)
public static void Draw(SerializedProperty sp, List<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);
}
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);
if (!isClicked) return;
if (!GUI.Button(rect, text, EditorStyles.popup)) return;
var gm = new GenericMenu();
gm.AddItem(s_ContentNothing, s_ActiveNames.Count == 0, () =>
gm.AddItem(s_ContentNothing, s_ActiveNames.Count == 0, x =>
{
sp.ClearArray();
sp.serializedObject.ApplyModifiedProperties();
});
var current = (SerializedProperty)x;
current.ClearArray();
current.serializedObject.ApplyModifiedProperties();
}, sp);
if (!sp.hasMultipleDifferentValues)
{
@@ -73,7 +73,7 @@ namespace Coffee.UIExtensions
}
s_Names.Clear();
for (var j = 0; j < mats.Length; j++)
for (var j = 0; j < mats.Count; j++)
{
var mat = mats[j];
if (!mat || !mat.shader) continue;
@@ -82,8 +82,7 @@ namespace Coffee.UIExtensions
{
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);
if (!s_Names.Add(name)) continue;
AddMenu(gm, sp, new ShaderProperty(name, type), true);

View File

@@ -5,6 +5,7 @@ using UnityEditor;
using UnityEditor.UI;
using UnityEditorInternal;
using UnityEngine;
using UnityEngine.Profiling;
using UnityEngine.UI;
using Coffee.UIParticleExtensions;
#if UNITY_2021_2_OR_NEWER
@@ -26,41 +27,24 @@ namespace Coffee.UIExtensions
[CanEditMultipleObjects]
internal class UIParticleEditor : GraphicEditor
{
#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)]
#else
[Overlay(typeof(SceneView), "Scene View/UI Particles", "UI Particles", true)]
#endif
private class UIParticleOverlay : IMGUIOverlay, ITransientOverlay
{
public bool visible => s_SerializedObject != null;
public override void OnGUI()
{
if (visible)
{
WindowFunction();
}
}
}
#endif
//################################
// Constant or Static Members.
//################################
private static readonly GUIContent[] s_ContentMaterials = new[]
{
new GUIContent("Material"),
new GUIContent("Trail Material")
};
private static readonly GUIContent s_ContentRenderingOrder = new GUIContent("Rendering Order");
private static readonly GUIContent s_ContentRefresh = new GUIContent("Refresh");
private static readonly GUIContent s_ContentFix = new GUIContent("Fix");
private static readonly GUIContent s_ContentMaterial = new GUIContent("Material");
private static readonly GUIContent s_ContentTrailMaterial = new GUIContent("Trail Material");
private static readonly GUIContent s_Content3D = new GUIContent("3D");
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 readonly GUIContent s_ContentPrimary = new GUIContent("Primary");
private static readonly Regex s_RegexBuiltInGuid = new Regex(@"^0{16}.0{15}$", RegexOptions.Compiled);
private static readonly List<Material> s_TempMaterials = new List<Material>();
private static bool s_XYZMode;
private SerializedProperty _maskable;
@@ -71,6 +55,8 @@ namespace Coffee.UIExtensions
private SerializedProperty _groupMaxId;
private SerializedProperty _positionMode;
private SerializedProperty _autoScalingMode;
private SerializedProperty _useCustomView;
private SerializedProperty _customViewSize;
private ReorderableList _ro;
private bool _showMax;
@@ -88,56 +74,6 @@ namespace Coffee.UIExtensions
"_ColorMask"
};
[InitializeOnLoadMethod]
private static void Init()
{
#if !UNITY_2021_2_OR_NEWER
var miSceneViewOverlayWindow = Type.GetType("UnityEditor.SceneViewOverlay, UnityEditor")
?.GetMethods(BindingFlags.Public | BindingFlags.Static)
.First(x => x.Name == "Window" && 5 <= x.GetParameters().Length);
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(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 };
#else
//public static void Window(GUIContent title, WindowFunction sceneViewFunc, int order, Object target, WindowDisplayOption option)
var sceneViewArgs = new object[] { windowTitle, windowFunctionDelegate, 599, null, 2 };
#endif
#if UNITY_2019_1_OR_NEWER
SceneView.duringSceneGui += _ =>
#else
SceneView.onSceneGUIDelegate += _ =>
#endif
{
if (s_SerializedObject != null)
{
miSceneViewOverlayWindow.Invoke(null, sceneViewArgs);
}
};
#endif
SerializedObject CreateSerializeObject()
{
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();
}
//################################
// Public/Protected Members.
//################################
@@ -156,31 +92,43 @@ namespace Coffee.UIExtensions
_groupMaxId = serializedObject.FindProperty("m_GroupMaxId");
_positionMode = serializedObject.FindProperty("m_PositionMode");
_autoScalingMode = serializedObject.FindProperty("m_AutoScalingMode");
_useCustomView = serializedObject.FindProperty("m_UseCustomView");
_customViewSize = serializedObject.FindProperty("m_CustomViewSize");
var sp = serializedObject.FindProperty("m_Particles");
_ro = new ReorderableList(sp.serializedObject, sp, true, true, true, true)
{
elementHeight = EditorGUIUtility.singleLineHeight * 3 + 4,
elementHeightCallback = _ => 3 * (EditorGUIUtility.singleLineHeight + 2),
elementHeightCallback = index =>
{
var ps = sp.GetArrayElementAtIndex(index).objectReferenceValue as ParticleSystem;
var materialCount = 0;
if (ps && ps.TryGetComponent<ParticleSystemRenderer>(out var psr))
{
materialCount = psr.sharedMaterials.Length;
}
return (materialCount + 1) * (EditorGUIUtility.singleLineHeight + 2);
},
drawElementCallback = (rect, index, _, __) =>
{
EditorGUI.BeginDisabledGroup(sp.hasMultipleDifferentValues);
rect.y += 1;
rect.y += 2;
rect.height = EditorGUIUtility.singleLineHeight;
var p = sp.GetArrayElementAtIndex(index);
EditorGUI.ObjectField(rect, p, GUIContent.none);
var ps = p.objectReferenceValue as ParticleSystem;
if (!ps || !ps.TryGetComponent<ParticleSystemRenderer>(out var psr)) return;
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)
var materials = new SerializedObject(psr).FindProperty("m_Materials");
var count = Mathf.Min(materials.arraySize, 2);
for (var i = 0; i < count; i++)
{
rect.y += rect.height + 2;
EditorGUI.PropertyField(rect, materials.GetArrayElementAtIndex(i), s_ContentMaterials[i]);
}
if (materials.serializedObject.hasModifiedProperties)
{
materials.serializedObject.ApplyModifiedProperties();
}
@@ -216,20 +164,6 @@ namespace Coffee.UIExtensions
}
}
private static void MaterialField(Rect rect, GUIContent label, SerializedProperty sp, int index)
{
if (sp == null || sp.arraySize <= index)
{
EditorGUI.BeginDisabledGroup(true);
EditorGUI.ObjectField(rect, label, null, typeof(Material), true);
EditorGUI.EndDisabledGroup();
}
else
{
EditorGUI.PropertyField(rect, sp.GetArrayElementAtIndex(index), label);
}
}
/// <summary>
/// Implement this function to make a custom inspector.
/// </summary>
@@ -238,6 +172,7 @@ namespace Coffee.UIExtensions
var current = target as UIParticle;
if (!current) return;
Profiler.BeginSample("(UIP:E) OnInspectorGUI");
serializedObject.Update();
// Maskable
@@ -249,13 +184,8 @@ namespace Coffee.UIExtensions
EditorGUI.EndDisabledGroup();
// AnimatableProperties
var mats = current.particles
.Where(x => x)
.Select(x => x.GetComponent<ParticleSystemRenderer>().sharedMaterial)
.Where(x => x)
.ToArray();
AnimatablePropertyEditor.Draw(_animatableProperties, mats);
current.GetMaterials(s_TempMaterials);
AnimatablePropertyEditor.Draw(_animatableProperties, s_TempMaterials);
// Mesh sharing
EditorGUI.BeginChangeCheck();
@@ -263,9 +193,12 @@ namespace Coffee.UIExtensions
if (EditorGUI.EndChangeCheck())
{
serializedObject.ApplyModifiedProperties();
foreach (var uip in targets.OfType<UIParticle>())
foreach (var t in targets)
{
uip.ResetGroupId();
if (t is UIParticle uip)
{
uip.ResetGroupId();
}
}
}
@@ -273,16 +206,29 @@ namespace Coffee.UIExtensions
EditorGUILayout.PropertyField(_positionMode);
// Auto Scaling
DrawAutoScaling(_autoScalingMode, targets.OfType<UIParticle>());
EditorGUILayout.PropertyField(_autoScalingMode);
// Custom View Size
EditorGUILayout.PropertyField(_useCustomView);
EditorGUI.BeginChangeCheck();
EditorGUI.BeginDisabledGroup(!_useCustomView.boolValue);
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(_customViewSize);
EditorGUI.indentLevel--;
EditorGUI.EndDisabledGroup();
if (EditorGUI.EndChangeCheck())
{
_customViewSize.floatValue = Mathf.Max(0.1f, _customViewSize.floatValue);
}
// Target ParticleSystems.
EditorGUI.BeginChangeCheck();
EditorGUI.BeginDisabledGroup(targets.OfType<UIParticle>().Any(x => !x.canvas));
_ro.DoLayoutList();
EditorGUI.EndDisabledGroup();
serializedObject.ApplyModifiedProperties();
if (EditorGUI.EndChangeCheck())
{
EditorApplication.QueuePlayerLoopUpdate();
foreach (var uip in targets.OfType<UIParticle>())
{
uip.RefreshParticles(uip.particles);
@@ -290,7 +236,8 @@ namespace Coffee.UIExtensions
}
// Non-UI built-in shader is not supported.
foreach (var mat in current.materials)
Profiler.BeginSample("(UIP:E) Non-UI built-in shader is not supported.");
foreach (var mat in s_TempMaterials)
{
if (!mat || !mat.shader) continue;
var shader = mat.shader;
@@ -303,15 +250,18 @@ namespace Coffee.UIExtensions
}
}
Profiler.EndSample();
// Does the shader support UI masks?
Profiler.BeginSample("(UIP:E) Does the shader support UI masks?");
if (current.maskable && current.GetComponentInParent<Mask>(false))
{
foreach (var mat in current.materials)
foreach (var mat in s_TempMaterials)
{
if (!mat || !mat.shader) continue;
var shader = mat.shader;
if (s_Shaders.Contains(shader)) continue;
s_Shaders.Add(shader);
if (!s_Shaders.Add(shader)) continue;
foreach (var propName in s_MaskablePropertyNames)
{
if (mat.HasProperty(propName)) continue;
@@ -325,7 +275,9 @@ namespace Coffee.UIExtensions
}
}
s_TempMaterials.Clear();
s_Shaders.Clear();
Profiler.EndSample();
// UIParticle for trail should be removed.
var label = "This UIParticle component should be removed. The UIParticle for trails is no longer needed.";
@@ -364,12 +316,14 @@ namespace Coffee.UIExtensions
}
}
#endif
Profiler.EndSample();
}
private bool IsBuiltInObject(Object obj)
private static bool IsBuiltInObject(Object obj)
{
return AssetDatabase.TryGetGUIDAndLocalFileIdentifier(obj, out var guid, out long _)
&& Regex.IsMatch(guid, "^0{16}.0{15}$", RegexOptions.Compiled);
return AssetDatabase.IsMainAsset(obj)
&& AssetDatabase.TryGetGUIDAndLocalFileIdentifier(obj, out var guid, out long _)
&& s_RegexBuiltInGuid.IsMatch(guid);
}
#if UNITY_2018 || UNITY_2019
@@ -463,7 +417,7 @@ namespace Coffee.UIExtensions
{
EditorGUI.BeginDisabledGroup(true);
var obj = UIParticleUpdater.GetPrimary(spGroupId.intValue);
EditorGUILayout.ObjectField("Primary", obj, typeof(UIParticle), false);
EditorGUILayout.ObjectField(s_ContentPrimary, obj, typeof(UIParticle), false);
EditorGUI.EndDisabledGroup();
}
@@ -473,54 +427,9 @@ namespace Coffee.UIExtensions
return showMax;
}
private static void DrawAutoScaling(SerializedProperty prop, IEnumerable<UIParticle> uiParticles)
private static void DrawAutoScaling(SerializedProperty prop)
{
var isTransformMode = prop.intValue == (int)UIParticle.AutoScalingMode.Transform;
EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(prop);
if (!EditorGUI.EndChangeCheck() || !isTransformMode) return;
// on changed true->false, reset scale.
EditorApplication.delayCall += () =>
{
foreach (var uip in uiParticles)
{
if (!uip) continue;
uip.transform.localScale = Vector3.one;
}
};
}
#if UNITY_2021_2_OR_NEWER
private static void WindowFunction()
#else
private static void WindowFunction(Object _, SceneView __)
#endif
{
try
{
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;
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)

View File

@@ -1,4 +1,4 @@
Copyright 2018-2023 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:

View File

@@ -1,61 +1,84 @@
# 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.
# <img alt="UIParticleIcon" src="https://github.com/mob-sakai/ParticleEffectForUGUI/assets/12690315/d76e105e-a840-4f61-a1f6-8cf311c0812d" width="26"/> Particle Effect For UGUI (UI Particle) <!-- omit in toc -->
[![](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/github/v/release/mob-sakai/ParticleEffectForUGUI)](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.md)
![](https://img.shields.io/badge/Unity-2018.2+-57b9d3.svg?style=flat&logo=unity)
![](https://img.shields.io/badge/uGUI_2.0_Ready-57b9d3.svg?style=flat)
![](https://img.shields.io/badge/UPR%2FHDPR_Ready-57b9d3.svg?style=flat)
![](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/github/watchers/mob-sakai/ParticleEffectForUGUI.svg?style=social&label=Watch)](https://github.com/mob-sakai/ParticleEffectForUGUI/subscription)
[![](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) >>
<< [📝 Description](#-description-) | [📌 Key Features](#-key-features) | [🎮 Demo](#-demo) | [⚙ Installation](#-installation) | [🚀 Usage](#-usage) | [🛠 Development Note](#-development-note) | [🤝 Contributing](#-contributing) >>
<br><br>
## 📝 Description
## 📝 Description <!-- omit in toc -->
![](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.
This package uses the new APIs `MeshBake/MeshTrailBake` (introduced in Unity 2018.2) to render particles through `CanvasRenderer`.
You can render, mask, and sort your `ParticleSystems` for UI without the need for an additional `Camera`, `RenderTexture`, or `Canvas`.
### Features
- [📌 Key Features](#-key-features)
- [🎮 Demo](#-demo)
- [⚙ Installation](#-installation)
- [Install via OpenUPM](#install-via-openupm)
- [Install via UPM (with Package Manager UI)](#install-via-upm-with-package-manager-ui)
- [Install via UPM (Manually)](#install-via-upm-manually)
- [Install as Embedded Package](#install-as-embedded-package)
- [🚀 Usage](#-usage)
- [Component: UIParticle](#component-uiparticle)
- [Basic Usage](#basic-usage)
- [Usage with Your Existing ParticleSystem Prefab](#usage-with-your-existing-particlesystem-prefab)
- [Usage with `Mask` or `RectMask2D` Component](#usage-with-mask-or-rectmask2d-component)
- [Usage with Script](#usage-with-script)
- [Component: UIParticleAttractor](#component-uiparticleattractor)
- [🛠 Development Note](#-development-note)
- [Compares the Baking mesh approach with the conventional approach](#compares-the-baking-mesh-approach-with-the-conventional-approach)
- [Performance test results](#performance-test-results)
- [🔍 FAQ: Why Are My UIParticles Not Displayed Correctly?](#-faq-why-are-my-uiparticles-not-displayed-correctly)
- [Shader Limitation](#shader-limitation)
- [Built-in shaders are not supported](#built-in-shaders-are-not-supported)
- [(Unity 2018 or 2019) UV.zw components will be discarded](#unity-2018-or-2019-uvzw-components-will-be-discarded)
- [(Unity 2018 or 2019) Custom vertex streams](#unity-2018-or-2019-custom-vertex-streams)
- [Overheads](#overheads)
- [How to Make a Custom Shader to Support `Mask` and `RectMask2D` Component](#how-to-make-a-custom-shader-to-support-mask-and-rectmask2d-component)
- [🤝 Contributing](#-contributing)
- [Issues](#issues)
- [Pull Requests](#pull-requests)
- [Support](#support)
- [License](#license)
- [Author](#author)
- [See Also](#see-also)
* 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]
<br><br>
[AnimatableProperty.gif]: https://user-images.githubusercontent.com/12690315/53286323-2d94a980-37b0-11e9-8afb-c4a207805ff2.gif
## 📌 Key Features
[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
* **Easy to use:** The package is ready to use out of the box.
* **Sortable:** Sort particle effects and other UI elements by sibling index.
* **Maskable:** Supports `Mask` or `RectMask2D`.
* **No extra components required:** No need for an additional `Camera`, `RenderTexture`, or `Canvas`.
* **Trail module support:** Fully supports the Trail module.
* **CanvasGroup alpha support:** Integrates with `CanvasGroup` alpha.
* **No allocations:** Efficiently renders particles without allocations.
* **Any canvas render mode support:** Works with overlay, camera space, and world space.
* **Any Render pipeline support:** Compatible with Universal Render Pipeline (URP) and High Definition Render Pipeline (HDRP).
* **Disabling domain reload support:** Supports disabling `Enter Play Mode Options > Reload Domain`.
* **Animatable material properties:** Supports changing material properties with AnimationClip (AnimatableProperty).
![AnimatableProperty.gif](https://user-images.githubusercontent.com/12690315/53286323-2d94a980-37b0-11e9-8afb-c4a207805ff2.gif)
* **Multiple materials:** Supports 8+ materials.
* **Correct positioning:** Adjusts world space particle positions correctly when changing window size for standalone platforms (Windows, MacOSX, and Linux).
* **Adaptive scaling:** Provides adaptive scaling for UI (AutoScalingMode).
* **Performance optimization:** Mesh sharing group to improve performance.
<img alt="MeshSharing.gif" src="https://user-images.githubusercontent.com/12690315/174311048-c882df81-6c34-4eba-b0aa-5645457692f1.gif" width="450"/>
* **Particle attractor:** Includes a particle attractor component.
<img alt="ParticleAttractor.gif" src="https://user-images.githubusercontent.com/12690315/174311027-462929a4-13f0-4ec4-86ea-9c832f2eecf1.gif" width="450"/>
* **Emission position mode:** Supports relative/absolute particle emission position modes.
<img alt="AbsolutePosition.gif" src="https://user-images.githubusercontent.com/12690315/175751579-5a2357e8-2ecf-4afd-83c8-66e9771bde39.gif" width="450"/>
* **Custom view size:** Fixes min/max particle size mismatch.
![CustomViewSize.gif](https://github.com/mob-sakai/ParticleEffectForUGUI/assets/12690315/dd929959-1a37-420b-b13d-e849022b9c9d)
<br><br>
@@ -76,66 +99,86 @@ or Canvas.
[JMO]: https://assetstore.unity.com/publishers/1669
<br><br>
## ⚙ Installation
_This package requires Unity 2018.3 or later._
_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.
- 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:
```
openupm add com.coffee.ui-particle
```
- To update the package, use Package Manager UI (`Window > Package Manager`) or run the following command with `@{version}`:
```
openupm add com.coffee.ui-particle@4.9.0
```
If you have [openupm-cli](https://github.com/openupm/openupm-cli) installed, then run the following command in your
project's directory:
#### Install via UPM (with Package Manager UI)
```sh
openupm add com.coffee.ui-particle
```
- Click `Window > Package Manager` to open Package Manager UI.
- Click `+ > Add package from git URL...` and input the repository URL: `https://github.com/mob-sakai/ParticleEffectForUGUI.git`
![](https://github.com/user-attachments/assets/f88f47ad-c606-44bd-9e86-ee3f72eac548)
- To update the package, change suffix `#{version}` to the target version.
- e.g. `https://github.com/mob-sakai/ParticleEffectForUGUI.git#4.9.0`
#### Install via UPM (using Git URL)
#### Install via UPM (Manually)
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",
...
- Open the `Packages/manifest.json` file in your project. 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.
- To update the package, change suffix `#{version}` to the target version.
- e.g. `"com.coffee.ui-particle": "https://github.com/mob-sakai/ParticleEffectForUGUI.git#4.9.0",`
* e.g. `"com.coffee.ui-particle": "https://github.com/mob-sakai/ParticleEffectForUGUI.git#4.6.0",`
#### Install as Embedded Package
Or, use [UpmGitExtension](https://github.com/mob-sakai/UpmGitExtension) to install and update the package.
1. Download a source code zip file from [Releases](https://github.com/mob-sakai/ParticleEffectForUGUI.git/releases) and extract it.
2. Place it in your project's `Packages` directory.
![](https://github.com/mob-sakai/mob-sakai/assets/12690315/0b7484b4-5fca-43b0-a9ef-e5dbd99bcdb4)
- If you want to fix bugs or add features, install it as an embedded package.
- To update the package, you need to re-download it and replace the contents.
<br><br>
## 🚀 Usage
### UIParticle Component
### Component: UIParticle
`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)
![](https://github.com/mob-sakai/ParticleEffectForUGUI/assets/12690315/1cf5753b-33fc-4cef-91c3-413c515a954f)
- **Maskable**: Does this graphic allow masking.
- **Scale**: Scale the rendering. When the `3D` toggle is enabled, 3D scale (x, y, z) is supported.
- **Maskable**: Does this graphic allow maskable.
- **Scale**: Scale the rendering particles. 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.
use this to mark as animatable.
- **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.
- **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.
- **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`.
- **Absolute:** The particles will be emitted from the world position.
- **Relative:** The particles will be emitted from the scaled position.
- **Auto Scaling Mode**: How to automatically adjust when the Canvas scale is changed by the screen size or reference resolution.
- **None:** Do nothing.
- **Transform:** Transform.lossyScale (=world scale) will be set to (1, 1, 1).
- **UIParticle:** UIParticle.scale will be adjusted.
- **Use Custom View:** Use this if the particles are not displayed correctly due to min/max particle size.
- **Custom view size:** Change the bake view size.
- **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
@@ -143,7 +186,7 @@ and z-position.
<br><br>
#### Basic Usage
### 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)
@@ -152,7 +195,7 @@ and z-position.
<br>
#### With Your Existing ParticleSystem Prefab
### Usage 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)
@@ -161,7 +204,7 @@ and z-position.
<br>
#### With `Mask` or `RectMask2D` Component
### Usage 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.
@@ -173,12 +216,13 @@ section.
<br><br>
### Script usage
### Usage with Script
```cs
// Instant ParticleSystem prefab with UIParticle on runtime.
// Instantiate ParticleSystem prefab with UIParticle on runtime.
var go = GameObject.Instantiate(prefab);
var uiParticle = go.AddComponent<UIParticle>();
uiParticle.scale = 100;
// Control by ParticleSystem.
particleSystem.Play();
@@ -191,14 +235,14 @@ uiParticle.Stop();
<br><br>
### UIParticleAttractor component
### Component: UIParticleAttractor
`UIParticleAttractor` attracts particles generated by the specified ParticleSystem.
![](https://github.com/mob-sakai/ParticleEffectForUGUI/assets/12690315/ea6ae0ed-f9a8-437c-8baa-47526303391e)
![](https://github.com/mob-sakai/ParticleEffectForUGUI/assets/12690315/5c20ad73-4b9a-4f38-9cdc-119df5cce077)
![](https://user-images.githubusercontent.com/12690315/174311027-462929a4-13f0-4ec4-86ea-9c832f2eecf1.gif)
- **Particle System**: Attracts particles generated by the specified particle system.
- **Particle Systems**: Attracts particles generated by the specified ParticleSystems.
- **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.
@@ -343,7 +387,7 @@ When improving performance, keep the following in mind:
- 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
### How to Make a Custom Shader to Support `Mask` and `RectMask2D` Component
<details>
<summary>Shader tips</summary>

View File

@@ -29,7 +29,7 @@ namespace Coffee.UIParticleExtensions
{
name = $"{baseMat.name}_{id}",
hideFlags = HideFlags.DontSave | HideFlags.NotEditable,
mainTexture = texture ? texture : null
mainTexture = texture ? texture : baseMat.mainTexture
}
};
s_Entries.Add(e);

View File

@@ -2,7 +2,6 @@ using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using Coffee.UIParticleExtensions;
using UnityEditor;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Serialization;
@@ -45,23 +44,26 @@ namespace Coffee.UIExtensions
[HideInInspector]
[SerializeField]
[Obsolete]
internal bool m_IsTrail;
[HideInInspector]
[FormerlySerializedAs("m_IgnoreParent")]
[SerializeField]
[Obsolete]
private bool m_IgnoreCanvasScaler;
[HideInInspector]
[SerializeField]
private bool m_AbsoluteMode;
[Obsolete]
internal bool m_AbsoluteMode;
[Tooltip("Particle effect scale")]
[Tooltip("Scale the rendering particles. When the `3D` toggle is enabled, 3D scale (x, y, z) is supported.")]
[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.")]
[Tooltip("If you want to update material properties (e.g. _MainTex_ST, _Color) in AnimationClip, " +
"use this to mark as animatable.")]
[SerializeField]
internal AnimatableProperty[] m_AnimatableProperties = new AnimatableProperty[0];
@@ -69,12 +71,13 @@ namespace Coffee.UIExtensions
[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" +
[Tooltip("Particle simulation results are shared within the same group. " +
"A large number of the same effects can be displayed with a small load.\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.")]
"Replica: Render simulation results provided by the primary.")]
[SerializeField]
private MeshSharing m_MeshSharing = MeshSharing.None;
@@ -86,26 +89,40 @@ namespace Coffee.UIExtensions
[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.")]
[Tooltip("Emission position mode.\n" +
"Relative: The particles will be emitted from the scaled position.\n" +
"Absolute: The particles will be emitted from the world position.")]
[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;
[Obsolete]
internal bool m_AutoScaling;
[SerializeField]
[Tooltip("Transform: Transform.lossyScale (=world scale) will be set to (1, 1, 1)." +
"UIParticle: UIParticle.scale will be adjusted.")]
[Tooltip(
"How to automatically adjust when the Canvas scale is changed by the screen size or reference resolution.\n" +
"None: Do nothing.\n" +
"Transform: Transform.lossyScale (=world scale) will be set to (1, 1, 1).\n" +
"UIParticle: UIParticle.scale will be adjusted.")]
private AutoScalingMode m_AutoScalingMode = AutoScalingMode.Transform;
[SerializeField]
private bool m_ResetScaleOnEnable;
[Tooltip("Use a custom view.\n" +
"Use this if the particles are not displayed correctly due to min/max particle size.")]
private bool m_UseCustomView;
[SerializeField]
[Tooltip("Custom view size.\n" +
"Change the bake view size.")]
private float m_CustomViewSize = 10;
private readonly List<UIParticleRenderer> _renderers = new List<UIParticleRenderer>();
private Camera _bakeCamera;
private Canvas _canvas;
private int _groupId;
private Camera _orthoCamera;
private bool _isScaleStored;
private Vector3 _storedScale;
private DrivenRectTransformTracker _tracker;
/// <summary>
@@ -118,7 +135,8 @@ namespace Coffee.UIExtensions
}
/// <summary>
/// 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.
/// None: disable mesh sharing.
/// Auto: automatically select Primary/Replica.
/// Primary: provides particle simulation results to the same group.
@@ -161,9 +179,9 @@ namespace Coffee.UIExtensions
}
/// <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.
/// Emission position mode.
/// Relative: The particles will be emitted from the scaled position.
/// Absolute: The particles will be emitted from the world position.
/// </summary>
public PositionMode positionMode
{
@@ -176,6 +194,7 @@ namespace Coffee.UIExtensions
/// 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>
[Obsolete("The absoluteMode is now obsolete. Please use the autoScalingMode instead.", false)]
public bool absoluteMode
{
get => m_PositionMode == PositionMode.Absolute;
@@ -193,8 +212,12 @@ namespace Coffee.UIExtensions
}
/// <summary>
/// Auto scaling mode.
/// How to automatically adjust when the Canvas scale is changed by the screen size or reference resolution.
/// <para/>
/// None: Do nothing.
/// <para/>
/// Transform: Transform.lossyScale (=world scale) will be set to (1, 1, 1).
/// <para/>
/// UIParticle: UIParticle.scale will be adjusted.
/// </summary>
public AutoScalingMode autoScalingMode
@@ -204,10 +227,35 @@ namespace Coffee.UIExtensions
{
if (m_AutoScalingMode == value) return;
m_AutoScalingMode = value;
UpdateTracker();
if (autoScalingMode != AutoScalingMode.Transform && _isScaleStored)
{
transform.localScale = _storedScale;
_isScaleStored = false;
}
}
}
/// <summary>
/// Use a custom view.
/// Use this if the particles are not displayed correctly due to min/max particle size.
/// </summary>
public bool useCustomView
{
get => m_UseCustomView;
set => m_UseCustomView = value;
}
/// <summary>
/// Custom view size.
/// Change the bake view size.
/// </summary>
public float customViewSize
{
get => m_CustomViewSize;
set => m_CustomViewSize = Mathf.Max(0.1f, value);
}
internal bool useMeshSharing => m_MeshSharing != MeshSharing.None;
internal bool isPrimary =>
@@ -247,30 +295,12 @@ namespace Coffee.UIExtensions
/// <summary>
/// Particle effect scale.
/// </summary>
public Vector3 scale3DForCalc => autoScalingMode == AutoScalingMode.UIParticle
? m_Scale3D.GetScaled(canvasScale)
: m_Scale3D;
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>
@@ -282,8 +312,8 @@ namespace Coffee.UIExtensions
protected override void OnEnable()
{
_isScaleStored = false;
ResetGroupId();
UpdateTracker();
UIParticleUpdater.Register(this);
RegisterDirtyMaterialCallback(UpdateRendererMaterial);
@@ -297,13 +327,6 @@ namespace Coffee.UIExtensions
}
base.OnEnable();
// Reset scale for upgrade.
if (m_ResetScaleOnEnable)
{
m_ResetScaleOnEnable = false;
transform.localScale = Vector3.one;
}
}
/// <summary>
@@ -311,7 +334,13 @@ namespace Coffee.UIExtensions
/// </summary>
protected override void OnDisable()
{
UpdateTracker();
_tracker.Clear();
if (autoScalingMode == AutoScalingMode.Transform && _isScaleStored)
{
transform.localScale = _storedScale;
}
_isScaleStored = false;
UIParticleUpdater.Unregister(this);
_renderers.ForEach(r => r.Reset());
UnregisterDirtyMaterialCallback(UpdateRendererMaterial);
@@ -326,36 +355,18 @@ namespace Coffee.UIExtensions
{
}
#if UNITY_EDITOR
protected override void OnValidate()
{
base.OnValidate();
UpdateTracker();
}
#endif
void ISerializationCallbackReceiver.OnBeforeSerialize()
{
}
void ISerializationCallbackReceiver.OnAfterDeserialize()
{
#pragma warning disable CS0612 // Type or member is obsolete
if (m_IgnoreCanvasScaler || m_AutoScaling)
{
m_IgnoreCanvasScaler = false;
m_AutoScaling = false;
m_AutoScalingMode = AutoScalingMode.Transform;
m_ResetScaleOnEnable = true;
#if UNITY_EDITOR
EditorApplication.delayCall += () =>
{
if (!this || !gameObject || !transform || Application.isPlaying) return;
transform.localScale = Vector3.one;
m_ResetScaleOnEnable = false;
EditorUtility.SetDirty(this);
};
#endif
}
if (m_AbsoluteMode)
@@ -363,31 +374,47 @@ namespace Coffee.UIExtensions
m_AbsoluteMode = false;
m_PositionMode = PositionMode.Absolute;
}
#pragma warning restore CS0612 // Type or member is obsolete
}
/// <summary>
/// Play the ParticleSystems.
/// </summary>
public void Play()
{
particles.Exec(p => p.Simulate(0, false, true));
isPaused = false;
}
/// <summary>
/// Pause the ParticleSystems.
/// </summary>
public void Pause()
{
particles.Exec(p => p.Pause());
isPaused = true;
}
/// <summary>
/// Unpause the ParticleSystems.
/// </summary>
public void Resume()
{
isPaused = false;
}
/// <summary>
/// Stop the ParticleSystems.
/// </summary>
public void Stop()
{
particles.Exec(p => p.Stop());
isPaused = true;
}
/// <summary>
/// Start emission of the ParticleSystems.
/// </summary>
public void StartEmission()
{
particles.Exec(p =>
@@ -397,6 +424,9 @@ namespace Coffee.UIExtensions
});
}
/// <summary>
/// Stop emission of the ParticleSystems.
/// </summary>
public void StopEmission()
{
particles.Exec(p =>
@@ -406,24 +436,52 @@ namespace Coffee.UIExtensions
});
}
/// <summary>
/// Clear the particles of the ParticleSystems.
/// </summary>
public void Clear()
{
particles.Exec(p => p.Clear());
isPaused = true;
}
/// <summary>
/// Get all base materials to render.
/// </summary>
public void GetMaterials(List<Material> result)
{
if (result == null) return;
for (var i = 0; i < _renderers.Count; i++)
{
var r = _renderers[i];
if (!r || !r.material) continue;
result.Add(r.material);
}
}
/// <summary>
/// Refresh UIParticle using the ParticleSystem instance.
/// </summary>
public void SetParticleSystemInstance(GameObject instance)
{
SetParticleSystemInstance(instance, true);
}
/// <summary>
/// Refresh UIParticle using the ParticleSystem instance.
/// </summary>
public void SetParticleSystemInstance(GameObject instance, bool destroyOldParticles)
{
if (!instance) return;
foreach (Transform child in transform)
var childCount = transform.childCount;
for (var i = 0; i < childCount; i++)
{
var go = child.gameObject;
var go = transform.GetChild(i).gameObject;
if (go.TryGetComponent<Camera>(out var cam) && cam == _bakeCamera) continue;
if (go.TryGetComponent<UIParticleRenderer>(out var _)) continue;
go.SetActive(false);
if (destroyOldParticles)
{
@@ -438,6 +496,10 @@ namespace Coffee.UIExtensions
RefreshParticles(instance);
}
/// <summary>
/// Refresh UIParticle using the prefab.
/// The prefab is automatically instantiated.
/// </summary>
public void SetParticleSystemPrefab(GameObject prefab)
{
if (!prefab) return;
@@ -445,16 +507,31 @@ namespace Coffee.UIExtensions
SetParticleSystemInstance(Instantiate(prefab.gameObject), true);
}
/// <summary>
/// Refresh UIParticle.
/// Collect ParticleSystems under the GameObject and refresh the UIParticle.
/// </summary>
public void RefreshParticles()
{
RefreshParticles(gameObject);
}
/// <summary>
/// Refresh UIParticle.
/// Collect ParticleSystems under the GameObject and refresh the UIParticle.
/// </summary>
private void RefreshParticles(GameObject root)
{
if (!root) return;
root.GetComponentsInChildren(true, particles);
particles.RemoveAll(x => x.GetComponentInParent<UIParticle>(true) != this);
for (var i = particles.Count - 1; 0 <= i; i--)
{
var ps = particles[i];
if (!ps || ps.GetComponentInParent<UIParticle>(true) != this)
{
particles.RemoveAt(i);
}
}
for (var i = 0; i < particles.Count; i++)
{
@@ -469,31 +546,39 @@ namespace Coffee.UIExtensions
RefreshParticles(particles);
}
public void RefreshParticles(List<ParticleSystem> particles)
/// <summary>
/// Refresh UIParticle using a list of ParticleSystems.
/// </summary>
public void RefreshParticles(List<ParticleSystem> particleSystems)
{
// Collect children UIParticleRenderer components.
// #246: Nullptr exceptions when using nested UIParticle components in hierarchy
_renderers.Clear();
foreach (Transform child in transform)
var childCount = transform.childCount;
for (var i = 0; i < childCount; i++)
{
var uiParticleRenderer = child.GetComponent<UIParticleRenderer>();
if (uiParticleRenderer != null)
var child = transform.GetChild(i);
if (child.TryGetComponent(out UIParticleRenderer uiParticleRenderer))
{
_renderers.Add(uiParticleRenderer);
}
}
// Reset the UIParticleRenderer components.
for (var i = 0; i < _renderers.Count; i++)
{
_renderers[i].Reset(i);
}
// Set the ParticleSystem to the UIParticleRenderer. If the trail is enabled, set it additionally.
var j = 0;
for (var i = 0; i < particles.Count; i++)
for (var i = 0; i < particleSystems.Count; i++)
{
var ps = particles[i];
var ps = particleSystems[i];
if (!ps) continue;
GetRenderer(j++).Set(this, ps, false);
// If the trail is enabled, set it additionally.
if (ps.trails.enabled)
{
GetRenderer(j++).Set(this, ps, true);
@@ -501,14 +586,32 @@ namespace Coffee.UIExtensions
}
}
internal void UpdateTransformScale()
internal void UpdateTransformScale(Vector3 ratio)
{
_tracker.Clear();
canvasScale = canvas.rootCanvas.transform.localScale.Inverse();
parentScale = transform.parent.lossyScale;
if (autoScalingMode != AutoScalingMode.Transform) return;
if (autoScalingMode != AutoScalingMode.Transform)
{
if (_isScaleStored)
{
transform.localScale = _storedScale;
}
var newScale = parentScale.Inverse();
if (transform.localScale != newScale)
_isScaleStored = false;
return;
}
var currentScale = transform.localScale;
if (!_isScaleStored)
{
_storedScale = currentScale.IsVisible() ? currentScale : Vector3.one;
_isScaleStored = true;
}
_tracker.Add(this, rectTransform, DrivenTransformProperties.Scale);
var newScale = parentScale.GetScaled(ratio).Inverse();
if (currentScale != newScale)
{
transform.localScale = newScale;
}
@@ -521,11 +624,10 @@ namespace Coffee.UIExtensions
for (var i = 0; i < _renderers.Count; i++)
{
var r = _renderers[i];
if (!r)
{
RefreshParticles(particles);
break;
}
if (r) continue;
RefreshParticles(particles);
break;
}
var bakeCamera = GetBakeCamera();
@@ -533,6 +635,7 @@ namespace Coffee.UIExtensions
{
var r = _renderers[i];
if (!r) continue;
r.UpdateMesh(bakeCamera);
}
}
@@ -584,64 +687,55 @@ namespace Coffee.UIExtensions
private Camera GetBakeCamera()
{
if (!canvas) return Camera.main;
// When render mode is ScreenSpaceCamera or WorldSpace, use world camera.
var root = canvas.rootCanvas;
if (root.renderMode != RenderMode.ScreenSpaceOverlay)
if (!useCustomView && canvas.renderMode != RenderMode.ScreenSpaceOverlay && canvas.rootCanvas.worldCamera)
{
return root.worldCamera ? root.worldCamera : Camera.main;
return canvas.rootCanvas.worldCamera;
}
// When render mode is ScreenSpaceOverlay, use ortho-camera.
if (!_orthoCamera)
if (_bakeCamera)
{
// Find existing ortho-camera.
foreach (Transform child in transform)
{
var cam = child.GetComponent<Camera>();
if (cam && cam.name == "[generated] UIParticleOverlayCamera")
{
_orthoCamera = cam;
break;
}
}
_bakeCamera.orthographicSize = useCustomView ? customViewSize : 10;
return _bakeCamera;
}
// Create ortho-camera.
if (!_orthoCamera)
// 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")
{
var go = new GameObject("[generated] UIParticleOverlayCamera")
{
hideFlags = HideFlags.HideAndDontSave
};
go.SetActive(false);
go.transform.SetParent(transform, false);
_orthoCamera = go.AddComponent<Camera>();
_orthoCamera.enabled = false;
_bakeCamera = cam;
break;
}
}
//
var size = ((RectTransform)root.transform).rect.size;
_orthoCamera.orthographicSize = Mathf.Max(size.x, size.y) * root.scaleFactor;
_orthoCamera.transform.SetPositionAndRotation(new Vector3(0, 0, -1000), Quaternion.identity);
_orthoCamera.orthographic = true;
_orthoCamera.farClipPlane = 2000f;
return _orthoCamera;
}
private void UpdateTracker()
{
#pragma warning disable CS0618 // Type or member is obsolete
if (!enabled || !autoScaling || autoScalingMode != AutoScalingMode.Transform)
#pragma warning restore CS0618 // Type or member is obsolete
// Create baking camera.
if (!_bakeCamera)
{
_tracker.Clear();
}
else
{
_tracker.Add(this, rectTransform, DrivenTransformProperties.Scale);
var go = new GameObject("[generated] UIParticle BakingCamera");
go.SetActive(false);
go.transform.SetParent(transform, false);
_bakeCamera = go.AddComponent<Camera>();
}
// Setup baking camera.
_bakeCamera.enabled = false;
_bakeCamera.orthographicSize = useCustomView ? customViewSize : 10;
_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;
_bakeCamera.gameObject.SetActive(false);
_bakeCamera.gameObject.hideFlags = HideFlags.HideAndDontSave;
return _bakeCamera;
}
}
}

View File

@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using Coffee.UIParticleExtensions;
using UnityEngine;
using UnityEngine.Events;
@@ -6,7 +7,7 @@ using UnityEngine.Events;
namespace Coffee.UIExtensions
{
[ExecuteAlways]
public class UIParticleAttractor : MonoBehaviour
public class UIParticleAttractor : MonoBehaviour, ISerializationCallbackReceiver
{
public enum Movement
{
@@ -22,8 +23,12 @@ namespace Coffee.UIExtensions
}
[SerializeField]
[HideInInspector]
private ParticleSystem m_ParticleSystem;
[SerializeField]
private List<ParticleSystem> m_ParticleSystems = new List<ParticleSystem>();
[Range(0.1f, 10f)]
[SerializeField]
private float m_DestinationRadius = 1;
@@ -45,7 +50,7 @@ namespace Coffee.UIExtensions
[SerializeField]
private UnityEvent m_OnAttracted;
private UIParticle _uiParticle;
private List<UIParticle> _uiParticles = new List<UIParticle>();
public float destinationRadius
{
@@ -84,25 +89,46 @@ namespace Coffee.UIExtensions
}
/// <summary>
/// The target ParticleSystem to attract.
/// The target ParticleSystems to attract. Use <see cref="AddParticleSystem"/> and
/// <see cref="RemoveParticleSystem"/> to modify the list.
/// </summary>
#if UNITY_EDITOR
public new ParticleSystem particleSystem
#else
public ParticleSystem particleSystem
#endif
public IReadOnlyList<ParticleSystem> particleSystems => m_ParticleSystems;
public void AddParticleSystem(ParticleSystem ps)
{
get => m_ParticleSystem;
set
if (m_ParticleSystems == null)
{
m_ParticleSystem = value;
ApplyParticleSystem();
m_ParticleSystems = new List<ParticleSystem>();
}
var i = m_ParticleSystems.IndexOf(ps);
if (0 <= i) return; // Already added: skip
m_ParticleSystems.Add(ps);
_uiParticles.Clear();
}
public void RemoveParticleSystem(ParticleSystem ps)
{
if (m_ParticleSystems == null)
{
return;
}
var i = m_ParticleSystems.IndexOf(ps);
if (i < 0) return; // Not found. skip
m_ParticleSystems.RemoveAt(i);
_uiParticles.Clear();
}
private void Awake()
{
UpgradeIfNeeded();
}
private void OnEnable()
{
ApplyParticleSystem();
UIParticleUpdater.Register(this);
}
@@ -113,85 +139,96 @@ namespace Coffee.UIExtensions
private void OnDestroy()
{
_uiParticle = null;
m_ParticleSystem = null;
_uiParticles = null;
m_ParticleSystems = null;
}
internal void Attract()
{
if (m_ParticleSystem == null) return;
// Collect UIParticle if needed (same size as m_ParticleSystems)
CollectUIParticlesIfNeeded();
var count = m_ParticleSystem.particleCount;
if (count == 0) return;
var particles = ParticleSystemExtensions.GetParticleArray(count);
m_ParticleSystem.GetParticles(particles, count);
var dstPos = GetDestinationPosition();
for (var i = 0; i < count; i++)
for (var particleIndex = 0; particleIndex < this.m_ParticleSystems.Count; particleIndex++)
{
// Attracted
var p = particles[i];
if (0f < p.remainingLifetime && Vector3.Distance(p.position, dstPos) < m_DestinationRadius)
{
p.remainingLifetime = 0f;
particles[i] = p;
var particleSystem = m_ParticleSystems[particleIndex];
if (m_OnAttracted != null)
// Skip: The ParticleSystem is not active
if (particleSystem == null || !particleSystem.gameObject.activeInHierarchy) continue;
// Skip: No active particles
var count = particleSystem.particleCount;
if (count == 0) continue;
var particles = ParticleSystemExtensions.GetParticleArray(count);
particleSystem.GetParticles(particles, count);
var uiParticle = _uiParticles[particleIndex];
var dstPos = this.GetDestinationPosition(uiParticle, particleSystem);
for (var i = 0; i < count; i++)
{
// Attracted
var p = particles[i];
if (0f < p.remainingLifetime && Vector3.Distance(p.position, dstPos) < this.m_DestinationRadius)
{
try
p.remainingLifetime = 0f;
particles[i] = p;
if (this.m_OnAttracted != null)
{
m_OnAttracted.Invoke();
}
catch (Exception e)
{
Debug.LogException(e);
try
{
this.m_OnAttracted.Invoke();
}
catch (Exception e)
{
Debug.LogException(e);
}
}
continue;
}
continue;
// Calc attracting time
var delayTime = p.startLifetime * this.m_DelayRate;
var duration = p.startLifetime - delayTime;
var time = Mathf.Max(0, p.startLifetime - p.remainingLifetime - delayTime);
// Delay
if (time <= 0) continue;
// Attract
p.position = this.GetAttractedPosition(p.position, dstPos, duration, time);
p.velocity *= 0.5f;
particles[i] = p;
}
// Calc attracting time
var delayTime = p.startLifetime * m_DelayRate;
var duration = p.startLifetime - delayTime;
var time = Mathf.Max(0, p.startLifetime - p.remainingLifetime - delayTime);
// Delay
if (time <= 0) continue;
// Attract
p.position = GetAttractedPosition(p.position, dstPos, duration, time);
p.velocity *= 0.5f;
particles[i] = p;
particleSystem.SetParticles(particles, count);
}
m_ParticleSystem.SetParticles(particles, count);
}
private Vector3 GetDestinationPosition()
private Vector3 GetDestinationPosition(UIParticle uiParticle, ParticleSystem particleSystem)
{
var isUI = _uiParticle && _uiParticle.enabled;
var psPos = m_ParticleSystem.transform.position;
var isUI = uiParticle && uiParticle.enabled;
var psPos = particleSystem.transform.position;
var attractorPos = transform.position;
var dstPos = attractorPos;
var isLocalSpace = m_ParticleSystem.IsLocalSpace();
var isLocalSpace = particleSystem.IsLocalSpace();
if (isLocalSpace)
{
dstPos = m_ParticleSystem.transform.InverseTransformPoint(dstPos);
dstPos = particleSystem.transform.InverseTransformPoint(dstPos);
}
if (isUI)
{
var inverseScale = _uiParticle.parentScale.Inverse();
var scale3d = _uiParticle.scale3DForCalc;
var inverseScale = uiParticle.parentScale.Inverse();
var scale3d = uiParticle.scale3DForCalc;
dstPos = dstPos.GetScaled(inverseScale, scale3d.Inverse());
// Relative mode
if (_uiParticle.positionMode == UIParticle.PositionMode.Relative)
if (uiParticle.positionMode == UIParticle.PositionMode.Relative)
{
var diff = _uiParticle.transform.position - psPos;
var diff = uiParticle.transform.position - psPos;
diff.Scale(scale3d - inverseScale);
diff.Scale(scale3d.Inverse());
dstPos += diff;
@@ -237,25 +274,59 @@ namespace Coffee.UIExtensions
return Vector3.MoveTowards(current, target, speed);
}
private void ApplyParticleSystem()
private void CollectUIParticlesIfNeeded()
{
_uiParticle = null;
if (m_ParticleSystem == null)
{
#if UNITY_EDITOR
if (Application.isPlaying)
#endif
{
Debug.LogError("No particle system attached to particle attractor script", this);
}
if (m_ParticleSystems.Count == 0 || _uiParticles.Count != 0) return;
return;
// Expand capacity
if (_uiParticles.Capacity < m_ParticleSystems.Capacity)
{
_uiParticles.Capacity = m_ParticleSystems.Capacity;
}
_uiParticle = m_ParticleSystem.GetComponentInParent<UIParticle>(true);
if (_uiParticle && !_uiParticle.particles.Contains(m_ParticleSystem))
// Find UIParticle that controls the ParticleSystem
for (var i = 0; i < m_ParticleSystems.Count; i++)
{
_uiParticle = null;
var ps = m_ParticleSystems[i];
if (ps == null)
{
_uiParticles.Add(null);
continue;
}
var uiParticle = ps.GetComponentInParent<UIParticle>(true);
_uiParticles.Add(uiParticle.particles.Contains(ps) ? uiParticle : null);
}
}
#if UNITY_EDITOR
private void OnValidate()
{
_uiParticles.Clear();
}
#endif
void ISerializationCallbackReceiver.OnBeforeSerialize()
{
UpgradeIfNeeded();
}
void ISerializationCallbackReceiver.OnAfterDeserialize()
{
}
private void UpgradeIfNeeded()
{
// Multiple ParticleSystems support: from 'm_ParticleSystem' to 'm_ParticleSystems'
if (m_ParticleSystem != null)
{
if (!m_ParticleSystems.Contains(m_ParticleSystem))
{
m_ParticleSystems.Add(m_ParticleSystem);
}
m_ParticleSystem = null;
Debug.Log($"Upgraded!");
}
}
}

View File

@@ -31,6 +31,7 @@ namespace Coffee.UIExtensions
private Material _currentMaterialForRendering;
private bool _delay;
private int _index;
private bool _isPrevStored;
private bool _isTrail;
private Bounds _lastBounds;
private Material _modifiedMaterial;
@@ -40,7 +41,7 @@ namespace Coffee.UIExtensions
private Vector3 _prevPsPos;
private Vector3 _prevScale;
private Vector2Int _prevScreenSize;
private bool _prewarm;
private bool _preWarm;
private ParticleSystemRenderer _renderer;
public override Texture mainTexture => _isTrail ? null : _particleSystem.GetTextureForSprite();
@@ -110,8 +111,7 @@ namespace Coffee.UIExtensions
if (this && isActiveAndEnabled)
{
material = null;
workerMesh.Clear();
canvasRenderer.SetMesh(workerMesh);
canvasRenderer.Clear();
_lastBounds = new Bounds();
enabled = false;
}
@@ -146,6 +146,7 @@ namespace Coffee.UIExtensions
ModifiedMaterial.Remove(_modifiedMaterial);
_modifiedMaterial = null;
_currentMaterialForRendering = null;
_isPrevStored = false;
}
public static UIParticleRenderer AddRenderer(UIParticle parent, int index)
@@ -219,20 +220,20 @@ namespace Coffee.UIExtensions
gameObject.layer = parent.gameObject.layer;
_particleSystem = ps;
_prewarm = _particleSystem.main.prewarm;
_preWarm = _particleSystem.main.prewarm;
#if UNITY_EDITOR
if (Application.isPlaying)
#endif
{
if (_particleSystem.isPlaying || _prewarm)
if (_particleSystem.isPlaying || _preWarm)
{
_particleSystem.Clear();
_particleSystem.Pause();
}
}
_renderer = ps.GetComponent<ParticleSystemRenderer>();
ps.TryGetComponent(out _renderer);
_renderer.enabled = false;
//_emitter = emitter;
@@ -328,7 +329,16 @@ namespace Coffee.UIExtensions
// Bake mesh.
Profiler.BeginSample("[UIParticleRenderer] Bake Mesh");
if (_isTrail && _parent.canSimulate && 0 < s_CombineInstances[0].mesh.vertexCount)
s_CombineInstances[0].mesh.Clear(false);
// Assertion failed on expression: 'ps->array_size()' #278
var extends = s_CombineInstances[0].mesh.bounds.extents.x;
if (!float.IsNaN(extends) && !float.IsInfinity(extends) && 0 < extends)
{
s_CombineInstances[0].mesh.RecalculateBounds();
}
if (_isTrail && _parent.canSimulate && 0 < _particleSystem.particleCount)
{
#if PS_BAKE_API_V2
_renderer.BakeTrailsMesh(s_CombineInstances[0].mesh, bakeCamera,
@@ -337,7 +347,7 @@ namespace Coffee.UIExtensions
_renderer.BakeTrailsMesh(s_CombineInstances[0].mesh, bakeCamera, true);
#endif
}
else if (_renderer.CanBakeMesh())
else if (!_isTrail && _renderer.CanBakeMesh())
{
_particleSystem.ValidateShape();
#if PS_BAKE_API_V2
@@ -347,15 +357,10 @@ namespace Coffee.UIExtensions
_renderer.BakeMesh(s_CombineInstances[0].mesh, bakeCamera, true);
#endif
}
else
{
s_CombineInstances[0].mesh.Clear(false);
}
// Too many vertices to render.
if (65535 <= s_CombineInstances[0].mesh.vertexCount)
{
s_CombineInstances[0].mesh.Clear(false);
Debug.LogErrorFormat(this,
"Too many vertices to render. index={0}, isTrail={1}, vertexCount={2}(>=65535)",
_index,
@@ -517,9 +522,10 @@ namespace Coffee.UIExtensions
var scale = _parent.scale3DForCalc.GetScaled(_parent.parentScale);
if (_parent.autoScalingMode == UIParticle.AutoScalingMode.UIParticle
&& _particleSystem.main.scalingMode == ParticleSystemScalingMode.Local)
&& _particleSystem.main.scalingMode == ParticleSystemScalingMode.Local
&& _parent.canvas)
{
scale = scale.GetScaled(_parent.canvas.transform.localScale);
scale = scale.GetScaled(_parent.canvas.rootCanvas.transform.localScale);
}
Profiler.EndSample();
@@ -556,10 +562,7 @@ namespace Coffee.UIExtensions
return Matrix4x4.Scale(scale);
case ParticleSystemSimulationSpace.Custom:
return Matrix4x4.Translate(_particleSystem.main.customSimulationSpace.position.GetScaled(scale))
//* Matrix4x4.Translate(wpos)
* Matrix4x4.Scale(scale)
//* Matrix4x4.Translate(-wpos)
;
* Matrix4x4.Scale(scale);
default:
throw new NotSupportedException();
}
@@ -575,15 +578,16 @@ namespace Coffee.UIExtensions
var screenSize = new Vector2Int(Screen.width, Screen.height);
var isWorldSpace = _particleSystem.IsWorldSpace();
var canvasScale = _parent.canvas ? _parent.canvas.scaleFactor : 1f;
var resolutionChanged = _prevScreenSize != screenSize || _prevCanvasScale != canvasScale;
if (resolutionChanged && isWorldSpace)
var resolutionChanged = _prevScreenSize != screenSize
|| !Mathf.Approximately(_prevCanvasScale, canvasScale);
if (resolutionChanged && isWorldSpace && _isPrevStored)
{
// Update particle array size and get particles.
var size = _particleSystem.particleCount;
var particles = ParticleSystemExtensions.GetParticleArray(size);
_particleSystem.GetParticles(particles, size);
// Resolusion resolver:
// Resolution resolver:
// (psPos / scale) / (prevPsPos / prevScale) -> psPos * scale.inv * prevPsPos.inv * prevScale
var modifier = psPos.GetScaled(
scale.Inverse(),
@@ -602,6 +606,7 @@ namespace Coffee.UIExtensions
_delay = true;
_prevScale = scale;
_prevPsPos = psPos;
_isPrevStored = true;
}
_prevCanvasScale = canvas ? canvas.scaleFactor : 1f;
@@ -617,23 +622,25 @@ namespace Coffee.UIExtensions
? Time.unscaledDeltaTime
: Time.deltaTime;
// Prewarm:
if (0 < deltaTime && _prewarm)
// Pre-warm:
if (0 < deltaTime && _preWarm)
{
deltaTime += main.duration;
_prewarm = false;
_preWarm = false;
}
// get world position.
var isLocalSpace = _particleSystem.IsLocalSpace();
var psTransform = _particleSystem.transform;
var originLocalPosition = psTransform.localPosition;
var originLocalRotation = psTransform.localRotation;
var originWorldPosition = psTransform.position;
var originWorldRotation = psTransform.rotation;
var emission = _particleSystem.emission;
var rateOverDistance = emission.enabled
&& 0 < emission.rateOverDistance.constant
&& 0 < emission.rateOverDistanceMultiplier;
if (rateOverDistance && !paused)
if (rateOverDistance && !paused && _isPrevStored)
{
// (For rate-over-distance emission,) Move to previous scaled position, simulate (delta = 0).
var prevScaledPos = isLocalSpace
@@ -649,7 +656,8 @@ namespace Coffee.UIExtensions
: originWorldPosition.GetScaled(scale.Inverse());
psTransform.SetPositionAndRotation(scaledPos, originWorldRotation);
_particleSystem.Simulate(deltaTime, false, false, false);
psTransform.SetPositionAndRotation(originWorldPosition, originWorldRotation);
psTransform.localPosition = originLocalPosition;
psTransform.localRotation = originLocalRotation;
}
#if UNITY_EDITOR

View File

@@ -1,4 +1,5 @@
using System.Collections.Generic;
using Coffee.UIParticleExtensions;
using UnityEditor;
using UnityEngine;
@@ -8,7 +9,7 @@ namespace Coffee.UIExtensions
{
private static readonly List<UIParticle> s_ActiveParticles = new List<UIParticle>();
private static readonly List<UIParticleAttractor> s_ActiveAttractors = new List<UIParticleAttractor>();
private static readonly HashSet<int> s_UpdatedGroupIds = new HashSet<int>();
private static readonly Dictionary<int, Vector3> s_GroupScales = new Dictionary<int, Vector3>();
private static int s_FrameCount;
public static int uiParticleCount => s_ActiveParticles.Count;
@@ -39,8 +40,9 @@ namespace Coffee.UIExtensions
#if UNITY_EDITOR
[InitializeOnLoadMethod]
#else
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
#endif
[RuntimeInitializeOnLoadMethod]
private static void InitializeOnLoad()
{
Canvas.willRenderCanvases -= Refresh;
@@ -52,15 +54,17 @@ namespace Coffee.UIExtensions
// Do not allow it to be called in the same frame.
if (s_FrameCount == Time.frameCount) return;
s_FrameCount = Time.frameCount;
s_GroupScales.Clear();
// Simulate -> Primary
for (var i = 0; i < s_ActiveParticles.Count; i++)
{
// Process only primary UIParticles.
var uip = s_ActiveParticles[i];
if (!uip || !uip.canvas || !uip.isPrimary || s_UpdatedGroupIds.Contains(uip.groupId)) continue;
if (!uip || !uip.canvas || !uip.isPrimary || s_GroupScales.ContainsKey(uip.groupId)) continue;
s_UpdatedGroupIds.Add(uip.groupId);
uip.UpdateTransformScale();
s_GroupScales.Add(uip.groupId, uip.transform.parent.lossyScale);
uip.UpdateTransformScale(Vector3.one);
uip.UpdateRenderers();
}
@@ -70,21 +74,31 @@ namespace Coffee.UIExtensions
var uip = s_ActiveParticles[i];
if (!uip || !uip.canvas) continue;
uip.UpdateTransformScale();
// Case 1: Not using mesh sharing.
if (!uip.useMeshSharing)
{
uip.UpdateTransformScale(Vector3.one);
uip.UpdateRenderers();
}
else if (!s_UpdatedGroupIds.Contains(uip.groupId))
// Case 2: Using mesh sharing as primary.
else if (!s_GroupScales.TryGetValue(uip.groupId, out var groupScale))
{
s_UpdatedGroupIds.Add(uip.groupId);
s_GroupScales.Add(uip.groupId, uip.transform.parent.lossyScale);
uip.UpdateTransformScale(Vector3.one);
uip.UpdateRenderers();
}
// Case 3: Using mesh sharing as replica. (Only scaling)
else
{
var parentScale = uip.transform.parent.lossyScale;
var ratio = parentScale.IsVisible()
? groupScale.GetScaled(parentScale.Inverse())
: Vector3.one;
ratio = Vector3.one;
uip.UpdateTransformScale(ratio);
}
}
s_UpdatedGroupIds.Clear();
// Attract
for (var i = 0; i < s_ActiveAttractors.Count; i++)
{

View File

@@ -51,7 +51,11 @@ namespace Coffee.UIExtensions.Demo
public void EnableAnimations(bool flag)
{
#if UNITY_2023_1_OR_NEWER
foreach (var animator in FindObjectsByType<Animator>(FindObjectsInactive.Include, FindObjectsSortMode.None))
#else
foreach (var animator in FindObjectsOfType<Animator>())
#endif
{
animator.enabled = flag;
}
@@ -79,7 +83,11 @@ namespace Coffee.UIExtensions.Demo
public void UIParticle_Scale(float scale)
{
#if UNITY_2023_1_OR_NEWER
foreach (var uip in FindObjectsByType<UIParticle>(FindObjectsInactive.Include, FindObjectsSortMode.None))
#else
foreach (var uip in FindObjectsOfType<UIParticle>())
#endif
{
uip.scale = scale;
}
@@ -87,7 +95,11 @@ namespace Coffee.UIExtensions.Demo
public void ParticleSystem_WorldSpaseSimulation(bool flag)
{
#if UNITY_2023_1_OR_NEWER
foreach (var p in FindObjectsByType<ParticleSystem>(FindObjectsInactive.Include, FindObjectsSortMode.None))
#else
foreach (var p in FindObjectsOfType<ParticleSystem>())
#endif
{
var main = p.main;
main.simulationSpace = flag
@@ -123,7 +135,11 @@ namespace Coffee.UIExtensions.Demo
public void ParticleSystem_SetScale(float scale)
{
#if UNITY_2023_1_OR_NEWER
foreach (var ps in FindObjectsByType<ParticleSystem>(FindObjectsInactive.Include, FindObjectsSortMode.None))
#else
foreach (var ps in FindObjectsOfType<ParticleSystem>())
#endif
{
ps.transform.localScale = new Vector3(scale, scale, scale);
}

View File

@@ -42,12 +42,12 @@ TextureImporter:
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
spriteMeshType: 0
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
spriteGenerateFallbackPhysicsShape: 0
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1

View File

@@ -27,7 +27,7 @@ TextureImporter:
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
textureFormat: 4
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
@@ -42,12 +42,12 @@ TextureImporter:
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
spriteMeshType: 0
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
spriteGenerateFallbackPhysicsShape: 0
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1

View File

@@ -42,12 +42,12 @@ TextureImporter:
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
spriteMeshType: 0
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
spriteGenerateFallbackPhysicsShape: 0
alphaUsage: 0
alphaIsTransparency: 1
spriteTessellationDetail: -1

View File

@@ -27,7 +27,7 @@ TextureImporter:
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: -1
textureFormat: 4
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
@@ -42,12 +42,12 @@ TextureImporter:
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
spriteMeshType: 0
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
spriteGenerateFallbackPhysicsShape: 0
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1

View File

@@ -14461,7 +14461,7 @@ Canvas:
m_GameObject: {fileID: 1074082869}
m_Enabled: 1
serializedVersion: 3
m_RenderMode: 0
m_RenderMode: 1
m_Camera: {fileID: 1023393581}
m_PlaneDistance: 100
m_PixelPerfect: 0

View File

@@ -2,7 +2,7 @@
"name": "com.coffee.ui-particle",
"displayName": "UI Particle",
"description": "This package provides a component to render particle effects for uGUI.\nThe particle rendering is maskable and sortable, without the need for an extra Camera, RenderTexture, or Canvas.",
"version": "4.6.2",
"version": "4.9.1",
"unity": "2018.2",
"license": "MIT",
"repository": {

View File

@@ -520,7 +520,7 @@ PlayerSettings:
webGLTemplate: APPLICATION:Default
webGLAnalyzeBuildSize: 0
webGLUseEmbeddedResources: 0
webGLCompressionFormat: 1
webGLCompressionFormat: 2
webGLLinkerTarget: 0
webGLThreadsSupport: 0
scriptingDefineSymbols: