You've already forked ParticleEffectForUGUI
mirror of
https://github.com/mob-sakai/ParticleEffectForUGUI.git
synced 2026-06-29 02:33:43 +00:00
Compare commits
7 Commits
5.0.0-prev
...
0441238cc5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0441238cc5 | ||
|
|
639bc9c342 | ||
|
|
b3d42a2478 | ||
|
|
418b257ae2 | ||
|
|
664c7963ea | ||
|
|
7363f7497c | ||
|
|
f961b8dc89 |
28
.github/workflows/deploy.yml
vendored
28
.github/workflows/deploy.yml
vendored
@@ -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
|
|
||||||
67
.github/workflows/release.yml
vendored
67
.github/workflows/release.yml
vendored
@@ -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
|
||||||
|
|||||||
37
.github/workflows/test.yml
vendored
37
.github/workflows/test.yml
vendored
@@ -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:
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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": {
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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>
|
||||||
{
|
{
|
||||||
@@ -48,6 +49,7 @@ namespace Coffee.UIExtensions
|
|||||||
private static readonly GUIContent s_ContentRandom = new GUIContent("Random");
|
private static readonly GUIContent s_ContentRandom = new GUIContent("Random");
|
||||||
private static readonly GUIContent s_ContentScale = new GUIContent("Scale");
|
private static readonly GUIContent s_ContentScale = new GUIContent("Scale");
|
||||||
private static readonly GUIContent s_ContentPrimary = new GUIContent("Primary");
|
private static readonly GUIContent s_ContentPrimary = new GUIContent("Primary");
|
||||||
|
private static readonly GUIContent s_Remove = new GUIContent("Remove");
|
||||||
private static readonly Regex s_RegexBuiltInGuid = new Regex(@"^0{16}.0{15}$", RegexOptions.Compiled);
|
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 readonly List<Material> s_TempMaterials = new List<Material>();
|
||||||
|
|
||||||
@@ -65,6 +67,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
|
||||||
@@ -86,8 +89,10 @@ namespace Coffee.UIExtensions
|
|||||||
/// <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 +185,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 +206,10 @@ namespace Coffee.UIExtensions
|
|||||||
serializedObject.Update();
|
serializedObject.Update();
|
||||||
|
|
||||||
// Maskable
|
// Maskable
|
||||||
EditorGUILayout.PropertyField(_maskable);
|
if (_maskable != null)
|
||||||
|
{
|
||||||
|
EditorGUILayout.PropertyField(_maskable);
|
||||||
|
}
|
||||||
|
|
||||||
// Scale
|
// Scale
|
||||||
EditorGUI.BeginDisabledGroup(!_meshSharing.hasMultipleDifferentValues && _meshSharing.intValue == 4);
|
EditorGUI.BeginDisabledGroup(!_meshSharing.hasMultipleDifferentValues && _meshSharing.intValue == 4);
|
||||||
@@ -341,6 +356,10 @@ namespace Coffee.UIExtensions
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Remove the temporary ParticleSystem.
|
||||||
|
ParticleSystemPreviewSystem.DrawWarningForTemporary(_gameObjects);
|
||||||
|
|
||||||
Profiler.EndSample();
|
Profiler.EndSample();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -461,11 +480,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 +498,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 +506,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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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://openupm.com/packages/com.coffee.ui-particle/)
|
[](https://openupm.com/packages/com.coffee.ui-particle/)
|
||||||
[](https://github.com/mob-sakai/ParticleEffectForUGUI/releases)
|
[](https://github.com/mob-sakai/ParticleEffectForUGUI/releases)
|
||||||
[](https://github.com/mob-sakai/ParticleEffectForUGUI/blob/main/LICENSE.md)
|
[](https://github.com/mob-sakai/ParticleEffectForUGUI/blob/main/LICENSE.md)
|
||||||

|

|
||||||

|

|
||||||

|

|
||||||

|

|
||||||
@@ -11,7 +11,7 @@
|
|||||||
[](https://github.com/mob-sakai/ParticleEffectForUGUI/subscription)
|
[](https://github.com/mob-sakai/ParticleEffectForUGUI/subscription)
|
||||||
[](https://twitter.com/intent/follow?screen_name=mob_sakai)
|
[](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 -->
|
||||||
|
|
||||||
@@ -26,9 +26,7 @@ You can render, mask, and sort your `ParticleSystems` for UI without the need fo
|
|||||||
- [Install via OpenUPM](#install-via-openupm)
|
- [Install via OpenUPM](#install-via-openupm)
|
||||||
- [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`
|
||||||

|

|
||||||
- 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.
|

|
||||||

|
- 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.
|
||||||

|

|
||||||
|
|
||||||
|
> [!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
|
||||||
|
|
||||||

|
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.
|

|
||||||
|
|
||||||
|
#### 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>
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ namespace Coffee.UIExtensions
|
|||||||
break;
|
break;
|
||||||
case ShaderPropertyType.Float:
|
case ShaderPropertyType.Float:
|
||||||
case ShaderPropertyType.Range:
|
case ShaderPropertyType.Range:
|
||||||
material.SetFloat(id, mpb.GetFloat(id));
|
material.SetFloat(id, mpb.GetFloat(id));
|
||||||
break;
|
break;
|
||||||
case ShaderPropertyType.Texture:
|
case ShaderPropertyType.Texture:
|
||||||
material.SetTexture(id, mpb.GetTexture(id));
|
material.SetTexture(id, mpb.GetTexture(id));
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -39,13 +71,16 @@ namespace Coffee.UIParticleInternal
|
|||||||
var defaultSettings = GetDefaultSettings(t);
|
var defaultSettings = GetDefaultSettings(t);
|
||||||
if (defaultSettings == null)
|
if (defaultSettings == null)
|
||||||
{
|
{
|
||||||
// When create a new instance, automatically set it as default settings.
|
if (!s_BuildingPlayer)
|
||||||
defaultSettings = CreateInstance(t) as PreloadedProjectSettings;
|
{
|
||||||
SetDefaultSettings(defaultSettings);
|
// When create a new instance, automatically set it as default settings.
|
||||||
|
defaultSettings = CreateInstance(t) as PreloadedProjectSettings;
|
||||||
|
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
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -151,7 +215,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 +257,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ namespace Coffee.UIParticleInternal
|
|||||||
UIExtraCallbacks.onLateAfterCanvasRebuild += ClearAllCache;
|
UIExtraCallbacks.onLateAfterCanvasRebuild += ClearAllCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if UNITY_EDITOR
|
#if UNITY_EDITOR && UNITY_2019_2_OR_NEWER
|
||||||
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
|
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
|
||||||
private static void Clear()
|
private static void Clear()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -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_2_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
|
||||||
|
|||||||
@@ -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);
|
Object.Destroy(obj);
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
#endif
|
||||||
{
|
|
||||||
Object.Destroy(obj);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[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)
|
||||||
{
|
{
|
||||||
|
|||||||
88
Packages/src/Runtime/Internal/Utilities/TypeCache.cs
Normal file
88
Packages/src/Runtime/Internal/Utilities/TypeCache.cs
Normal 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
|
||||||
11
Packages/src/Runtime/Internal/Utilities/TypeCache.cs.meta
Normal file
11
Packages/src/Runtime/Internal/Utilities/TypeCache.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: bc1207b657ed74ec19e459664d06925f
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
222
Packages/src/Runtime/ParticleSystemPreviewer.cs
Normal file
222
Packages/src/Runtime/ParticleSystemPreviewer.cs
Normal file
@@ -0,0 +1,222 @@
|
|||||||
|
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>();
|
||||||
|
|
||||||
|
/// <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 _)) return;
|
||||||
|
|
||||||
|
// Create temporary ParticleSystem for preview.
|
||||||
|
var ps = target.AddComponent<ParticleSystem>();
|
||||||
|
ps.hideFlags = k_TemporaryHideFlags;
|
||||||
|
|
||||||
|
var emission = ps.emission;
|
||||||
|
emission.enabled = false;
|
||||||
|
var shape = ps.shape;
|
||||||
|
shape.enabled = false;
|
||||||
|
|
||||||
|
if (target.TryGetComponent<ParticleSystemRenderer>(out var psr))
|
||||||
|
{
|
||||||
|
psr.enabled = false;
|
||||||
|
psr.hideFlags = k_TemporaryHideFlags;
|
||||||
|
}
|
||||||
|
|
||||||
|
instance.m_PreviewObjects.Add(target);
|
||||||
|
EditorUtility.SetDirty(target);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <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 OnEnable()
|
||||||
|
{
|
||||||
|
Selection.selectionChanged -= OnSelectionChanged;
|
||||||
|
Selection.selectionChanged += OnSelectionChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnDisable()
|
||||||
|
{
|
||||||
|
Selection.selectionChanged -= OnSelectionChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
11
Packages/src/Runtime/ParticleSystemPreviewer.cs.meta
Normal file
11
Packages/src/Runtime/ParticleSystemPreviewer.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b171deb49fb7b471291108ad7e1c9baa
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -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.HideAndDontSave // 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++)
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,17 +125,26 @@
|
|||||||
|
|
||||||
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
|
||||||
clip (color.a - 0.001);
|
clip(color.a - 0.001);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
color.rgb *= color.a;
|
color.rgb *= color.a;
|
||||||
|
|
||||||
return color;
|
return color;
|
||||||
}
|
}
|
||||||
ENDCG
|
ENDCG
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
Reference in New Issue
Block a user