Compare commits

..

8 Commits

Author SHA1 Message Date
mob-sakai
64a050f17c fix: Support for skipping "reload domain"
close #406
2026-06-24 19:56:50 +09:00
mob-sakai
d6d36006ad docs: update readme 2026-06-24 19:56:50 +09:00
mob-sakai
63d5eedde1 fix: rename UIParticleProjectSettings.enableLinearToGamma to autoColorCorrection 2026-06-24 19:56:50 +09:00
mob-sakai
c05c1d5f21 fix: UI/Additive shader does not support RectMask2D softness. 2026-06-24 19:56:50 +09:00
mob-sakai
738021a9b3 fix: there is a compilation error in Unity 2019.2 or earlier
close #407
2026-06-24 19:56:50 +09:00
mob-sakai
b4cac73fb1 chore: update internal 2026-06-24 19:56:50 +09:00
mob-sakai
32c9926f10 feat: preview the ParticleSystem playback when selecting a UIParticle in the Editor 2026-06-24 19:56:50 +09:00
mob-sakai
f961b8dc89 chore: fix workflow for pwn request 2026-06-12 16:27:44 +09:00
27 changed files with 798 additions and 236 deletions

View File

@@ -1,28 +0,0 @@
name: 🚀 Deploy with Zip
on:
workflow_dispatch:
inputs:
zip:
description: "The url to the zip file"
required: true
jobs:
deploy:
name: 🚀 Deploy
runs-on: ubuntu-latest
permissions:
pages: write
id-token: write
steps:
- name: 📦 Download zip file To '_site'
run: |
curl -L ${{ github.event.inputs.zip }} -o _site.zip
unzip _site.zip -d _site
find _site -name __MACOSX | xargs rm -rf
- name: 📦 Upload '_site'
uses: actions/upload-pages-artifact@v3
- name: 🚀 Deploy To GitHub Pages
uses: actions/deploy-pages@v4

View File

@@ -5,9 +5,8 @@ on:
workflow_dispatch: workflow_dispatch:
push: push:
branches: branches:
- preview - release
- main - release-*
- v*.x
tags-ignore: tags-ignore:
- "**" - "**"
@@ -23,6 +22,9 @@ jobs:
channel: ${{ steps.release.outputs.new_release_channel }} channel: ${{ steps.release.outputs.new_release_channel }}
released: ${{ steps.release.outputs.new_release_published }} released: ${{ steps.release.outputs.new_release_published }}
tag: ${{ steps.release.outputs.new_release_git_tag }} tag: ${{ steps.release.outputs.new_release_git_tag }}
version: ${{ steps.release.outputs.new_release_version }}
merge_to: ${{ steps.summary.outputs.merge_to }}
split_to: ${{ steps.summary.outputs.split_to }}
steps: steps:
- name: 🚚 Checkout (${{ github.ref_name }}) - name: 🚚 Checkout (${{ github.ref_name }})
uses: actions/checkout@v6 uses: actions/checkout@v6
@@ -36,9 +38,64 @@ jobs:
@semantic-release/changelog @semantic-release/changelog
@semantic-release/git @semantic-release/git
env: env:
GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} 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 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 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 "🔖 New release git tag: '${{ steps.release.outputs.new_release_git_tag }}'" | tee -a $GITHUB_STEP_SUMMARY
if [ '${{ steps.release.outputs.new_release_published }}' = 'false' ]; then
echo "No new release published." | tee -a $GITHUB_STEP_SUMMARY
elif [ '${{ github.ref_name }}' = 'release' ]; then
echo "merge_to=develop" | tee -a $GITHUB_OUTPUT $GITHUB_STEP_SUMMARY
echo "split_to=main" | tee -a $GITHUB_OUTPUT $GITHUB_STEP_SUMMARY
else
channel=$(echo ${{ github.ref_name }} | sed 's/^release-//')
echo "merge_to=develop-${channel}" | tee -a $GITHUB_OUTPUT $GITHUB_STEP_SUMMARY
echo "split_to=${channel}" | tee -a $GITHUB_OUTPUT $GITHUB_STEP_SUMMARY
fi
merge-to:
if: needs.release.outputs.merge_to != ''
needs: release
name: 🔀 Merge to ${{ needs.release.outputs.merge_to }}
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: 🚚 Checkout (${{ needs.release.outputs.merge_to }})
uses: actions/checkout@v5
with:
ref: ${{ needs.release.outputs.merge_to }}
fetch-depth: 0
- name: 🔀 Merge '${{ needs.release.outputs.tag }}' into '${{ needs.release.outputs.merge_to }}'
run: |
git config --local user.email "github-actions[bot]@users.noreply.github.com"
git config --local user.name "github-actions[bot]"
git merge ${{ needs.release.outputs.tag }}
git push origin ${{ needs.release.outputs.merge_to }}
split-to:
if: needs.release.outputs.split_to != ''
needs: release
name: 🔀 Split package to ${{ needs.release.outputs.split_to }}
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: 🚚 Checkout (${{ needs.release.outputs.tag }})
uses: actions/checkout@v5
with:
ref: ${{ needs.release.outputs.tag }}
fetch-depth: 0
- name: 🔀 Split subtree 'Packages/src' to '${{ needs.release.outputs.split_to }}'
run: |
split_to=${{ needs.release.outputs.split_to }}
git branch $split_to origin/$split_to
git subtree split --prefix=Packages/src --branch $split_to
git tag ${{ needs.release.outputs.version }} $split_to
git push origin ${{ needs.release.outputs.version }} $split_to:$split_to

View File

@@ -27,7 +27,7 @@ on:
- "!*" - "!*"
paths-ignore: paths-ignore:
- "**.md" - "**.md"
pull_request_target: pull_request:
types: types:
- opened - opened
- reopened - reopened
@@ -39,16 +39,29 @@ jobs:
setup: setup:
name: ⚙️ Setup name: ⚙️ Setup
runs-on: ubuntu-latest runs-on: ubuntu-latest
permissions: {} # No permissions needed for setup job
outputs: outputs:
unityVersions: ${{ steps.setup.outputs.unityVersions }} unityVersions: ${{ steps.setup.outputs.unityVersions }}
steps: steps:
- name: 🔑 Secrets check
run: |
if [ -z "$UNITY_EMAIL" ] || [ -z "$UNITY_PASSWORD" ] || [ -z "UNITY_LICENSE" ]; then
echo "Error: UNITY_EMAIL, UNITY_PASSWORD, and UNITY_LICENSE secrets must be set." | tee -a $GITHUB_STEP_SUMMARY >&2
echo "Error: See https://game.ci/docs/github/test-runner#basic-setup" | tee -a $GITHUB_STEP_SUMMARY >&2
echo "Error: Set the secrets at ${{ github.server_url }}/${{ github.repository }}/settings/secrets/actions" | tee -a $GITHUB_STEP_SUMMARY >&2
exit 1
fi
env:
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }}
- name: ⚙️ Find target Unity versions - name: ⚙️ Find target Unity versions
id: setup id: setup
run: | run: |
echo "==== Target Unity Versions ====" echo "==== Target Unity Versions ===="
LATEST_VERSIONS=`npx unity-changeset@latest list --versions --latest-patch --min ${MINIMUM_VERSION} --json --all --ignore-alpha` LATEST_VERSIONS=`npx -y unity-changeset@latest list --json --versions --all --latest-patch --ignore-alpha --min ${MINIMUM_VERSION}`
if [ "${{ inputs.usePeriodVersions }}" = "true" ]; then if [ "${{ inputs.usePeriodVersions }}" = "true" ]; then
ADDITIONAL_VERSIONS=`npx unity-changeset list --versions --grep '0f' --min ${MINIMUM_VERSION} --json --ignore-alpha` ADDITIONAL_VERSIONS=`npx -y unity-changeset@latest list --json --versions --ignore-alpha --min ${MINIMUM_VERSION} --grep '0f'`
else else
ADDITIONAL_VERSIONS=[] ADDITIONAL_VERSIONS=[]
fi fi
@@ -66,29 +79,13 @@ jobs:
needs: setup needs: setup
strategy: strategy:
fail-fast: false fail-fast: false
max-parallel: 6 max-parallel: 8
matrix: matrix:
unityVersion: ${{ fromJson(needs.setup.outputs.unityVersions) }} unityVersion: ${{ fromJson(needs.setup.outputs.unityVersions) }}
steps: steps:
- name: 🚚 Checkout ($${{ github.ref }}) - name: 🚚 Checkout ($${{ github.ref }})
if: github.event_name == 'push'
uses: actions/checkout@v6 uses: actions/checkout@v6
- name: 🚚 Checkout pull request (pull_request_target)
if: github.event_name == 'pull_request_target'
uses: actions/checkout@v6
with:
ref: ${{ github.event.pull_request.head.sha }}
fetch-depth: 0
- name: 🚚 Marge pull request (pull_request_target)
if: github.event_name == 'pull_request_target'
run: |
git config user.name "GitHub Actions"
git config user.email "actions@github.com"
git rebase ${{ github.event.pull_request.base.sha }}
git log --oneline -n 10
- name: 📥 Cache library - name: 📥 Cache library
uses: actions/cache@v5 uses: actions/cache@v5
with: with:

View File

@@ -3,7 +3,7 @@
"com.coffee.development": "https://github.com/mob-sakai/Coffee.Internal.git?path=Packages/Development", "com.coffee.development": "https://github.com/mob-sakai/Coffee.Internal.git?path=Packages/Development",
"com.coffee.minimal-resource": "https://github.com/mob-sakai/Coffee.Internal.git?path=Packages/MinimalResource", "com.coffee.minimal-resource": "https://github.com/mob-sakai/Coffee.Internal.git?path=Packages/MinimalResource",
"com.coffee.nano-monitor": "https://github.com/mob-sakai/Coffee.Internal.git?path=Packages/NanoMonitor", "com.coffee.nano-monitor": "https://github.com/mob-sakai/Coffee.Internal.git?path=Packages/NanoMonitor",
"com.unity.ide.rider": "3.0.31", "com.unity.ide.rider": "3.0.36",
"com.unity.test-framework": "1.1.33", "com.unity.test-framework": "1.1.33",
"com.unity.modules.animation": "1.0.0", "com.unity.modules.animation": "1.0.0",
"com.unity.modules.physics": "1.0.0" "com.unity.modules.physics": "1.0.0"

View File

@@ -40,7 +40,7 @@
"url": "https://packages.unity.com" "url": "https://packages.unity.com"
}, },
"com.unity.ide.rider": { "com.unity.ide.rider": {
"version": "3.0.31", "version": "3.0.36",
"depth": 0, "depth": 0,
"source": "registry", "source": "registry",
"dependencies": { "dependencies": {

View File

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

View File

@@ -1,27 +1,46 @@
# [5.0.0-preview.17](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/5.0.0-preview.16...5.0.0-preview.17) (2026-06-08) ## [4.12.2](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.12.1...v4.12.2) (2026-06-08)
### Bug Fixes ### Bug Fixes
* add `meshCleared` flag to optimize mesh clearing ([859fa20](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/859fa20d297c3f44e3361f20dbb7ce966407e03e)) * add `meshCleared` flag to optimize mesh clearing ([859fa20](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/859fa20d297c3f44e3361f20dbb7ce966407e03e))
* add early return for case where subEmitter module is disabled ([d1386a1](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/d1386a12216743a6e09f1b9b87bea1dfcf7702e4))
* avoid endless loop ([eb2e862](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/eb2e862e80e549c8cf16ddfed776c101c2413bac)), closes [#392](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/392)
* fix icon ([a9461ec](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/a9461ecb4d40d7fe878e12465d6e38faae7ae65b))
* fix Unity6.5 compile errors and warnings ([a5ee687](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/a5ee6878212be2fc4d7b48879426f239e8753009)), closes [#400](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/400) * fix Unity6.5 compile errors and warnings ([a5ee687](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/a5ee6878212be2fc4d7b48879426f239e8753009)), closes [#400](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/400)
* fix URL link in README ([a79ffb2](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/a79ffb2c2b4c26f23d2925cb18674fda5d8bc9cb))
* fix URL link in README ([1c8c65d](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/1c8c65d25e7f6fe7b1d20da4461333df8fc7578e)), closes [#376](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/376)
* fix: second and subsequent bursts not displayed when world simulation and non-looping ([df2f3ca](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/df2f3caafbe279f1457d74f8183cb561ac14aa17)), closes [#326](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/326)
* ignore "EditorOnly" tagged gameObjects on refresh ([031d46a](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/031d46a3216c942d2d1a6ccfadf5f0b9e3ce3006))
* potential access to UIParticleRenderer that has already been destroyed ([b740dd6](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/b740dd662d423c6bef849662ce1b0bfbb4940ed4)), closes [#403](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/403) * potential access to UIParticleRenderer that has already been destroyed ([b740dd6](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/b740dd662d423c6bef849662ce1b0bfbb4940ed4)), closes [#403](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/403)
* UIParticle in canvas with 0f-0.01f alpha value does not start to play until alpha value is greater than 0.01f, causes play calls to be delayed unintentionally if canvas alpha value is set to mentioned value range ([38aec2e](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/38aec2ea1afd77677d629c86665a3342d92e49d9))
* updated support for some changed menu paths ([f8ac986](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/f8ac9869f141238169730e74f5d65c4fc6081f51)), closes [#397](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/397) * updated support for some changed menu paths ([f8ac986](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/f8ac9869f141238169730e74f5d65c4fc6081f51)), closes [#397](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/397)
## [4.12.1](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.12.0...v4.12.1) (2026-03-24)
### Bug Fixes
* ignore "EditorOnly" tagged gameObjects on refresh ([031d46a](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/031d46a3216c942d2d1a6ccfadf5f0b9e3ce3006))
# [4.12.0](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.11.4...v4.12.0) (2026-03-24)
### Features ### Features
* explicit null checks ([5384f61](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/5384f61c569e9f78ff9d5b45acfc6f5c2f021a87)) * explicit null checks ([5384f61](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/5384f61c569e9f78ff9d5b45acfc6f5c2f021a87))
# [5.0.0-preview.16](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/5.0.0-preview.15...5.0.0-preview.16) (2025-03-15) ## [4.11.4](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.11.3...v4.11.4) (2025-12-24)
### Bug Fixes
* add early return for case where subEmitter module is disabled ([d1386a1](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/d1386a12216743a6e09f1b9b87bea1dfcf7702e4))
* avoid endless loop ([eb2e862](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/eb2e862e80e549c8cf16ddfed776c101c2413bac)), closes [#392](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/392)
## [4.11.3](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.11.2...v4.11.3) (2025-10-14)
### Bug Fixes
* fix icon ([a9461ec](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/a9461ecb4d40d7fe878e12465d6e38faae7ae65b))
* fix URL link in README ([1c8c65d](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/1c8c65d25e7f6fe7b1d20da4461333df8fc7578e)), closes [#376](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/376)
* fix: second and subsequent bursts not displayed when world simulation and non-looping ([df2f3ca](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/df2f3caafbe279f1457d74f8183cb561ac14aa17)), closes [#326](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/326)
* UIParticle in canvas with 0f-0.01f alpha value does not start to play until alpha value is greater than 0.01f, causes play calls to be delayed unintentionally if canvas alpha value is set to mentioned value range ([38aec2e](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/38aec2ea1afd77677d629c86665a3342d92e49d9))
## [4.11.2](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.11.1...v4.11.2) (2025-03-15)
### Bug Fixes ### Bug Fixes
@@ -29,20 +48,28 @@
* IL2CPP build fails on older versions of Unity ([0da6525](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/0da652520cd165b43de7404c0b0ab1fbcf9349d1)) * IL2CPP build fails on older versions of Unity ([0da6525](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/0da652520cd165b43de7404c0b0ab1fbcf9349d1))
* NRE on enable ([0cff50e](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/0cff50ef696aa53fb7c46a9a737b7cf3a05b7b9b)), closes [#359](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/359) * NRE on enable ([0cff50e](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/0cff50ef696aa53fb7c46a9a737b7cf3a05b7b9b)), closes [#359](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/359)
# [5.0.0-preview.15](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/5.0.0-preview.14...5.0.0-preview.15) (2025-02-21) ## [4.11.1](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.11.0...v4.11.1) (2025-02-21)
### Bug Fixes ### Bug Fixes
* component icons will no longer be displayed in the scene view ([6dfbdae](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/6dfbdae38d3822ab9c2c6f0e4ca1ca32ee98a239)) * component icons will no longer be displayed in the scene view ([6dfbdae](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/6dfbdae38d3822ab9c2c6f0e4ca1ca32ee98a239))
* editor crashed on exit play mode (editor, windows) ([47ee45c](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/47ee45cbbe651a8f87ca2b8a3948f8b88db8211e)), closes [#351](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/351)
# [4.11.0](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.10.7...v4.11.0) (2025-02-21)
### Features ### Features
* add 'TimeScaleMultiplier' option ([925af0b](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/925af0b6046f65f23a778f67cefa8ff9cbedb513)) * add 'TimeScaleMultiplier' option ([925af0b](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/925af0b6046f65f23a778f67cefa8ff9cbedb513))
# [5.0.0-preview.14](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/5.0.0-preview.13...5.0.0-preview.14) (2025-01-03) ## [4.10.7](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.10.6...v4.10.7) (2025-01-14)
### Bug Fixes
* editor crashed on exit play mode (editor, windows) ([47ee45c](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/47ee45cbbe651a8f87ca2b8a3948f8b88db8211e)), closes [#351](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/351)
## [4.10.6](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.10.5...v4.10.6) (2025-01-03)
### Bug Fixes ### Bug Fixes
@@ -50,19 +77,6 @@
* sub-emitter particles may not render correctly in certain scenarios ([8276684](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/8276684c3b1646f0490ed64557547ba15281664a)), closes [#348](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/348) * sub-emitter particles may not render correctly in certain scenarios ([8276684](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/8276684c3b1646f0490ed64557547ba15281664a)), closes [#348](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/348)
* sub-emitter's `inherit velocity` module doubles at runtime ([67de3d1](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/67de3d1bd3e16dc9b564625cb990c53d75769506)), closes [#349](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/349) * sub-emitter's `inherit velocity` module doubles at runtime ([67de3d1](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/67de3d1bd3e16dc9b564625cb990c53d75769506)), closes [#349](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/349)
# [5.0.0-preview.13](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/5.0.0-preview.12...5.0.0-preview.13) (2025-01-03)
### Features
* change the default value of `UIParticle.scale` from `10` to `1` ([9955eef](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/9955eefdc22cf565502f85c87cd2efd3a25fbe50))
* UIParticle no longer inherits from MaskableGraphic ([c09bfb8](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/c09bfb81abc9179bf5fc49d29eaf7fc4ed01a4dc))
### BREAKING CHANGES
* Some members inherited from MaskableGraphic will no longer be available.
## [4.10.5](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.10.4...v4.10.5) (2024-12-23) ## [4.10.5](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.10.4...v4.10.5) (2024-12-23)

View File

@@ -1,18 +1,19 @@
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using UnityEditor; using UnityEditor;
using UnityEditor.UI;
using UnityEditorInternal; using UnityEditorInternal;
using UnityEngine; using UnityEngine;
using UnityEngine.Profiling; using UnityEngine.Profiling;
using UnityEngine.UI; using UnityEngine.UI;
using Coffee.UIParticleInternal; using Coffee.UIParticleInternal;
using Object = UnityEngine.Object;
#if UNITY_2021_2_OR_NEWER #if UNITY_2021_2_OR_NEWER
using UnityEditor.Overlays; using UnityEditor.Overlays;
#else #else
using System;
using System.Reflection; using System.Reflection;
using Object = UnityEngine.Object;
#endif #endif
#if UNITY_2021_2_OR_NEWER #if UNITY_2021_2_OR_NEWER
using UnityEditor.SceneManagement; using UnityEditor.SceneManagement;
@@ -25,7 +26,7 @@ namespace Coffee.UIExtensions
{ {
[CustomEditor(typeof(UIParticle))] [CustomEditor(typeof(UIParticle))]
[CanEditMultipleObjects] [CanEditMultipleObjects]
internal class UIParticleEditor : Editor internal class UIParticleEditor : GraphicEditor
{ {
internal class State : ScriptableSingleton<State> internal class State : ScriptableSingleton<State>
{ {
@@ -65,6 +66,7 @@ namespace Coffee.UIExtensions
private ReorderableList _ro; private ReorderableList _ro;
private bool _showMax; private bool _showMax;
private bool _is3DScaleMode; private bool _is3DScaleMode;
private GameObject[] _gameObjects;
private static readonly HashSet<Shader> s_Shaders = new HashSet<Shader>(); private static readonly HashSet<Shader> s_Shaders = new HashSet<Shader>();
#if UNITY_2018 || UNITY_2019 #if UNITY_2018 || UNITY_2019
@@ -80,14 +82,28 @@ namespace Coffee.UIExtensions
"_ColorMask" "_ColorMask"
}; };
/// <summary>
/// ドメインリロード無効化対応:静的キャッシュをクリア
/// </summary>
[InitializeOnLoadMethod]
private static void OnDomainReload()
{
s_Shaders.Clear();
#if UNITY_2018 || UNITY_2019
s_Streams.Clear();
#endif
}
//################################ //################################
// Public/Protected Members. // Public/Protected Members.
//################################ //################################
/// <summary> /// <summary>
/// This function is called when the object becomes enabled and active. /// This function is called when the object becomes enabled and active.
/// </summary> /// </summary>
private void OnEnable() protected override void OnEnable()
{ {
base.OnEnable();
_maskable = serializedObject.FindProperty("m_Maskable"); _maskable = serializedObject.FindProperty("m_Maskable");
_scale3D = serializedObject.FindProperty("m_Scale3D"); _scale3D = serializedObject.FindProperty("m_Scale3D");
_animatableProperties = serializedObject.FindProperty("m_AnimatableProperties"); _animatableProperties = serializedObject.FindProperty("m_AnimatableProperties");
@@ -180,6 +196,13 @@ namespace Coffee.UIExtensions
y.hasMultipleDifferentValues || y.hasMultipleDifferentValues ||
z.hasMultipleDifferentValues; z.hasMultipleDifferentValues;
} }
// Add temporary ParticleSystem for preview if enabled.
if (UIParticleProjectSettings.s_PreviewOnSelectOnSelect)
{
_gameObjects = targets.OfType<UIParticle>().Select(x => x.gameObject).ToArray();
ParticleSystemPreviewSystem.Register(_gameObjects);
}
} }
/// <summary> /// <summary>
@@ -194,7 +217,10 @@ namespace Coffee.UIExtensions
serializedObject.Update(); serializedObject.Update();
// Maskable // Maskable
if (_maskable != null)
{
EditorGUILayout.PropertyField(_maskable); EditorGUILayout.PropertyField(_maskable);
}
// Scale // Scale
EditorGUI.BeginDisabledGroup(!_meshSharing.hasMultipleDifferentValues && _meshSharing.intValue == 4); EditorGUI.BeginDisabledGroup(!_meshSharing.hasMultipleDifferentValues && _meshSharing.intValue == 4);
@@ -341,6 +367,10 @@ namespace Coffee.UIExtensions
} }
} }
#endif #endif
// Remove the temporary ParticleSystem.
ParticleSystemPreviewSystem.DrawWarningForTemporary(_gameObjects);
Profiler.EndSample(); Profiler.EndSample();
} }
@@ -461,11 +491,9 @@ namespace Coffee.UIExtensions
{ {
if (!p || (ignoreCurrent && target == p)) return; if (!p || (ignoreCurrent && target == p)) return;
Misc.DestroyImmediate(p); var cr = p.canvasRenderer;
if (p.TryGetComponent<CanvasRenderer>(out var cr)) DestroyImmediate(p);
{ DestroyImmediate(cr);
Misc.DestroyImmediate(cr);
}
#if UNITY_2018_3_OR_NEWER #if UNITY_2018_3_OR_NEWER
var stage = PrefabStageUtility.GetCurrentPrefabStage(); var stage = PrefabStageUtility.GetCurrentPrefabStage();
@@ -481,7 +509,7 @@ namespace Coffee.UIExtensions
#endif #endif
} }
private static bool FixButton(bool show, string text) private static bool FixButton(bool show, string text, GUIContent buttonText = null)
{ {
if (!show) return false; if (!show) return false;
using (new EditorGUILayout.HorizontalScope(GUILayout.ExpandWidth(true))) using (new EditorGUILayout.HorizontalScope(GUILayout.ExpandWidth(true)))
@@ -489,7 +517,7 @@ namespace Coffee.UIExtensions
EditorGUILayout.HelpBox(text, MessageType.Warning, true); EditorGUILayout.HelpBox(text, MessageType.Warning, true);
using (new EditorGUILayout.VerticalScope()) using (new EditorGUILayout.VerticalScope())
{ {
return GUILayout.Button(s_ContentFix, GUILayout.Width(30)); return GUILayout.Button(buttonText ?? s_ContentFix, GUILayout.ExpandWidth(false));
} }
} }
} }

View File

@@ -1,9 +1,9 @@
# <img alt="UIParticleIcon" src="https://github.com/mob-sakai/ParticleEffectForUGUI/assets/12690315/d76e105e-a840-4f61-a1f6-8cf311c0812d" width="26"/> UI Particle v5 <!-- omit in toc --> # <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/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)](https://github.com/mob-sakai/ParticleEffectForUGUI/releases) [![](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/github/license/mob-sakai/ParticleEffectForUGUI.svg)](https://github.com/mob-sakai/ParticleEffectForUGUI/blob/main/LICENSE.md)
![](https://img.shields.io/badge/Unity-2019.3+-57b9d3.svg?style=flat&logo=unity) ![](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/uGUI_2.0_Ready-57b9d3.svg?style=flat)
![](https://img.shields.io/badge/UPR%2FHDPR_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) ![](https://github.com/mob-sakai/ParticleEffectForUGUI/actions/workflows/test.yml/badge.svg?branch=develop)
@@ -11,7 +11,7 @@
[![](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/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) [![](https://img.shields.io/twitter/follow/mob_sakai.svg?label=Follow&style=social)](https://twitter.com/intent/follow?screen_name=mob_sakai)
<< [📝 Description](#-description-) | [📌 Key Features](#-key-features) | [🎮 Demo](#-demo) | [⚙ Installation](#-installation) | [🔄 Upgrading to 5.x](#-upgrading-from-3x4x-to-5x) | [🚀 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) >>
## 📝 Description <!-- omit in toc --> ## 📝 Description <!-- omit in toc -->
@@ -27,8 +27,6 @@ You can render, mask, and sort your `ParticleSystems` for UI without the need fo
- [Install via UPM (with Package Manager UI)](#install-via-upm-with-package-manager-ui) - [Install via UPM (with Package Manager UI)](#install-via-upm-with-package-manager-ui)
- [Install via UPM (Manually)](#install-via-upm-manually) - [Install via UPM (Manually)](#install-via-upm-manually)
- [Install as Embedded Package](#install-as-embedded-package) - [Install as Embedded Package](#install-as-embedded-package)
- [🔄 Upgrading from v3/v4 to v5](#-upgrading-from-v3v4-to-v5)
- [Breaking Changes](#breaking-changes)
- [🚀 Usage](#-usage) - [🚀 Usage](#-usage)
- [Component: UIParticle](#component-uiparticle) - [Component: UIParticle](#component-uiparticle)
- [Basic Usage](#basic-usage) - [Basic Usage](#basic-usage)
@@ -106,7 +104,7 @@ You can render, mask, and sort your `ParticleSystems` for UI without the need fo
## ⚙ Installation ## ⚙ Installation
_This package requires **Unity 2019.3 or later**._ _This package requires **Unity 2018.3 or later**._
#### Install via OpenUPM #### Install via OpenUPM
@@ -118,16 +116,16 @@ _This package requires **Unity 2019.3 or later**._
``` ```
- To update the package, use Package Manager UI (`Window > Package Manager`) or run the following command with `@{version}`: - To update the package, use Package Manager UI (`Window > Package Manager`) or run the following command with `@{version}`:
``` ```
openupm add com.coffee.ui-particle@5.0.0 openupm add com.coffee.ui-particle@4.9.0
``` ```
#### Install via UPM (with Package Manager UI) #### Install via UPM (with Package Manager UI)
- Click `Window > Package Manager` to open Package Manager UI. - 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?path=Packages/src` - Click `+ > Add package from git URL...` and input the repository URL: `https://github.com/mob-sakai/ParticleEffectForUGUI.git`
![](https://github.com/user-attachments/assets/f88f47ad-c606-44bd-9e86-ee3f72eac548) ![](https://github.com/user-attachments/assets/f88f47ad-c606-44bd-9e86-ee3f72eac548)
- To update the package, change suffix `#{version}` to the target version. - To update the package, change suffix `#{version}` to the target version.
- e.g. `https://github.com/mob-sakai/ParticleEffectForUGUI.git?path=Packages/src#5.0.0` - e.g. `https://github.com/mob-sakai/ParticleEffectForUGUI.git#4.9.0`
#### Install via UPM (Manually) #### Install via UPM (Manually)
@@ -135,41 +133,22 @@ _This package requires **Unity 2019.3 or later**._
```json ```json
{ {
"dependencies": { "dependencies": {
"com.coffee.ui-particle": "https://github.com/mob-sakai/ParticleEffectForUGUI.git?path=Packages/src", "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?path=Packages/src#5.0.0",` - e.g. `"com.coffee.ui-particle": "https://github.com/mob-sakai/ParticleEffectForUGUI.git#4.9.0",`
### Install as Embedded Package #### Install as Embedded Package
1. Download the `Source code (zip)` file from [Releases](https://github.com/mob-sakai/ParticleEffectForUGUI/releases) and 1. Download a source code zip file from [Releases](https://github.com/mob-sakai/ParticleEffectForUGUI/releases) and extract it.
extract it. 2. Place it in your project's `Packages` directory.
2. Move the `<extracted_dir>/Packages/src` directory into your project's `Packages` directory. ![](https://github.com/mob-sakai/mob-sakai/assets/12690315/0b7484b4-5fca-43b0-a9ef-e5dbd99bcdb4)
![](https://github.com/user-attachments/assets/187cbcbe-5922-4ed5-acec-cf19aa17d208) - If you want to fix bugs or add features, install it as an embedded package.
- You can rename the `src` directory if needed. - To update the package, you need to re-download it and replace the contents.
- If you intend to fix bugs or add features, installing it as an embedded package is recommended.
- To update the package, re-download it and replace the existing contents.
<br><br>
## 🔄 Upgrading from v3/v4 to v5
### Breaking Changes
- The default value of `UIParticle.scale` has been changed from `10` to `1`.
- `UIParticle` no longer inherits from `MaskableGraphic`.
- If you are installing via git URL, add `?path=Packages/src`.
```json
// v3/v4
"com.coffee.ui-particle": "https://github.com/mob-sakai/ParticleEffectForUGUI.git",
// v5
"com.coffee.ui-particle": "https://github.com/mob-sakai/ParticleEffectForUGUI.git?path=Packages/src",
```
<br><br> <br><br>
@@ -204,9 +183,14 @@ _This package requires **Unity 2019.3 or later**._
- **Time Scale Multiplier:** Time scale multiplier. - **Time Scale Multiplier:** Time scale multiplier.
- **Rendering Order**: The ParticleSystem list to be rendered. You can change the order and the materials. - **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 > [!TIPS]
> Press the `Refresh` button to reconstruct the rendering order based on children ParticleSystem's sorting order
and z-position. and z-position.
> [!TIPS]
> When a `GameObject` with this component is selected in the editor, a temporary `ParticleSystem` is added if needed so you can preview the effect in the Scene view.
> The generated `ParticleSystem` is marked with `HideFlags.DontSave`, so it is neither saved nor included in builds.
<br><br> <br><br>
### Basic Usage ### Basic Usage
@@ -216,6 +200,10 @@ and z-position.
2. Adjust the ParticleSystem as you like. 2. Adjust the ParticleSystem as you like.
![particle1](https://user-images.githubusercontent.com/12690315/95007359-ca385200-0649-11eb-8383-627c9750bda8.png) ![particle1](https://user-images.githubusercontent.com/12690315/95007359-ca385200-0649-11eb-8383-627c9750bda8.png)
> [!Tips]
> Adding a `UIParticle` to the parent is the recommended setup rather than attaching it directly to the `ParticleSystem`.
> When using `ParticleSystem.emission.rateOverDistance`, it is recommended to move the transform of `UIParticle` rather than the `ParticleSystem`.
<br> <br>
### Usage with Your Existing ParticleSystem Prefab ### Usage with Your Existing ParticleSystem Prefab
@@ -277,13 +265,34 @@ uiParticle.Stop();
- **Unscaled Time:** Update with unscaled delta time. - **Unscaled Time:** Update with unscaled delta time.
- **OnAttracted**: An event called when attracting is complete (per particle). - **OnAttracted**: An event called when attracting is complete (per particle).
<br><br>
### Component: ParticleSystemPreviewer
`ParticleSystemPreviewer` is used to preview a ParticleSystem in the editor.
- When a `GameObject` with this component is selected in the editor, a temporary `ParticleSystem` is added if needed so you can preview the effect in the Scene view.
- The generated `ParticleSystem` is marked with `HideFlags.DontSave`, so it is neither saved nor included in builds.
<br><br> <br><br>
### Project Settings ### Project Settings
![](https://github.com/user-attachments/assets/befc7f34-fb47-4006-831a-eba79fda11ca) You can adjust the project-wide settings for `UI Particle`. (`Edit > Project Settings > UI > UI Particle`)
- Click `Edit > Project Settings` to open the Project Settings window and then select `UI > UI Particle` category. ![](https://github.com/mob-sakai/mob-sakai/releases/download/docs/1782270746550.png)
#### Settings
- **Enable Linear To Gamma**: Automatically correct the color space of the mesh.
#### Editor
- **Hide Generated Component**: Automatically hide the generated `UIParticleRenderer` component and `UIParticle BakingCamera`.
- **Preview On Select**: When selecting UIParticle, a temporary ParticleSystem is generated for preview.
<br><br> <br><br>

View File

@@ -12,6 +12,33 @@ namespace Coffee.UIParticleInternal
/// </summary> /// </summary>
internal static class ComponentExtensions internal static class ComponentExtensions
{ {
#if !UNITY_2019_2_OR_NEWER
public static bool TryGetComponent<T>(this GameObject self, out T component)
where T : Component
{
if (self == null)
{
component = null;
return false;
}
component = self.GetComponent<T>();
return component != null;
}
public static bool TryGetComponent<T>(this Component self, out T component)
where T : Component
{
if (self == null)
{
component = null;
return false;
}
return self.gameObject.TryGetComponent(out component);
}
#endif
/// <summary> /// <summary>
/// Get components in children of a specific type in the hierarchy of a GameObject. /// Get components in children of a specific type in the hierarchy of a GameObject.
/// </summary> /// </summary>

View File

@@ -14,6 +14,15 @@ namespace Coffee.UIParticleInternal
public abstract class PreloadedProjectSettings : ScriptableObject public abstract class PreloadedProjectSettings : ScriptableObject
#if UNITY_EDITOR #if UNITY_EDITOR
{ {
[Tooltip("When enabled, this settings asset will be added to PlayerSettings.preloadedAssets in build.\n\n" +
"When disable, you should load this settings via Resources, AssetBundles or Addressables to use.")]
[SerializeField]
[Header("Advanced")]
[HideInInspector]
private bool m_PreLoadSettingsInBuild = true;
protected static bool s_BuildingPlayer;
private class Postprocessor : AssetPostprocessor private class Postprocessor : AssetPostprocessor
{ {
private static void OnPostprocessAllAssets(string[] _, string[] __, string[] ___, string[] ____) private static void OnPostprocessAllAssets(string[] _, string[] __, string[] ___, string[] ____)
@@ -22,12 +31,35 @@ namespace Coffee.UIParticleInternal
} }
} }
private class PreprocessBuildWithReport : IPreprocessBuildWithReport private class ExcludeFromBuild : IPreprocessBuildWithReport, IPostprocessBuildWithReport
{ {
int IOrderedCallback.callbackOrder => 0; int IOrderedCallback.callbackOrder => 0;
void IPreprocessBuildWithReport.OnPreprocessBuild(BuildReport report) void IPreprocessBuildWithReport.OnPreprocessBuild(BuildReport report)
{ {
AssetDatabase.Refresh();
Initialize();
s_BuildingPlayer = true;
foreach (var t in TypeCache.GetTypesDerivedFrom(typeof(PreloadedProjectSettings<>)))
{
var settings = GetDefaultSettings(t);
if (!settings || settings.m_PreLoadSettingsInBuild) continue;
PlayerSettings.SetPreloadedAssets(
PlayerSettings.GetPreloadedAssets()
.Where(x => x && x.GetType() != t)
.ToArray());
Debug.Log($"[PreloadedProjectSettings] Build started: removed '{settings.name}' " +
$"({t.Name}) from PreloadedAssets. " +
$"It will be restored after build completes.");
}
}
void IPostprocessBuildWithReport.OnPostprocessBuild(BuildReport report)
{
s_BuildingPlayer = false;
Initialize(); Initialize();
} }
} }
@@ -38,14 +70,17 @@ namespace Coffee.UIParticleInternal
{ {
var defaultSettings = GetDefaultSettings(t); var defaultSettings = GetDefaultSettings(t);
if (defaultSettings == null) if (defaultSettings == null)
{
if (!s_BuildingPlayer)
{ {
// When create a new instance, automatically set it as default settings. // When create a new instance, automatically set it as default settings.
defaultSettings = CreateInstance(t) as PreloadedProjectSettings; defaultSettings = CreateInstance(t) as PreloadedProjectSettings;
SetDefaultSettings(defaultSettings); SetDefaultSettings(defaultSettings);
} }
}
else if (GetPreloadedSettings(t).Length != 1) else if (GetPreloadedSettings(t).Length != 1)
{ {
SetDefaultSettings(defaultSettings); if (!s_BuildingPlayer) SetDefaultSettings(defaultSettings);
} }
if (defaultSettings != null) if (defaultSettings != null)
@@ -73,7 +108,7 @@ namespace Coffee.UIParticleInternal
protected static PreloadedProjectSettings GetDefaultSettings(Type type) protected static PreloadedProjectSettings GetDefaultSettings(Type type)
{ {
return GetPreloadedSettings(type).FirstOrDefault() as PreloadedProjectSettings return GetPreloadedSettings(type).FirstOrDefault() as PreloadedProjectSettings
?? AssetDatabase.FindAssets($"t:{nameof(PreloadedProjectSettings)}") ?? AssetDatabase.FindAssets($"t:{type.Name}")
.Select(AssetDatabase.GUIDToAssetPath) .Select(AssetDatabase.GUIDToAssetPath)
.Select(AssetDatabase.LoadAssetAtPath<PreloadedProjectSettings>) .Select(AssetDatabase.LoadAssetAtPath<PreloadedProjectSettings>)
.FirstOrDefault(x => x != null && x.GetType() == type); .FirstOrDefault(x => x != null && x.GetType() == type);
@@ -120,6 +155,35 @@ namespace Coffee.UIParticleInternal
{ {
} }
} }
internal abstract class PreloadedProjectSettingsEditor : Editor
{
private SerializedProperty _preLoadSettingsInBuild;
protected virtual void OnEnable()
{
_preLoadSettingsInBuild = serializedObject.FindProperty("m_PreLoadSettingsInBuild");
}
protected void DrawPreLoadSettingsInBuild(string packageName)
{
EditorGUILayout.PropertyField(_preLoadSettingsInBuild);
if (!_preLoadSettingsInBuild.boolValue)
{
EditorGUILayout.BeginHorizontal();
EditorGUILayout.HelpBox(
$"{target.GetType().Name} asset will not be built in.\n" +
$"please load manually from Resources, AssetBundle, or Addressables before using {packageName}.",
MessageType.Warning);
if (GUILayout.Button("Ping"))
{
EditorGUIUtility.PingObject(target);
}
EditorGUILayout.EndHorizontal();
}
}
}
#else #else
{ {
} }
@@ -131,6 +195,13 @@ namespace Coffee.UIParticleInternal
private static T s_Instance; private static T s_Instance;
#if UNITY_EDITOR #if UNITY_EDITOR
#if UNITY_2019_3_OR_NEWER
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
private static void OnDomainReload()
{
s_Instance = null;
}
#endif
private string _jsonText; private string _jsonText;
public static bool hasInstance => s_Instance != null; public static bool hasInstance => s_Instance != null;
@@ -151,7 +222,7 @@ namespace Coffee.UIParticleInternal
return s_Instance; return s_Instance;
} }
SetDefaultSettings(s_Instance); if (!s_BuildingPlayer) SetDefaultSettings(s_Instance);
return s_Instance; return s_Instance;
} }
} }
@@ -193,9 +264,12 @@ namespace Coffee.UIParticleInternal
} }
EditorApplication.playModeStateChanged += OnPlayModeStateChanged; EditorApplication.playModeStateChanged += OnPlayModeStateChanged;
#else
if (s_Instance && s_Instance != this)
{
Destroy(s_Instance);
}
#endif #endif
if (s_Instance != null) return;
s_Instance = this as T; s_Instance = this as T;
} }

View File

@@ -14,7 +14,7 @@ namespace Coffee.UIParticleInternal
UIExtraCallbacks.onLateAfterCanvasRebuild += ClearAllCache; UIExtraCallbacks.onLateAfterCanvasRebuild += ClearAllCache;
} }
#if UNITY_EDITOR #if UNITY_EDITOR && UNITY_2019_3_OR_NEWER
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
private static void Clear() private static void Clear()
{ {

View File

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

View File

@@ -13,7 +13,9 @@ namespace Coffee.UIParticleInternal
public static int count => s_Repository.count; public static int count => s_Repository.count;
#if UNITY_EDITOR public static Func<string, Shader> onShaderFind = Shader.Find;
#if UNITY_EDITOR && UNITY_2019_3_OR_NEWER
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
public static void Clear() public static void Clear()
{ {
@@ -48,7 +50,7 @@ namespace Coffee.UIParticleInternal
public static void Get(Hash128 hash, ref Material material, string shaderName) public static void Get(Hash128 hash, ref Material material, string shaderName)
{ {
Profiler.BeginSample("(COF)[MaterialRepository] Get"); Profiler.BeginSample("(COF)[MaterialRepository] Get");
s_Repository.Get(hash, ref material, x => new Material(Shader.Find(x)) s_Repository.Get(hash, ref material, x => new Material(onShaderFind(x))
{ {
hideFlags = HideFlags.DontSave | HideFlags.NotEditable hideFlags = HideFlags.DontSave | HideFlags.NotEditable
}, shaderName); }, shaderName);
@@ -61,7 +63,7 @@ namespace Coffee.UIParticleInternal
public static void Get(Hash128 hash, ref Material material, string shaderName, string[] keywords) public static void Get(Hash128 hash, ref Material material, string shaderName, string[] keywords)
{ {
Profiler.BeginSample("(COF)[MaterialRepository] Get"); Profiler.BeginSample("(COF)[MaterialRepository] Get");
s_Repository.Get(hash, ref material, x => new Material(Shader.Find(x.shaderName)) s_Repository.Get(hash, ref material, x => new Material(onShaderFind(x.shaderName))
{ {
hideFlags = HideFlags.DontSave | HideFlags.NotEditable, hideFlags = HideFlags.DontSave | HideFlags.NotEditable,
shaderKeywords = x.keywords shaderKeywords = x.keywords

View File

@@ -48,15 +48,10 @@ namespace Coffee.UIParticleInternal
{ {
if (obj == null) return; if (obj == null) return;
#if UNITY_EDITOR #if UNITY_EDITOR
if (Application.isEditor) Object.DestroyImmediate(obj, true);
{ #else
Object.DestroyImmediate(obj);
}
else
#endif
{
Object.Destroy(obj); Object.Destroy(obj);
} #endif
} }
[Conditional("UNITY_EDITOR")] [Conditional("UNITY_EDITOR")]
@@ -114,7 +109,7 @@ namespace Coffee.UIParticleInternal
{ {
if (Misc.isBatchOrBuilding) return; if (Misc.isBatchOrBuilding) return;
var types = TypeCache.GetTypesWithAttribute<IconAttribute>(); var types = TypeCache.GetTypesWithAttribute(typeof(IconAttribute));
var scripts = MonoImporter.GetAllRuntimeMonoScripts(); var scripts = MonoImporter.GetAllRuntimeMonoScripts();
foreach (var type in types) foreach (var type in types)
{ {

View File

@@ -0,0 +1,88 @@
#if !UNITY_2019_2_OR_NEWER
using System;
using System.Collections.Generic;
using System.Reflection;
namespace Coffee.UIParticleInternal
{
public static class TypeCache
{
private static readonly object s_Lock = new object();
private static readonly Dictionary<Type, Type[]> s_DerivedTypesCache = new Dictionary<Type, Type[]>();
private static readonly Dictionary<Type, Type[]> s_AttributeTypesCache = new Dictionary<Type, Type[]>();
public static IEnumerable<Type> GetTypesDerivedFrom(Type baseType)
{
lock (s_Lock)
{
if (s_DerivedTypesCache.TryGetValue(baseType, out var cached))
{
return cached;
}
var types = new List<Type>();
foreach (var t in GetAllLoadableTypes())
{
if (t != baseType && baseType.IsAssignableFrom(t))
{
types.Add(t);
}
}
return s_DerivedTypesCache[baseType] = types.ToArray();
}
}
public static IEnumerable<Type> GetTypesWithAttribute(Type attr)
{
lock (s_Lock)
{
if (s_AttributeTypesCache.TryGetValue(attr, out var cached))
{
return cached;
}
var types = new List<Type>();
foreach (var t in GetAllLoadableTypes())
{
if (t.GetCustomAttributes(attr, inherit: true).Length > 0)
{
types.Add(t);
}
}
return s_AttributeTypesCache[attr] = types.ToArray();
}
}
private static IEnumerable<Type> GetAllLoadableTypes()
{
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
{
Type[] types;
try
{
types = assembly.GetTypes();
}
catch (ReflectionTypeLoadException ex)
{
types = ex.Types;
}
if (types == null)
{
continue;
}
foreach (var t in types)
{
if (t != null)
{
yield return t;
}
}
}
}
}
}
#endif

View File

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

View File

@@ -82,14 +82,22 @@ namespace Coffee.UIParticleInternal
message: "InitializeAfterCanvasRebuild"); message: "InitializeAfterCanvasRebuild");
} }
#if UNITY_EDITOR #if UNITY_EDITOR && UNITY_2019_3_OR_NEWER
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
#elif UNITY_EDITOR
[InitializeOnLoadMethod] [InitializeOnLoadMethod]
#endif #else
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)] [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
#endif
private static void InitializeOnLoad() private static void InitializeOnLoad()
{ {
Canvas.willRenderCanvases -= OnAfterCanvasRebuild; Canvas.willRenderCanvases -= OnAfterCanvasRebuild;
s_IsInitializedAfterCanvasRebuild = false; s_IsInitializedAfterCanvasRebuild = false;
s_AfterCanvasRebuildAction.Clear();
s_LateAfterCanvasRebuildAction.Clear();
s_BeforeCanvasRebuildAction.Clear();
s_OnScreenSizeChangedAction.Clear();
s_LastScreenSize = default;
} }
/// <summary> /// <summary>

View File

@@ -0,0 +1,236 @@
using System.Collections.Generic;
using System.Linq;
using Coffee.UIParticleInternal;
using UnityEditor;
using UnityEngine;
namespace Coffee.UIExtensions
{
[Icon("Packages/com.coffee.ui-particle/Editor/UIParticleIcon.png")]
[ExecuteAlways]
internal class ParticleSystemPreviewer : MonoBehaviour
{
// Do nothing.
}
#if UNITY_EDITOR
[CustomEditor(typeof(ParticleSystemPreviewer))]
[CanEditMultipleObjects]
internal class ParticleSystemPreviewerEditor : Editor
{
private GameObject[] _gameObjects;
private void OnEnable()
{
_gameObjects = targets.OfType<ParticleSystemPreviewer>().Select(x => x.gameObject).ToArray();
ParticleSystemPreviewSystem.Register(_gameObjects);
}
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
ParticleSystemPreviewSystem.DrawWarningForTemporary(_gameObjects);
ParticleSystemPreviewSystem.DrawWarningForPermanent(_gameObjects);
}
}
/// <summary>
/// This class manages temporary ParticleSystems for preview purposes.
/// When previewing in the editor, it is common to place an empty ParticleSystem as the root, but it consumes memory at runtime if included in the build.
/// The temporary ParticleSystems created by this class only exist when the specified GameObject is selected, and are automatically deleted when the selection is cleared.
/// </summary>
internal class ParticleSystemPreviewSystem : ScriptableSingleton<ParticleSystemPreviewSystem>
{
private const HideFlags k_TemporaryHideFlags = HideFlags.DontSave | HideFlags.NotEditable;
[SerializeField]
private List<GameObject> m_PreviewObjects = new List<GameObject>();
#if UNITY_2019_3_OR_NEWER
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
#else
[InitializeOnLoadMethod]
#endif
public static void Initialize()
{
instance.OnSelectionChanged();
Selection.selectionChanged -= instance.OnSelectionChanged;
Selection.selectionChanged += instance.OnSelectionChanged;
}
/// <summary>
/// Adds a temporary ParticleSystem to the specified GameObject for preview purposes.
/// </summary>
public static void Register(GameObject[] targets)
{
foreach (var target in targets)
{
Register(target);
}
}
/// <summary>
/// Adds a temporary ParticleSystem to the specified GameObject for preview purposes.
/// </summary>
public static void Register(GameObject target)
{
if (!target) return;
if (EditorApplication.isPlaying) return;
if (instance.m_PreviewObjects.Contains(target)) return;
if (target.TryGetComponent<ParticleSystem>(out var ps))
{
if (ps.hideFlags == k_TemporaryHideFlags)
{
RegisterParticleSystem(ps);
}
return;
}
// Create temporary ParticleSystem for preview.
RegisterParticleSystem(target.AddComponent<ParticleSystem>());
}
/// <summary>
/// Removes the temporary ParticleSystem associated with the specified GameObject.
/// </summary>
/// <param name="target"></param>
public static void Unregister(GameObject target)
{
if (!target) return;
var index = instance.m_PreviewObjects.IndexOf(target);
if (index < 0) return;
instance.m_PreviewObjects.RemoveAt(index);
if (HasTemporaryParticleSystem(target))
{
RemoveParticleSystem(target);
}
}
private static void RegisterParticleSystem(ParticleSystem ps)
{
if (!ps) return;
ps.hideFlags = k_TemporaryHideFlags;
var emission = ps.emission;
emission.enabled = false;
var shape = ps.shape;
shape.enabled = false;
if (ps.TryGetComponent<ParticleSystemRenderer>(out var psr))
{
psr.enabled = false;
psr.hideFlags = k_TemporaryHideFlags;
}
instance.m_PreviewObjects.Add(ps.gameObject);
EditorUtility.SetDirty(ps.gameObject);
}
/// <summary>
/// Removes the temporary ParticleSystem associated with the specified GameObject.
/// </summary>
/// <param name="target"></param>
private static void RemoveParticleSystem(GameObject target)
{
if (target.TryGetComponent<ParticleSystem>(out var ps))
{
Misc.DestroyImmediate(ps);
EditorUtility.SetDirty(target);
}
if (target.TryGetComponent<ParticleSystem>(out var psr))
{
Misc.DestroyImmediate(psr);
EditorUtility.SetDirty(target);
}
}
/// <summary>
/// Checks if the specified GameObject has a temporary ParticleSystem.
/// </summary>
private static bool HasTemporaryParticleSystem(GameObject target)
{
return target
&& instance.m_PreviewObjects.Contains(target)
&& target.TryGetComponent<ParticleSystem>(out var ps)
&& ps.hideFlags == k_TemporaryHideFlags;
}
/// <summary>
/// Checks if the specified GameObject has a permanent ParticleSystem.
/// </summary>
private static bool HasPermanentParticleSystem(GameObject target)
{
return target
&& target.TryGetComponent<ParticleSystem>(out var ps)
&& ps.hideFlags != k_TemporaryHideFlags;
}
private void OnSelectionChanged()
{
var selectedGameObjects = Selection.gameObjects;
for (var i = m_PreviewObjects.Count - 1; 0 <= i; i--)
{
var go = m_PreviewObjects[i];
if (!go)
{
m_PreviewObjects.RemoveAt(i);
}
else if (!selectedGameObjects.Contains(go))
{
Unregister(go);
}
}
}
public static void DrawWarningForTemporary(GameObject[] gameObjects)
{
if (gameObjects == null || gameObjects.Length == 0 || !gameObjects.Any(HasTemporaryParticleSystem)) return;
if (WarningButton("The temporary ParticleSystem for preview is attached.\n" +
"It will be removed when exiting edit mode.", "Remove"))
{
foreach (var go in gameObjects)
{
if (HasTemporaryParticleSystem(go))
{
RemoveParticleSystem(go);
}
}
}
}
public static void DrawWarningForPermanent(GameObject[] gameObjects)
{
if (gameObjects == null || gameObjects.Length == 0 || !gameObjects.Any(HasPermanentParticleSystem)) return;
if (WarningButton("The permanent ParticleSystem is attached.\n" +
"It will be included in build.", "Remove"))
{
foreach (var go in gameObjects)
{
if (HasPermanentParticleSystem(go))
{
RemoveParticleSystem(go);
Unregister(go);
Register(go);
}
}
}
}
private static bool WarningButton(string message, string buttonText)
{
EditorGUILayout.BeginHorizontal();
EditorGUILayout.HelpBox(message, MessageType.Warning, true);
var clicked = GUILayout.Button(EditorGUIUtility.TrTempContent(buttonText));
EditorGUILayout.EndHorizontal();
return clicked;
}
}
#endif
}

View File

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

View File

@@ -3,9 +3,9 @@ using System.Collections.Generic;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using Coffee.UIParticleInternal; using Coffee.UIParticleInternal;
using UnityEngine; using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Rendering; using UnityEngine.Rendering;
using UnityEngine.Serialization; using UnityEngine.Serialization;
using UnityEngine.UI;
using Random = UnityEngine.Random; using Random = UnityEngine.Random;
[assembly: InternalsVisibleTo("Coffee.UIParticle.Editor")] [assembly: InternalsVisibleTo("Coffee.UIParticle.Editor")]
@@ -22,7 +22,7 @@ namespace Coffee.UIExtensions
[ExecuteAlways] [ExecuteAlways]
[RequireComponent(typeof(RectTransform))] [RequireComponent(typeof(RectTransform))]
[RequireComponent(typeof(CanvasRenderer))] [RequireComponent(typeof(CanvasRenderer))]
public class UIParticle : UIBehaviour, ISerializationCallbackReceiver public class UIParticle : MaskableGraphic, ISerializationCallbackReceiver
{ {
public enum AutoScalingMode public enum AutoScalingMode
{ {
@@ -64,7 +64,7 @@ namespace Coffee.UIExtensions
[Tooltip("Scale the rendering particles. When the `3D` toggle is enabled, 3D scale (x, y, z) is supported.")] [Tooltip("Scale the rendering particles. When the `3D` toggle is enabled, 3D scale (x, y, z) is supported.")]
[SerializeField] [SerializeField]
private Vector3 m_Scale3D = new Vector3(1, 1, 1); private Vector3 m_Scale3D = new Vector3(10, 10, 10);
[Tooltip("If you want to update material properties (e.g. _MainTex_ST, _Color) in AnimationClip, " + [Tooltip("If you want to update material properties (e.g. _MainTex_ST, _Color) in AnimationClip, " +
"use this to mark as animatable.")] "use this to mark as animatable.")]
@@ -125,48 +125,20 @@ namespace Coffee.UIExtensions
[Tooltip("Time scale multiplier.")] [Tooltip("Time scale multiplier.")]
private float m_TimeScaleMultiplier = 1; private float m_TimeScaleMultiplier = 1;
[SerializeField]
private bool m_Maskable = true;
private readonly List<UIParticleRenderer> _renderers = new List<UIParticleRenderer>(); private readonly List<UIParticleRenderer> _renderers = new List<UIParticleRenderer>();
private Camera _bakeCamera; private Camera _bakeCamera;
private Canvas _canvas;
private int _groupId; private int _groupId;
private bool _isScaleStored; private bool _isScaleStored;
private Vector3 _storedScale; private Vector3 _storedScale;
private DrivenRectTransformTracker _tracker; private DrivenRectTransformTracker _tracker;
public RectTransform rectTransform => transform as RectTransform;
public Canvas canvas
{
get
{
if (_canvas) return _canvas;
var tr = transform;
while (tr && !_canvas)
{
if (tr.TryGetComponent(out _canvas)) return _canvas;
tr = tr.parent;
}
return null;
}
}
/// <summary> /// <summary>
/// Does this graphic allow masking. /// Should this graphic be considered a target for ray-casting?
/// </summary> /// </summary>
public bool maskable public override bool raycastTarget
{ {
get => m_Maskable; get => false;
set set { }
{
if (value == m_Maskable) return;
m_Maskable = value;
UpdateRendererMaterial();
}
} }
/// <summary> /// <summary>
@@ -352,15 +324,15 @@ namespace Coffee.UIExtensions
public Vector3 parentScale { get; private set; } public Vector3 parentScale { get; private set; }
private Vector3 canvasScale { get; set; } public Vector3 canvasScale { get; private set; }
protected override void OnEnable() protected override void OnEnable()
{ {
_isScaleStored = false; _isScaleStored = false;
ResetGroupId(); ResetGroupId();
UIParticleUpdater.Register(this); UIParticleUpdater.Register(this);
RegisterDirtyMaterialCallback(UpdateRendererMaterial);
//
if (0 < particles.Count) if (0 < particles.Count)
{ {
RefreshParticles(particles); RefreshParticles(particles);
@@ -370,7 +342,7 @@ namespace Coffee.UIExtensions
RefreshParticles(); RefreshParticles();
} }
UpdateRendererMaterial(); base.OnEnable();
} }
/// <summary> /// <summary>
@@ -388,15 +360,9 @@ namespace Coffee.UIExtensions
UIParticleUpdater.Unregister(this); UIParticleUpdater.Unregister(this);
_renderers.RemoveAll(r => r == null); _renderers.RemoveAll(r => r == null);
_renderers.ForEach(r => r.Reset()); _renderers.ForEach(r => r.Reset());
_canvas = null; UnregisterDirtyMaterialCallback(UpdateRendererMaterial);
}
/// <summary> base.OnDisable();
/// Called when the state of the parent Canvas is changed.
/// </summary>
protected override void OnCanvasHierarchyChanged()
{
_canvas = null;
} }
/// <summary> /// <summary>
@@ -406,14 +372,6 @@ namespace Coffee.UIExtensions
{ {
} }
/// <summary>
/// This function is called when a direct or indirect parent of the transform of the GameObject has changed.
/// </summary>
protected override void OnTransformParentChanged()
{
_canvas = null;
}
void ISerializationCallbackReceiver.OnBeforeSerialize() void ISerializationCallbackReceiver.OnBeforeSerialize()
{ {
} }
@@ -587,7 +545,10 @@ namespace Coffee.UIExtensions
{ {
var ps = particles[i]; var ps = particles[i];
if (!ps if (!ps
#if UNITY_EDITOR
|| (ps.hideFlags & HideFlags.DontSave) != 0 // Dummy ParticleSystems for preview.
|| ps.gameObject.CompareTag("EditorOnly") // Ignore "EditorOnly" tagged ParticleSystems. || ps.gameObject.CompareTag("EditorOnly") // Ignore "EditorOnly" tagged ParticleSystems.
#endif
|| ps.GetComponentInParent<UIParticle>(true) != this) // Ignore ParticleSystems that are not under this UIParticle. || ps.GetComponentInParent<UIParticle>(true) != this) // Ignore ParticleSystems that are not under this UIParticle.
{ {
particles.RemoveAt(i); particles.RemoveAt(i);
@@ -710,6 +671,17 @@ namespace Coffee.UIExtensions
: Random.Range(m_GroupId, m_GroupMaxId + 1); : Random.Range(m_GroupId, m_GroupMaxId + 1);
} }
protected override void UpdateMaterial()
{
}
/// <summary>
/// Call to update the geometry of the Graphic onto the CanvasRenderer.
/// </summary>
protected override void UpdateGeometry()
{
}
private void UpdateRendererMaterial() private void UpdateRendererMaterial()
{ {
for (var i = 0; i < _renderers.Count; i++) for (var i = 0; i < _renderers.Count; i++)

View File

@@ -2,6 +2,7 @@
using Coffee.UIParticleInternal; using Coffee.UIParticleInternal;
using UnityEditor; using UnityEditor;
using UnityEngine; using UnityEngine;
using UnityEngine.Serialization;
namespace Coffee.UIExtensions namespace Coffee.UIExtensions
{ {
@@ -9,12 +10,14 @@ namespace Coffee.UIExtensions
{ {
[Header("Setting")] [Header("Setting")]
[SerializeField] [SerializeField]
internal bool m_EnableLinearToGamma = true; [Tooltip("Automatically correct the color space of the mesh.")]
[FormerlySerializedAs("m_EnableLinearToGamma")]
internal bool m_AutoColorCorrection = true;
public static bool enableLinearToGamma public static bool autoColorCorrection
{ {
get => instance.m_EnableLinearToGamma; get => instance.m_AutoColorCorrection;
set => instance.m_EnableLinearToGamma = value; set => instance.m_AutoColorCorrection = value;
} }
@@ -25,10 +28,16 @@ namespace Coffee.UIExtensions
[SerializeField] [SerializeField]
private bool m_HideGeneratedObjects = true; private bool m_HideGeneratedObjects = true;
public static HideFlags globalHideFlags => instance.m_HideGeneratedObjects [Tooltip("When selecting UIParticle, a temporary ParticleSystem is generated for preview.")]
[SerializeField]
private bool m_PreviewOnSelect = true;
internal static HideFlags globalHideFlags => instance.m_HideGeneratedObjects
? HideFlags.DontSave | HideFlags.NotEditable | HideFlags.HideInHierarchy | HideFlags.HideInInspector ? HideFlags.DontSave | HideFlags.NotEditable | HideFlags.HideInHierarchy | HideFlags.HideInInspector
: HideFlags.DontSave | HideFlags.NotEditable; : HideFlags.DontSave | HideFlags.NotEditable;
internal static bool s_PreviewOnSelectOnSelect => instance.m_PreviewOnSelect;
#if UNITY_EDITOR #if UNITY_EDITOR
[SettingsProvider] [SettingsProvider]
private static SettingsProvider CreateSettingsProvider() private static SettingsProvider CreateSettingsProvider()

View File

@@ -444,7 +444,7 @@ namespace Coffee.UIExtensions
_lastBounds = bounds; _lastBounds = bounds;
// Convert linear color to gamma color. // Convert linear color to gamma color.
if (UIParticleProjectSettings.enableLinearToGamma && canvas.ShouldGammaToLinearInMesh()) if (UIParticleProjectSettings.autoColorCorrection && canvas.ShouldGammaToLinearInMesh())
{ {
workerMesh.LinearToGamma(); workerMesh.LinearToGamma();
} }

View File

@@ -39,6 +39,17 @@ namespace Coffee.UIExtensions
} }
#if UNITY_EDITOR #if UNITY_EDITOR
#if UNITY_2019_3_OR_NEWER
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
private static void OnDomainReload()
{
s_ActiveParticles.Clear();
s_ActiveAttractors.Clear();
s_UpdatedGroupIds.Clear();
s_FrameCount = 0;
}
#endif
[InitializeOnLoadMethod] [InitializeOnLoadMethod]
private static void InitializeOnLoad() private static void InitializeOnLoad()
{ {

View File

@@ -40,12 +40,8 @@
Lighting Off Lighting Off
ZWrite Off ZWrite Off
ZTest [unity_GUIZTestMode] ZTest [unity_GUIZTestMode]
Fog Fog { Mode Off }
{
Mode Off
}
Blend One One Blend One One
ColorMask [_ColorMask] ColorMask [_ColorMask]
Pass Pass
@@ -76,6 +72,7 @@
fixed4 color : COLOR; fixed4 color : COLOR;
float2 texcoord : TEXCOORD0; float2 texcoord : TEXCOORD0;
float4 worldPosition : TEXCOORD1; float4 worldPosition : TEXCOORD1;
float4 mask : TEXCOORD2;
UNITY_VERTEX_OUTPUT_STEREO UNITY_VERTEX_OUTPUT_STEREO
}; };
@@ -84,16 +81,43 @@
float4 _MainTex_ST; float4 _MainTex_ST;
fixed4 _TextureSampleAdd; fixed4 _TextureSampleAdd;
float4 _ClipRect; float4 _ClipRect;
float _UIMaskSoftnessX;
float _UIMaskSoftnessY;
int _UIVertexColorAlwaysGammaSpace;
half3 _UIGammaToLinear(half3 value)
{
half3 low = 0.0849710 * value - 0.000163029;
half3 high = value * (value * (value * 0.265885 + 0.736584) - 0.00980184) + 0.00319697;
// We should be 0.5 away from any actual gamma value stored in an 8 bit channel
const half3 split = (half3)0.0725490; // Equals 18.5 / 255
return (value < split) ? low : high;
}
v2f vert(appdata_t v) v2f vert(appdata_t v)
{ {
v2f OUT; v2f OUT;
UNITY_SETUP_INSTANCE_ID(v); UNITY_SETUP_INSTANCE_ID(v);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT); UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT);
float4 vPosition = UnityObjectToClipPos(v.vertex);
OUT.worldPosition = v.vertex; OUT.worldPosition = v.vertex;
OUT.vertex = UnityObjectToClipPos(OUT.worldPosition); OUT.vertex = vPosition;
OUT.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex); 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)
{
#ifndef UNITY_COLORSPACE_GAMMA
v.color.rgb = _UIGammaToLinear(v.color.rgb);
#endif
}
OUT.color = v.color * _Color; OUT.color = v.color * _Color;
return OUT; return OUT;
@@ -101,10 +125,18 @@
fixed4 frag(v2f IN) : SV_Target fixed4 frag(v2f IN) : SV_Target
{ {
half4 color = (tex2D(_MainTex, IN.texcoord) + _TextureSampleAdd) * IN.color; //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);
IN.color.a = round(IN.color.a * alphaPrecision) * invAlphaPrecision;
half4 color = IN.color * (tex2D(_MainTex, IN.texcoord) + _TextureSampleAdd);
#ifdef UNITY_UI_CLIP_RECT #ifdef UNITY_UI_CLIP_RECT
color.a *= UnityGet2DClipping(IN.worldPosition.xy, _ClipRect); half2 m = saturate((_ClipRect.zw - _ClipRect.xy - abs(IN.mask.xy)) * IN.mask.zw);
color.a *= m.x * m.y;
#endif #endif
#ifdef UNITY_UI_ALPHACLIP #ifdef UNITY_UI_ALPHACLIP
@@ -112,6 +144,7 @@
#endif #endif
color.rgb *= color.a; color.rgb *= color.a;
return color; return color;
} }
ENDCG ENDCG

View File

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