Compare commits

..

6 Commits

Author SHA1 Message Date
mob-sakai
09ccb0d47c update demo 2024-07-18 15:04:41 +09:00
mob-sakai
819de92b20 docs: update readme 2024-07-18 14:24:49 +09:00
mob-sakai
1628290db7 feat: add project settings for UIParticle
- enableLinearToGamma: Enables LinearToGamma during mesh baking
2024-07-18 14:21:07 +09:00
mob-sakai
d33bde10d2 install coffee.internal 2024-07-18 14:21:07 +09:00
mob-sakai
29e30a3f1b feat: UIParticle no longer inherits from MaskableGraphic
BREAKING CHANGE: Some members inherited from MaskableGraphic will no longer be available.
2024-07-18 14:15:55 +09:00
mob-sakai
ae838587cb feat: change the default value of UIParticle.scale from 10 to 1
close #310
2024-07-18 14:15:55 +09:00
54 changed files with 2884 additions and 7946 deletions

View File

@@ -1,12 +1,12 @@
name: 🔖 Release name: 🔖 Release
run-name: 🔖 Release (${{ github.ref_name }})
on: on:
workflow_dispatch: workflow_dispatch:
push: push:
branches: branches:
- release - release
- release-* - release-preview
- release-v4
tags-ignore: tags-ignore:
- "**" - "**"
@@ -27,10 +27,10 @@ jobs:
split_to: ${{ steps.summary.outputs.split_to }} split_to: ${{ steps.summary.outputs.split_to }}
steps: steps:
- name: 🚚 Checkout (${{ github.ref_name }}) - name: 🚚 Checkout (${{ github.ref_name }})
uses: actions/checkout@v5 uses: actions/checkout@v4
- name: 🔖 Run semantic release - name: 🔖 Run semantic release
uses: cycjimmy/semantic-release-action@v5 uses: cycjimmy/semantic-release-action@v4
id: release id: release
with: with:
working_directory: Packages/src working_directory: Packages/src
@@ -38,7 +38,7 @@ jobs:
@semantic-release/changelog @semantic-release/changelog
@semantic-release/git @semantic-release/git
env: env:
GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} GITHUB_TOKEN: ${{ github.token }}
- id: summary - id: summary
run: | run: |
@@ -50,12 +50,14 @@ jobs:
if [ '${{ steps.release.outputs.new_release_published }}' = 'false' ]; then if [ '${{ steps.release.outputs.new_release_published }}' = 'false' ]; then
echo "No new release published." | tee -a $GITHUB_STEP_SUMMARY echo "No new release published." | tee -a $GITHUB_STEP_SUMMARY
elif [ '${{ github.ref_name }}' = 'release' ]; then elif [ '${{ github.ref_name }}' = 'release' ]; then
echo "merge_to=develop" | tee -a $GITHUB_OUTPUT $GITHUB_STEP_SUMMARY echo "merge_to=develop" | tee -a $GITHUB_OUTPUT
echo "split_to=main" | tee -a $GITHUB_OUTPUT $GITHUB_STEP_SUMMARY echo "split_to=main" | tee -a $GITHUB_OUTPUT
else elif [ '${{ github.ref_name }}' = 'release-preview' ]; then
channel=$(echo ${{ github.ref_name }} | sed 's/^release-//') echo "merge_to=develop-preview" | tee -a $GITHUB_OUTPUT
echo "merge_to=develop-${channel}" | tee -a $GITHUB_OUTPUT $GITHUB_STEP_SUMMARY echo "split_to=preview" | tee -a $GITHUB_OUTPUT
echo "split_to=${channel}" | tee -a $GITHUB_OUTPUT $GITHUB_STEP_SUMMARY elif [ '${{ github.ref_name }}' = 'release-4.x' ]; then
echo "merge_to=develop-4.x" | tee -a $GITHUB_OUTPUT
echo "split_to=4.x" | tee -a $GITHUB_OUTPUT
fi fi
merge-to: merge-to:
@@ -67,7 +69,7 @@ jobs:
contents: write contents: write
steps: steps:
- name: 🚚 Checkout (${{ needs.release.outputs.merge_to }}) - name: 🚚 Checkout (${{ needs.release.outputs.merge_to }})
uses: actions/checkout@v5 uses: actions/checkout@v4
with: with:
ref: ${{ needs.release.outputs.merge_to }} ref: ${{ needs.release.outputs.merge_to }}
fetch-depth: 0 fetch-depth: 0
@@ -88,7 +90,7 @@ jobs:
contents: write contents: write
steps: steps:
- name: 🚚 Checkout (${{ needs.release.outputs.tag }}) - name: 🚚 Checkout (${{ needs.release.outputs.tag }})
uses: actions/checkout@v5 uses: actions/checkout@v4
with: with:
ref: ${{ needs.release.outputs.tag }} ref: ${{ needs.release.outputs.tag }}
fetch-depth: 0 fetch-depth: 0

View File

@@ -3,37 +3,28 @@
# UNITY_EMAIL: Unity user email to login # UNITY_EMAIL: Unity user email to login
# UNITY_PASSWORD: Unity user password to login # UNITY_PASSWORD: Unity user password to login
name: 🧪 Test name: 🧪 Test
run-name: 🧪 Test (${{ github.event.pull_request.title || github.ref_name }})
env: env:
# MINIMUM_VERSION: The minimum version of Unity. # MINIMUM_VERSION: The minimum version of Unity.
MINIMUM_VERSION: 2019.4 MINIMUM_VERSION: 2019.4
# EXCLUDE_FILTER: The excluded versions of Unity. # EXCLUDE_FILTER: The excluded versions of Unity.
EXCLUDE_FILTER: "(2020.2.0|2021.1|2023.3)" EXCLUDE_FILTER: '(2020.2.0)'
PROJECT_PATH: .
on: on:
workflow_dispatch: workflow_dispatch:
inputs:
usePeriodVersions:
description: "Use the period versions (.0f1, .10f1, 20f1, ...)."
required: false
default: "true"
push: push:
branches: branches:
- develop - develop
- "develop-*" - develop-preview
- develop-4.x
tags: tags:
- "!*" - "!*"
paths-ignore: paths-ignore:
- "**.md" - "*.md"
pull_request_target: pull_request:
types: types:
- opened - opened
- reopened
- synchronize - synchronize
paths-ignore:
- "**.md"
jobs: jobs:
setup: setup:
@@ -46,12 +37,9 @@ jobs:
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` LATEST_VERSIONS=`npx unity-changeset list --versions --latest-patch --min ${MINIMUM_VERSION} --json --all`
if [ "${{ inputs.usePeriodVersions }}" = "true" ]; then # ADDITIONAL_VERSIONS=`npx unity-changeset list --versions --grep '0f' --min ${MINIMUM_VERSION} --json`
ADDITIONAL_VERSIONS=`npx unity-changeset list --versions --grep '0f' --min ${MINIMUM_VERSION} --json`
else
ADDITIONAL_VERSIONS=[] ADDITIONAL_VERSIONS=[]
fi
VERSIONS=`echo "[${LATEST_VERSIONS}, ${ADDITIONAL_VERSIONS}]" \ VERSIONS=`echo "[${LATEST_VERSIONS}, ${ADDITIONAL_VERSIONS}]" \
| jq -c '[ flatten | sort | unique | .[] | select( test("${{ env.EXCLUDE_FILTER }}") | not ) ]'` | jq -c '[ flatten | sort | unique | .[] | select( test("${{ env.EXCLUDE_FILTER }}") | not ) ]'`
@@ -60,57 +48,40 @@ jobs:
test: test:
name: 🧪 Run tests name: 🧪 Run tests
runs-on: ubuntu-latest runs-on: ubuntu-latest
env:
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }}
permissions: permissions:
checks: write checks: write
contents: read contents: read
needs: setup needs: setup
strategy: strategy:
fail-fast: false fail-fast: false
max-parallel: 6 max-parallel: 4
matrix: matrix:
unityVersion: ${{ fromJson(needs.setup.outputs.unityVersions) }} unityVersion: ${{ fromJson(needs.setup.outputs.unityVersions) }}
steps: steps:
- name: 🚚 Checkout ($${{ github.ref }}) - name: 🚚 Checkout
if: github.event_name == 'push' uses: actions/checkout@v4
uses: actions/checkout@v5
- name: 🚚 Checkout pull request (pull_request_target)
if: github.event_name == 'pull_request_target'
uses: actions/checkout@v5
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@v4 uses: actions/cache@v4
with: with:
path: ${{ env.PROJECT_PATH }}/Library path: Library
key: ${{ env.PROJECT_PATH }}-Library-${{ matrix.unityVersion }}-${{ github.event.pull_request.head.sha || github.sha }} key: Library-${{ matrix.unityVersion }}-${{ github.sha }}
restore-keys: | restore-keys: |
${{ env.PROJECT_PATH }}-Library-${{ matrix.unityVersion }}- Library-${{ matrix.unityVersion }}-
${{ env.PROJECT_PATH }}-Library- Library-
- name: 🛠️ Build Unity Project (Test) - name: 🛠️ Build Unity Project
uses: game-ci/unity-builder@main uses: game-ci/unity-builder@v4
timeout-minutes: 45 timeout-minutes: 45
with: with:
customImage: ghcr.io/mob-sakai/unity3d:${{ matrix.unityVersion }} customImage: ghcr.io/mob-sakai/unity3d:${{ matrix.unityVersion }}
targetPlatform: StandaloneLinux64 targetPlatform: StandaloneLinux64
allowDirtyBuild: true allowDirtyBuild: true
customParameters: -nographics customParameters: -nographics
projectPath: ${{ env.PROJECT_PATH }}
env:
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }}
- name: 🧪 Run tests - name: 🧪 Run tests
uses: game-ci/unity-test-runner@v4 uses: game-ci/unity-test-runner@v4
@@ -121,8 +92,4 @@ jobs:
customParameters: -nographics customParameters: -nographics
checkName: ${{ matrix.unityVersion }} Test Results checkName: ${{ matrix.unityVersion }} Test Results
githubToken: ${{ github.token }} githubToken: ${{ github.token }}
projectPath: ${{ env.PROJECT_PATH }} coverageOptions: "dontClear;generateHtmlReport;generateBadgeReport;pathFilters:+**/Packages/src/**;assemblyFilters:+<packages>,-*.Editor,-*.Test"
env:
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }}

File diff suppressed because it is too large Load Diff

View File

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

View File

@@ -80,11 +80,7 @@ namespace Coffee.UIExtensions.Demo
.SelectMany(x => x.GetTypes()) .SelectMany(x => x.GetTypes())
.FirstOrDefault(x => x.Name == typeName); .FirstOrDefault(x => x.Name == typeName);
#if UNITY_2023_2_OR_NEWER
return type == null ? null : FindFirstObjectByType(type);
#else
return type == null ? null : FindObjectOfType(type); return type == null ? null : FindObjectOfType(type);
#endif
} }
public void SetCanvasWidth(int width) public void SetCanvasWidth(int width)

View File

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

View File

@@ -18,12 +18,11 @@ MonoBehaviour:
m_EnabledInEditor: 1 m_EnabledInEditor: 1
m_AlwaysIncludeAssembly: 1 m_AlwaysIncludeAssembly: 1
m_InstantiateOnLoad: 1 m_InstantiateOnLoad: 1
m_Prefab: {fileID: 4567906826058368312, guid: 7cebff2d255b9433cbe23b243c193329, m_Prefab: {fileID: 7211429669315726685, guid: b73940fc30a2f4eb9a73783e9c1f8da6,
type: 3} type: 3}
m_Interval: 0.5 m_Interval: 0.5
m_Anchor: 0 m_Anchor: 0
m_Width: 750 m_Width: 750
m_HelpUrl: https://github.com/mob-sakai/ParticleEffectForUGUI
m_CustomMonitorItems: m_CustomMonitorItems:
- m_Format: Screen:{0}x{1} - m_Format: Screen:{0}x{1}
m_Arg0: m_Arg0:

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: b73940fc30a2f4eb9a73783e9c1f8da6
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -10,7 +10,6 @@ MonoBehaviour:
m_Enabled: 1 m_Enabled: 1
m_EditorHideFlags: 0 m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: f22a23b9d98e440478697f4adf30e61c, type: 3} m_Script: {fileID: 11500000, guid: f22a23b9d98e440478697f4adf30e61c, type: 3}
m_Name: UIParticleProjectSettings m_Name: UIParticle
m_EditorClassIdentifier: m_EditorClassIdentifier:
m_EnableLinearToGamma: 1 m_LinearToGamma: 1
m_HideGeneratedObjects: 1

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: a5b9278dfbd194d04b1c6ae7031928c1 guid: e8e7744b163af4869b07b8f192c810ed
NativeFormatImporter: NativeFormatImporter:
externalObjects: {} externalObjects: {}
mainObjectFileID: 11400000 mainObjectFileID: 11400000

View File

@@ -1,21 +1,16 @@
using System.Collections; using System.Collections;
using Coffee.UIParticleInternal;
using NUnit.Framework; using NUnit.Framework;
using UnityEngine;
using UnityEngine.TestTools; using UnityEngine.TestTools;
namespace Coffee.UIParticle.Editor.Tests namespace Coffee.UIParticle.Editor.Tests
{ {
public class NewTestScript public class NewTestScript
{ {
[TestCase(-1)] // A Test behaves as an ordinary method
[TestCase(0)] [Test]
[TestCase(2048)] public void NewTestScriptSimplePasses()
[TestCase(3000)]
public void GetParticleArray(int requiredSize)
{ {
var array = ParticleSystemExtensions.GetParticleArray(requiredSize); // Use the Assert class to test conditions
Debug.Log($"requiredSize: {requiredSize}, array.Length: {array.Length}");
} }
// A UnityTest behaves like a coroutine in Play Mode. In Edit Mode you can use // A UnityTest behaves like a coroutine in Play Mode. In Edit Mode you can use

View File

@@ -1,9 +1,9 @@
{ {
"dependencies": { "dependencies": {
"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.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.31",
"com.coffee.development": "https://github.com/mob-sakai/Coffee.Internal.git?path=Packages/Development",
"com.coffee.nano-monitor": "https://github.com/mob-sakai/Coffee.Internal.git?path=Packages/NanoMonitor",
"com.coffee.sub-asset-editor": "https://github.com/mob-sakai/SubAssetEditor.git",
"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

@@ -5,14 +5,7 @@
"depth": 0, "depth": 0,
"source": "git", "source": "git",
"dependencies": {}, "dependencies": {},
"hash": "3c280f1a8f4db5038b881ff07f270efd9638fa31" "hash": "c51e4514c9ab944915a639433ee52342e55a644e"
},
"com.coffee.minimal-resource": {
"version": "https://github.com/mob-sakai/Coffee.Internal.git?path=Packages/MinimalResource",
"depth": 0,
"source": "git",
"dependencies": {},
"hash": "3c280f1a8f4db5038b881ff07f270efd9638fa31"
}, },
"com.coffee.nano-monitor": { "com.coffee.nano-monitor": {
"version": "https://github.com/mob-sakai/Coffee.Internal.git?path=Packages/NanoMonitor", "version": "https://github.com/mob-sakai/Coffee.Internal.git?path=Packages/NanoMonitor",
@@ -21,7 +14,14 @@
"dependencies": { "dependencies": {
"com.unity.ugui": "1.0.0" "com.unity.ugui": "1.0.0"
}, },
"hash": "3c280f1a8f4db5038b881ff07f270efd9638fa31" "hash": "c51e4514c9ab944915a639433ee52342e55a644e"
},
"com.coffee.sub-asset-editor": {
"version": "https://github.com/mob-sakai/SubAssetEditor.git",
"depth": 0,
"source": "git",
"dependencies": {},
"hash": "01464178eec1e4dbe741c11c9baeb94a151c99ee"
}, },
"com.coffee.ui-particle": { "com.coffee.ui-particle": {
"version": "file:src", "version": "file:src",

View File

@@ -1,126 +1,3 @@
## [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
* explicit null checks ([5384f61](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/5384f61c569e9f78ff9d5b45acfc6f5c2f021a87))
## [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
* 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)
## [4.11.1](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.11.0...v4.11.1) (2025-02-21)
### Bug Fixes
* component icons will no longer be displayed in the scene view ([6dfbdae](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/6dfbdae38d3822ab9c2c6f0e4ca1ca32ee98a239))
# [4.11.0](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.10.7...v4.11.0) (2025-02-21)
### Features
* add 'TimeScaleMultiplier' option ([925af0b](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/925af0b6046f65f23a778f67cefa8ff9cbedb513))
## [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
* 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)
## [4.10.5](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.10.4...v4.10.5) (2024-12-23)
### Bug Fixes
* '3D' scale toggle in the inspector does not keep on reload ([934f4b8](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/934f4b8f1c61f8ff20228d0ebcea9f636a3758ed)), closes [#346](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/346)
## [4.10.4](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.10.3...v4.10.4) (2024-12-19)
### Bug Fixes
* rendering issues when playing with opening a prefab stage ([95235a9](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/95235a929b82cf681365ed6eba837d857f83e3d2)), closes [#345](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/345)
## [4.10.3](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.10.2...v4.10.3) (2024-11-20)
### Bug Fixes
* if not configured as a preloaded asset, the project settings asset will be regenerated ([abe0948](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/abe09485f65dd4efd18e74675e752e0213bdf3be)), closes [#342](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/342)
## [4.10.2](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.10.1...v4.10.2) (2024-11-01)
### Bug Fixes
* trail incorrect offset ([afe00a1](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/afe00a1dde80eb1c0a7bb668b75f4c3733d3fa43)), closes [#335](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/335)
## [4.10.1](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.10.0...v4.10.1) (2024-09-29)
### Bug Fixes
* mainTex will be ignored ([2ee69d0](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/2ee69d04245fabce185f67dc9bd68c870e556564))
# [4.10.0](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.9.1...v4.10.0) (2024-09-29)
### Bug Fixes
* component icon is not set ([5ff6ec8](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/5ff6ec815a174de5d3f16d424f1204c60912a8d8))
### Features
* add project settings ([1ce4e31](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/1ce4e31a9681bf1a201d2723c8d97e07ecc16592))
## [4.9.1](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.9.0...v4.9.1) (2024-08-07)
### Bug Fixes
* ParticleSystem trails gain offset on parent canvas change ([2a1cd50](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/2a1cd502b452b5b56edf8bcfe91adf99d1bb5147)), closes [#323](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/323)
# [4.9.0](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.8.1...v4.9.0) (2024-07-18) # [4.9.0](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.8.1...v4.9.0) (2024-07-18)

View File

@@ -76,7 +76,7 @@ namespace Coffee.UIExtensions
for (var j = 0; j < mats.Count; j++) for (var j = 0; j < mats.Count; j++)
{ {
var mat = mats[j]; var mat = mats[j];
if (mat == null || mat.shader == null) continue; if (!mat || !mat.shader) continue;
for (var i = 0; i < ShaderUtil.GetPropertyCount(mat.shader); i++) for (var i = 0; i < ShaderUtil.GetPropertyCount(mat.shader); i++)
{ {

View File

@@ -2,19 +2,20 @@ 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;
#if UNITY_2021_2_OR_NEWER #if UNITY_2021_2_OR_NEWER
using UnityEditor.Overlays; using UnityEditor.Overlays;
#else #else
using System; using System;
using System.Reflection; using System.Reflection;
using Coffee.UIParticleInternal;
using Object = UnityEngine.Object; using Object = UnityEngine.Object;
#endif #endif
#if UNITY_2021_2_OR_NEWER #if UNITY_2021_2_OR_NEWER
using UnityEditor.SceneManagement; using UnityEditor.SceneManagement;
@@ -26,13 +27,8 @@ namespace Coffee.UIExtensions
{ {
[CustomEditor(typeof(UIParticle))] [CustomEditor(typeof(UIParticle))]
[CanEditMultipleObjects] [CanEditMultipleObjects]
internal class UIParticleEditor : GraphicEditor internal class UIParticleEditor : Editor
{ {
internal class State : ScriptableSingleton<State>
{
public bool is3DScaleMode;
}
//################################ //################################
// Constant or Static Members. // Constant or Static Members.
//################################ //################################
@@ -51,6 +47,7 @@ namespace Coffee.UIExtensions
private static readonly GUIContent s_ContentPrimary = new GUIContent("Primary"); private static readonly GUIContent s_ContentPrimary = new GUIContent("Primary");
private static readonly Regex s_RegexBuiltInGuid = new Regex(@"^0{16}.0{15}$", RegexOptions.Compiled); private static readonly 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>();
private static bool s_XYZMode;
private SerializedProperty _maskable; private SerializedProperty _maskable;
private SerializedProperty _scale3D; private SerializedProperty _scale3D;
@@ -62,10 +59,8 @@ namespace Coffee.UIExtensions
private SerializedProperty _autoScalingMode; private SerializedProperty _autoScalingMode;
private SerializedProperty _useCustomView; private SerializedProperty _useCustomView;
private SerializedProperty _customViewSize; private SerializedProperty _customViewSize;
private SerializedProperty _timeScaleMultiplier;
private ReorderableList _ro; private ReorderableList _ro;
private bool _showMax; private bool _showMax;
private bool _is3DScaleMode;
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
@@ -87,10 +82,8 @@ 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>
protected override void OnEnable() private 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");
@@ -101,7 +94,6 @@ namespace Coffee.UIExtensions
_autoScalingMode = serializedObject.FindProperty("m_AutoScalingMode"); _autoScalingMode = serializedObject.FindProperty("m_AutoScalingMode");
_useCustomView = serializedObject.FindProperty("m_UseCustomView"); _useCustomView = serializedObject.FindProperty("m_UseCustomView");
_customViewSize = serializedObject.FindProperty("m_CustomViewSize"); _customViewSize = serializedObject.FindProperty("m_CustomViewSize");
_timeScaleMultiplier = serializedObject.FindProperty("m_TimeScaleMultiplier");
var sp = serializedObject.FindProperty("m_Particles"); var sp = serializedObject.FindProperty("m_Particles");
_ro = new ReorderableList(sp.serializedObject, sp, true, true, true, true) _ro = new ReorderableList(sp.serializedObject, sp, true, true, true, true)
@@ -110,7 +102,7 @@ namespace Coffee.UIExtensions
{ {
var ps = sp.GetArrayElementAtIndex(index).objectReferenceValue as ParticleSystem; var ps = sp.GetArrayElementAtIndex(index).objectReferenceValue as ParticleSystem;
var materialCount = 0; var materialCount = 0;
if (ps != null && ps.TryGetComponent<ParticleSystemRenderer>(out var psr)) if (ps && ps.TryGetComponent<ParticleSystemRenderer>(out var psr))
{ {
materialCount = psr.sharedMaterials.Length; materialCount = psr.sharedMaterials.Length;
} }
@@ -124,7 +116,7 @@ namespace Coffee.UIExtensions
var p = sp.GetArrayElementAtIndex(index); var p = sp.GetArrayElementAtIndex(index);
EditorGUI.ObjectField(rect, p, GUIContent.none); EditorGUI.ObjectField(rect, p, GUIContent.none);
var ps = p.objectReferenceValue as ParticleSystem; var ps = p.objectReferenceValue as ParticleSystem;
if (ps == null || !ps.TryGetComponent<ParticleSystemRenderer>(out var psr)) return; if (!ps || !ps.TryGetComponent<ParticleSystemRenderer>(out var psr)) return;
rect.x += 15; rect.x += 15;
rect.width -= 15; rect.width -= 15;
@@ -170,19 +162,6 @@ namespace Coffee.UIExtensions
uip.RefreshParticles(uip.particles); uip.RefreshParticles(uip.particles);
} }
} }
// Initialize 3D scale mode.
_is3DScaleMode = State.instance.is3DScaleMode;
if (!_is3DScaleMode)
{
var x = _scale3D.FindPropertyRelative("x");
var y = _scale3D.FindPropertyRelative("y");
var z = _scale3D.FindPropertyRelative("z");
_is3DScaleMode = !Mathf.Approximately(x.floatValue, y.floatValue) ||
!Mathf.Approximately(y.floatValue, z.floatValue) ||
y.hasMultipleDifferentValues ||
z.hasMultipleDifferentValues;
}
} }
/// <summary> /// <summary>
@@ -191,7 +170,7 @@ namespace Coffee.UIExtensions
public override void OnInspectorGUI() public override void OnInspectorGUI()
{ {
var current = target as UIParticle; var current = target as UIParticle;
if (current == null) return; if (!current) return;
Profiler.BeginSample("(UIP:E) OnInspectorGUI"); Profiler.BeginSample("(UIP:E) OnInspectorGUI");
serializedObject.Update(); serializedObject.Update();
@@ -201,11 +180,7 @@ namespace Coffee.UIExtensions
// Scale // Scale
EditorGUI.BeginDisabledGroup(!_meshSharing.hasMultipleDifferentValues && _meshSharing.intValue == 4); EditorGUI.BeginDisabledGroup(!_meshSharing.hasMultipleDifferentValues && _meshSharing.intValue == 4);
if (DrawFloatOrVector3Field(_scale3D, _is3DScaleMode) != _is3DScaleMode) s_XYZMode = DrawFloatOrVector3Field(_scale3D, s_XYZMode);
{
State.instance.is3DScaleMode = _is3DScaleMode = !_is3DScaleMode;
}
EditorGUI.EndDisabledGroup(); EditorGUI.EndDisabledGroup();
// AnimatableProperties // AnimatableProperties
@@ -246,9 +221,6 @@ namespace Coffee.UIExtensions
_customViewSize.floatValue = Mathf.Max(0.1f, _customViewSize.floatValue); _customViewSize.floatValue = Mathf.Max(0.1f, _customViewSize.floatValue);
} }
// Time Scale Multiplier
EditorGUILayout.PropertyField(_timeScaleMultiplier);
// Target ParticleSystems. // Target ParticleSystems.
EditorGUI.BeginChangeCheck(); EditorGUI.BeginChangeCheck();
_ro.DoLayoutList(); _ro.DoLayoutList();
@@ -267,7 +239,7 @@ namespace Coffee.UIExtensions
Profiler.BeginSample("(UIP:E) Non-UI built-in shader is not supported."); Profiler.BeginSample("(UIP:E) Non-UI built-in shader is not supported.");
foreach (var mat in s_TempMaterials) foreach (var mat in s_TempMaterials)
{ {
if (mat == null || mat.shader == null) continue; if (!mat || !mat.shader) continue;
var shader = mat.shader; var shader = mat.shader;
if (IsBuiltInObject(shader) && !shader.name.StartsWith("UI/")) if (IsBuiltInObject(shader) && !shader.name.StartsWith("UI/"))
{ {
@@ -286,7 +258,7 @@ namespace Coffee.UIExtensions
{ {
foreach (var mat in s_TempMaterials) foreach (var mat in s_TempMaterials)
{ {
if (mat == null || mat.shader == null) continue; if (!mat || !mat.shader) continue;
var shader = mat.shader; var shader = mat.shader;
if (!s_Shaders.Add(shader)) continue; if (!s_Shaders.Add(shader)) continue;
@@ -464,9 +436,7 @@ namespace Coffee.UIExtensions
{ {
if (!p || (ignoreCurrent && target == p)) return; if (!p || (ignoreCurrent && target == p)) return;
var cr = p.canvasRenderer;
DestroyImmediate(p); DestroyImmediate(p);
DestroyImmediate(cr);
#if UNITY_2018_3_OR_NEWER #if UNITY_2018_3_OR_NEWER
var stage = PrefabStageUtility.GetCurrentPrefabStage(); var stage = PrefabStageUtility.GetCurrentPrefabStage();

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

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

View File

Before

Width:  |  Height:  |  Size: 418 B

After

Width:  |  Height:  |  Size: 418 B

View File

@@ -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) | [🚀 Usage](#-usage) | [🛠 Development Note](#-development-note) | [🤝 Contributing](#-contributing) >> << [📝 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 <!-- omit in toc --> ## 📝 Description <!-- omit in toc -->
@@ -27,6 +27,8 @@ 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 3.x/4.x to 5.x](#-upgrading-from-3x4x-to-5x)
- [Breaking Changes](#breaking-changes)
- [🚀 Usage](#-usage) - [🚀 Usage](#-usage)
- [Component: UIParticle](#component-uiparticle) - [Component: UIParticle](#component-uiparticle)
- [Basic Usage](#basic-usage) - [Basic Usage](#basic-usage)
@@ -34,7 +36,6 @@ You can render, mask, and sort your `ParticleSystems` for UI without the need fo
- [Usage with `Mask` or `RectMask2D` Component](#usage-with-mask-or-rectmask2d-component) - [Usage with `Mask` or `RectMask2D` Component](#usage-with-mask-or-rectmask2d-component)
- [Usage with Script](#usage-with-script) - [Usage with Script](#usage-with-script)
- [Component: UIParticleAttractor](#component-uiparticleattractor) - [Component: UIParticleAttractor](#component-uiparticleattractor)
- [Project Settings](#project-settings)
- [🛠 Development Note](#-development-note) - [🛠 Development Note](#-development-note)
- [Compares the Baking mesh approach with the conventional approach](#compares-the-baking-mesh-approach-with-the-conventional-approach) - [Compares the Baking mesh approach with the conventional approach](#compares-the-baking-mesh-approach-with-the-conventional-approach)
- [Performance test results](#performance-test-results) - [Performance test results](#performance-test-results)
@@ -144,7 +145,7 @@ _This package requires **Unity 2018.3 or later**._
#### Install as Embedded Package #### Install as Embedded Package
1. Download a source code zip file from [Releases](https://github.com/mob-sakai/ParticleEffectForUGUI/releases) and extract it. 1. Download a source code zip file from [Releases](https://github.com/mob-sakai/ParticleEffectForUGUI.git/releases) and extract it.
2. Place it in your project's `Packages` directory. 2. Place it in your project's `Packages` directory.
![](https://github.com/mob-sakai/mob-sakai/assets/12690315/0b7484b4-5fca-43b0-a9ef-e5dbd99bcdb4) ![](https://github.com/mob-sakai/mob-sakai/assets/12690315/0b7484b4-5fca-43b0-a9ef-e5dbd99bcdb4)
- If you want to fix bugs or add features, install it as an embedded package. - If you want to fix bugs or add features, install it as an embedded package.
@@ -152,13 +153,24 @@ _This package requires **Unity 2018.3 or later**._
<br><br> <br><br>
## 🔄 Upgrading from 3.x/4.x to 5.x
### Breaking Changes
- The default value of `UIParticle.scale` has been changed from `10` to `1`.
- `UIParticle` no longer inherits from `MaskableGraphic`.
- Add project settings for UIParticle
- enableLinearToGamma: Enables LinearToGamma during mesh baking
<br><br>
## 🚀 Usage ## 🚀 Usage
### Component: UIParticle ### Component: UIParticle
`UIParticle` controls the ParticleSystems that are attached to its own game objects and child game objects. `UIParticle` controls the ParticleSystems that are attached to its own game objects and child game objects.
![](https://github.com/user-attachments/assets/bc9eb783-afce-4102-ac61-aee9ea8d6f2f) ![](https://github.com/mob-sakai/ParticleEffectForUGUI/assets/12690315/1cf5753b-33fc-4cef-91c3-413c515a954f)
- **Maskable**: Does this graphic allow maskable. - **Maskable**: Does this graphic allow maskable.
- **Scale**: Scale the rendering particles. When the `3D` toggle is enabled, 3D scale (x, y, z) is supported. - **Scale**: Scale the rendering particles. When the `3D` toggle is enabled, 3D scale (x, y, z) is supported.
@@ -180,7 +192,6 @@ _This package requires **Unity 2018.3 or later**._
- **UIParticle:** UIParticle.scale will be adjusted. - **UIParticle:** UIParticle.scale will be adjusted.
- **Use Custom View:** Use this if the particles are not displayed correctly due to min/max particle size. - **Use Custom View:** Use this if the particles are not displayed correctly due to min/max particle size.
- **Custom view size:** Change the bake view size. - **Custom view size:** Change the bake view size.
- **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 **NOTE:** Press the `Refresh` button to reconstruct the rendering order based on children ParticleSystem's sorting order
@@ -211,7 +222,7 @@ and z-position.
If you want to mask particles, set a stencil-supported shader (such as `UI/UIAdditive`) to the material for If you want to mask particles, set a stencil-supported shader (such as `UI/UIAdditive`) to the material for
ParticleSystem. ParticleSystem.
If you use some custom shaders, see If you use some custom shaders, see
the [How to Make a Custom Shader to Support Mask/RectMask2D Component](#how-to-make-a-custom-shader-to-support-mask-and-rectmask2d-component) the [How to Make a Custom Shader to Support Mask/RectMask2D Component](#how-to-make-a-custom-shader-to-support-maskrectmask2d-component)
section. section.
![](https://user-images.githubusercontent.com/12690315/95017591-3b512700-0695-11eb-864e-04166ea1809a.png) ![](https://user-images.githubusercontent.com/12690315/95017591-3b512700-0695-11eb-864e-04166ea1809a.png)
@@ -258,14 +269,6 @@ uiParticle.Stop();
<br><br> <br><br>
### Project Settings
![](https://github.com/user-attachments/assets/befc7f34-fb47-4006-831a-eba79fda11ca)
- Click `Edit > Project Settings` to open the Project Settings window and then select `UI > UI Particle` category.
<br><br>
## 🛠 Development Note ## 🛠 Development Note
### Compares the Baking mesh approach with the conventional approach ### Compares the Baking mesh approach with the conventional approach

View File

@@ -1,33 +0,0 @@
fileFormatVersion: 2
guid: 4d73b3825bf044d418ae21bb331d3902
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 1
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 1
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
Windows Store Apps: WindowsStoreApps
second:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -18,10 +18,10 @@ namespace Coffee.UIParticleInternal
public static T[] GetComponentsInChildren<T>(this Component self, int depth) public static T[] GetComponentsInChildren<T>(this Component self, int depth)
where T : Component where T : Component
{ {
var results = InternalListPool<T>.Rent(); var results = ListPool<T>.Rent();
self.GetComponentsInChildren_Internal(results, depth); self.GetComponentsInChildren_Internal(results, depth);
var array = results.ToArray(); var array = results.ToArray();
InternalListPool<T>.Return(ref results); ListPool<T>.Return(ref results);
return array; return array;
} }
@@ -38,7 +38,7 @@ namespace Coffee.UIParticleInternal
private static void GetComponentsInChildren_Internal<T>(this Component self, List<T> results, int depth) private static void GetComponentsInChildren_Internal<T>(this Component self, List<T> results, int depth)
where T : Component where T : Component
{ {
if (self == null || results == null || depth < 0) return; if (!self || results == null || depth < 0) return;
var tr = self.transform; var tr = self.transform;
if (tr.TryGetComponent<T>(out var t)) if (tr.TryGetComponent<T>(out var t))
@@ -59,7 +59,7 @@ namespace Coffee.UIParticleInternal
/// </summary> /// </summary>
public static T GetOrAddComponent<T>(this Component self) where T : Component public static T GetOrAddComponent<T>(this Component self) where T : Component
{ {
if (self == null) return null; if (!self) return null;
return self.TryGetComponent<T>(out var component) return self.TryGetComponent<T>(out var component)
? component ? component
: self.gameObject.AddComponent<T>(); : self.gameObject.AddComponent<T>();
@@ -134,39 +134,10 @@ namespace Coffee.UIParticleInternal
Profiler.EndSample(); Profiler.EndSample();
} }
/// <summary>
/// Add a component of a specific type to the children of a GameObject.
/// </summary>
public static void AddComponentOnChildren<T>(this Component self, bool includeSelf)
where T : Component
{
if (self == null) return;
Profiler.BeginSample("(COF)[ComponentExt] AddComponentOnChildren > Self");
if (includeSelf && !self.TryGetComponent<T>(out _))
{
self.gameObject.AddComponent<T>();
}
Profiler.EndSample();
Profiler.BeginSample("(COF)[ComponentExt] AddComponentOnChildren > Child");
var childCount = self.transform.childCount;
for (var i = 0; i < childCount; i++)
{
var child = self.transform.GetChild(i);
if (child.TryGetComponent<T>(out _)) continue;
child.gameObject.AddComponent<T>();
}
Profiler.EndSample();
}
#if !UNITY_2021_2_OR_NEWER && !UNITY_2020_3_45 && !UNITY_2020_3_46 && !UNITY_2020_3_47 && !UNITY_2020_3_48 #if !UNITY_2021_2_OR_NEWER && !UNITY_2020_3_45 && !UNITY_2020_3_46 && !UNITY_2020_3_47 && !UNITY_2020_3_48
public static T GetComponentInParent<T>(this Component self, bool includeInactive) where T : Component public static T GetComponentInParent<T>(this Component self, bool includeInactive) where T : Component
{ {
if (self == null) return null; if (!self) return null;
if (!includeInactive) return self.GetComponentInParent<T>(); if (!includeInactive) return self.GetComponentInParent<T>();
var current = self.transform; var current = self.transform;
@@ -186,7 +157,7 @@ namespace Coffee.UIParticleInternal
/// </summary> /// </summary>
internal static bool CanConvertTo<T>(this Object context) where T : MonoBehaviour internal static bool CanConvertTo<T>(this Object context) where T : MonoBehaviour
{ {
return context != null && context.GetType() != typeof(T); return context && context.GetType() != typeof(T);
} }
/// <summary> /// <summary>
@@ -204,7 +175,7 @@ namespace Coffee.UIParticleInternal
target.enabled = false; target.enabled = false;
// Find MonoScript of the specified component. // Find MonoScript of the specified component.
foreach (var script in MonoImporter.GetAllRuntimeMonoScripts()) foreach (var script in Resources.FindObjectsOfTypeAll<MonoScript>())
{ {
if (script.GetClass() != typeof(T)) if (script.GetClass() != typeof(T))
{ {

View File

@@ -0,0 +1,19 @@
using System.Collections.Generic;
namespace Coffee.UIParticleInternal
{
/// <summary>
/// Extension methods for Component class.
/// </summary>
internal static class ListExtensions
{
public static void RemoveAtFast<T>(this List<T> self, int index)
{
if (self == null) return;
var lastIndex = self.Count - 1;
self[index] = self[lastIndex];
self.RemoveAt(lastIndex);
}
}
}

View File

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

View File

@@ -0,0 +1,48 @@
using System.Diagnostics;
using UnityEditor;
using UnityEngine;
namespace Coffee.UIParticleInternal
{
internal static class Misc
{
public static void Destroy(Object obj)
{
if (!obj) return;
#if UNITY_EDITOR
if (!Application.isPlaying)
{
Object.DestroyImmediate(obj);
}
else
#endif
{
Object.Destroy(obj);
}
}
public static void DestroyImmediate(Object obj)
{
if (!obj) return;
#if UNITY_EDITOR
if (Application.isEditor)
{
Object.DestroyImmediate(obj);
}
else
#endif
{
Object.Destroy(obj);
}
}
[Conditional("UNITY_EDITOR")]
public static void SetDirty(Object obj)
{
#if UNITY_EDITOR
if (!obj) return;
EditorUtility.SetDirty(obj);
#endif
}
}
}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 182319ecc315e4858b119764af0fbcb0 guid: 39ed6a6b0a72e482488bd298b2ae762e
MonoImporter: MonoImporter:
externalObjects: {} externalObjects: {}
serializedVersion: 2 serializedVersion: 2

View File

@@ -17,25 +17,23 @@ namespace Coffee.UIParticleInternal
Type.GetType("UnityEditor.Experimental.U2D.SpriteEditorExtension, UnityEditor") Type.GetType("UnityEditor.Experimental.U2D.SpriteEditorExtension, UnityEditor")
?? Type.GetType("UnityEditor.U2D.SpriteEditorExtension, UnityEditor"); ?? Type.GetType("UnityEditor.U2D.SpriteEditorExtension, UnityEditor");
private static readonly Func<Sprite, Texture2D> s_GetActiveAtlasTextureMethod = private static readonly MethodInfo s_GetActiveAtlasTextureMethod = s_SpriteEditorExtensionType
(Func<Sprite, Texture2D>)Delegate.CreateDelegate(typeof(Func<Sprite, Texture2D>), .GetMethod("GetActiveAtlasTexture", BindingFlags.Static | BindingFlags.NonPublic);
s_SpriteEditorExtensionType
.GetMethod("GetActiveAtlasTexture", BindingFlags.Static | BindingFlags.NonPublic));
private static readonly Func<Sprite, SpriteAtlas> s_GetActiveAtlasMethod = private static readonly MethodInfo s_GetActiveAtlasMethod = s_SpriteEditorExtensionType
(Func<Sprite, SpriteAtlas>)Delegate.CreateDelegate(typeof(Func<Sprite, SpriteAtlas>), .GetMethod("GetActiveAtlas", BindingFlags.Static | BindingFlags.NonPublic);
s_SpriteEditorExtensionType
.GetMethod("GetActiveAtlas", BindingFlags.Static | BindingFlags.NonPublic));
/// <summary> /// <summary>
/// Get the actual texture of a sprite in play mode or edit mode. /// Get the actual texture of a sprite in play mode or edit mode.
/// </summary> /// </summary>
public static Texture2D GetActualTexture(this Sprite self) public static Texture2D GetActualTexture(this Sprite self)
{ {
if (self == null) return null; if (!self) return null;
var ret = s_GetActiveAtlasTextureMethod(self); if (Application.isPlaying) return self.texture;
return ret != null ? ret : self.texture;
var ret = s_GetActiveAtlasTextureMethod.Invoke(null, new object[] { self }) as Texture2D;
return ret ? ret : self.texture;
} }
/// <summary> /// <summary>
@@ -43,9 +41,9 @@ namespace Coffee.UIParticleInternal
/// </summary> /// </summary>
public static SpriteAtlas GetActiveAtlas(this Sprite self) public static SpriteAtlas GetActiveAtlas(this Sprite self)
{ {
if (self == null) return null; if (!self) return null;
return s_GetActiveAtlasMethod(self); return s_GetActiveAtlasMethod.Invoke(null, new object[] { self }) as SpriteAtlas;
} }
#else #else
/// <summary> /// <summary>
@@ -53,7 +51,7 @@ namespace Coffee.UIParticleInternal
/// </summary> /// </summary>
internal static Texture2D GetActualTexture(this Sprite self) internal static Texture2D GetActualTexture(this Sprite self)
{ {
return self != null ? self.texture : null; return self ? self.texture : null;
} }
#endif #endif
} }

View File

@@ -1,9 +1,9 @@
using System; using System;
using System.Linq; using System.Linq;
using System.Reflection;
using UnityEngine; using UnityEngine;
using Object = UnityEngine.Object; using Object = UnityEngine.Object;
#if UNITY_EDITOR #if UNITY_EDITOR
using System.IO;
using UnityEditor; using UnityEditor;
using UnityEditor.Build; using UnityEditor.Build;
using UnityEditor.Build.Reporting; using UnityEditor.Build.Reporting;
@@ -14,14 +14,6 @@ namespace Coffee.UIParticleInternal
public abstract class PreloadedProjectSettings : ScriptableObject public abstract class PreloadedProjectSettings : ScriptableObject
#if UNITY_EDITOR #if UNITY_EDITOR
{ {
private class Postprocessor : AssetPostprocessor
{
private static void OnPostprocessAllAssets(string[] _, string[] __, string[] ___, string[] ____)
{
Initialize();
}
}
private class PreprocessBuildWithReport : IPreprocessBuildWithReport private class PreprocessBuildWithReport : IPreprocessBuildWithReport
{ {
int IOrderedCallback.callbackOrder => 0; int IOrderedCallback.callbackOrder => 0;
@@ -32,32 +24,32 @@ namespace Coffee.UIParticleInternal
} }
} }
[InitializeOnLoadMethod]
[InitializeOnEnterPlayMode]
private static void Initialize() private static void Initialize()
{ {
const BindingFlags flags = BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy;
foreach (var t in TypeCache.GetTypesDerivedFrom(typeof(PreloadedProjectSettings<>))) foreach (var t in TypeCache.GetTypesDerivedFrom(typeof(PreloadedProjectSettings<>)))
{ {
var defaultSettings = GetDefaultSettings(t); var defaultSettings = GetDefaultSettings(t);
if (defaultSettings == null) if (!defaultSettings)
{ {
// When create a new instance, automatically set it as default settings. defaultSettings = t.GetProperty("instance", flags)
defaultSettings = CreateInstance(t) as PreloadedProjectSettings; ?.GetValue(null, null) as PreloadedProjectSettings;
SetDefaultSettings(defaultSettings); SetDefaultSettings(defaultSettings);
} }
else if (GetPreloadedSettings(t).Length != 1) else if (GetPreloadedSettings(t).Length != 1)
{ {
SetDefaultSettings(defaultSettings); SetDefaultSettings(defaultSettings);
} }
}
if (defaultSettings != null) EditorApplication.QueuePlayerLoopUpdate();
{
defaultSettings.OnInitialize();
}
}
} }
protected static string GetDefaultName(Type type, bool nicify) protected static string GetDefaultName(Type type, bool nicify)
{ {
var typeName = type.Name; var typeName = type.Name.Replace("ProjectSettings", "");
return nicify return nicify
? ObjectNames.NicifyVariableName(typeName) ? ObjectNames.NicifyVariableName(typeName)
: typeName; : typeName;
@@ -66,7 +58,7 @@ namespace Coffee.UIParticleInternal
private static Object[] GetPreloadedSettings(Type type) private static Object[] GetPreloadedSettings(Type type)
{ {
return PlayerSettings.GetPreloadedAssets() return PlayerSettings.GetPreloadedAssets()
.Where(x => x != null && x.GetType() == type) .Where(x => x && x.GetType() == type)
.ToArray(); .ToArray();
} }
@@ -76,13 +68,11 @@ namespace Coffee.UIParticleInternal
?? AssetDatabase.FindAssets($"t:{nameof(PreloadedProjectSettings)}") ?? AssetDatabase.FindAssets($"t:{nameof(PreloadedProjectSettings)}")
.Select(AssetDatabase.GUIDToAssetPath) .Select(AssetDatabase.GUIDToAssetPath)
.Select(AssetDatabase.LoadAssetAtPath<PreloadedProjectSettings>) .Select(AssetDatabase.LoadAssetAtPath<PreloadedProjectSettings>)
.FirstOrDefault(x => x != null && x.GetType() == type); .FirstOrDefault(x => x && x.GetType() == type);
} }
protected static void SetDefaultSettings(PreloadedProjectSettings asset) protected static void SetDefaultSettings(PreloadedProjectSettings asset)
{ {
if (asset == null) return;
var type = asset.GetType(); var type = asset.GetType();
if (string.IsNullOrEmpty(AssetDatabase.GetAssetPath(asset))) if (string.IsNullOrEmpty(AssetDatabase.GetAssetPath(asset)))
{ {
@@ -93,17 +83,13 @@ namespace Coffee.UIParticleInternal
var assetPath = $"Assets/ProjectSettings/{GetDefaultName(type, false)}.asset"; var assetPath = $"Assets/ProjectSettings/{GetDefaultName(type, false)}.asset";
assetPath = AssetDatabase.GenerateUniqueAssetPath(assetPath); assetPath = AssetDatabase.GenerateUniqueAssetPath(assetPath);
if (!File.Exists(assetPath))
{
AssetDatabase.CreateAsset(asset, assetPath); AssetDatabase.CreateAsset(asset, assetPath);
asset.OnCreateAsset();
}
} }
var preloadedAssets = PlayerSettings.GetPreloadedAssets(); var preloadedAssets = PlayerSettings.GetPreloadedAssets();
var projectSettings = GetPreloadedSettings(type); var projectSettings = GetPreloadedSettings(type);
PlayerSettings.SetPreloadedAssets(preloadedAssets PlayerSettings.SetPreloadedAssets(preloadedAssets
.Where(x => x != null) .Where(x => x)
.Except(projectSettings.Except(new[] { asset })) .Except(projectSettings.Except(new[] { asset }))
.Append(asset) .Append(asset)
.Distinct() .Distinct()
@@ -111,20 +97,13 @@ namespace Coffee.UIParticleInternal
AssetDatabase.Refresh(); AssetDatabase.Refresh();
} }
protected virtual void OnCreateAsset()
{
}
protected virtual void OnInitialize()
{
}
} }
#else #else
{ {
} }
#endif #endif
public abstract class PreloadedProjectSettings<T> : PreloadedProjectSettings public abstract class PreloadedProjectSettings<T> : PreloadedProjectSettings
where T : PreloadedProjectSettings<T> where T : PreloadedProjectSettings<T>
{ {
@@ -133,19 +112,17 @@ namespace Coffee.UIParticleInternal
#if UNITY_EDITOR #if UNITY_EDITOR
private string _jsonText; private string _jsonText;
public static bool hasInstance => s_Instance != null;
public static T instance public static T instance
{ {
get get
{ {
if (s_Instance != null) return s_Instance; if (s_Instance) return s_Instance;
s_Instance = GetDefaultSettings(typeof(T)) as T; s_Instance = GetDefaultSettings(typeof(T)) as T;
if (s_Instance != null) return s_Instance; if (s_Instance) return s_Instance;
s_Instance = CreateInstance<T>(); s_Instance = CreateInstance<T>();
if (s_Instance == null) if (!s_Instance)
{ {
s_Instance = null; s_Instance = null;
return s_Instance; return s_Instance;
@@ -174,7 +151,7 @@ namespace Coffee.UIParticleInternal
} }
} }
#else #else
public static T instance => s_Instance != null ? s_Instance : s_Instance = CreateInstance<T>(); public static T instance => s_Instance ? s_Instance : s_Instance = CreateInstance<T>();
#endif #endif
/// <summary> /// <summary>
@@ -183,7 +160,7 @@ namespace Coffee.UIParticleInternal
protected virtual void OnEnable() protected virtual void OnEnable()
{ {
#if UNITY_EDITOR #if UNITY_EDITOR
var isDefaultSettings = s_Instance == null || s_Instance == this || GetDefaultSettings(typeof(T)) == this; var isDefaultSettings = !s_Instance || s_Instance == this || GetDefaultSettings(typeof(T)) == this;
if (!isDefaultSettings) if (!isDefaultSettings)
{ {
DestroyImmediate(this, true); DestroyImmediate(this, true);
@@ -193,7 +170,7 @@ namespace Coffee.UIParticleInternal
EditorApplication.playModeStateChanged += OnPlayModeStateChanged; EditorApplication.playModeStateChanged += OnPlayModeStateChanged;
#endif #endif
if (s_Instance != null) return; if (s_Instance) return;
s_Instance = this as T; s_Instance = this as T;
} }
@@ -222,7 +199,7 @@ namespace Coffee.UIParticleInternal
public override void OnGUI(string searchContext) public override void OnGUI(string searchContext)
{ {
if (_target == null) if (!_target)
{ {
if (_editor) if (_editor)
{ {

View File

@@ -10,9 +10,8 @@ namespace Coffee.UIParticleInternal
/// </summary> /// </summary>
internal class FastActionBase<T> internal class FastActionBase<T>
{ {
private static readonly InternalObjectPool<LinkedListNode<T>> s_NodePool = private static readonly ObjectPool<LinkedListNode<T>> s_NodePool =
new InternalObjectPool<LinkedListNode<T>>(() => new LinkedListNode<T>(default), _ => true, new ObjectPool<LinkedListNode<T>>(() => new LinkedListNode<T>(default), _ => true, x => x.Value = default);
x => x.Value = default);
private readonly LinkedList<T> _delegates = new LinkedList<T>(); private readonly LinkedList<T> _delegates = new LinkedList<T>();

View File

@@ -46,6 +46,7 @@ namespace Coffee.UIParticleInternal
GetFrameCache<T>().Set((key1.GetHashCode(), key2.GetHashCode()), result); GetFrameCache<T>().Set((key1.GetHashCode(), key2.GetHashCode()), result);
} }
/// <summary> /// <summary>
/// Sets a value in the frame cache with a specified key. /// Sets a value in the frame cache with a specified key.
/// </summary> /// </summary>

View File

@@ -5,6 +5,7 @@ using Object = UnityEngine.Object;
#if ENABLE_COFFEE_LOGGER #if ENABLE_COFFEE_LOGGER
using System.Reflection; using System.Reflection;
using System.Collections.Generic; using System.Collections.Generic;
#else #else
using Conditional = System.Diagnostics.ConditionalAttribute; using Conditional = System.Diagnostics.ConditionalAttribute;
#endif #endif
@@ -42,40 +43,44 @@ namespace Coffee.UIParticleInternal
#endif #endif
} }
#if !ENABLE_COFFEE_LOGGER #if !ENABLE_COFFEE_LOGGER
[Conditional(k_DisableSymbol)] [Conditional(k_DisableSymbol)]
#endif #endif
public static void LogIf(bool enable, object tag, object message, Object context = null) public static void LogIf(bool enable, object tag, object message, Object context = null)
{ {
if (!enable) return; if (!enable) return;
Log_Internal(LogType.Log, tag, message, context != null ? context : tag as Object); Log_Internal(LogType.Log, tag, message, context ? context : tag as Object);
} }
#if !ENABLE_COFFEE_LOGGER #if !ENABLE_COFFEE_LOGGER
[Conditional(k_DisableSymbol)] [Conditional(k_DisableSymbol)]
#endif #endif
public static void Log(object tag, object message, Object context = null) public static void Log(object tag, object message, Object context = null)
{ {
Log_Internal(LogType.Log, tag, message, context != null ? context : tag as Object); Log_Internal(LogType.Log, tag, message, context ? context : tag as Object);
} }
#if !ENABLE_COFFEE_LOGGER #if !ENABLE_COFFEE_LOGGER
[Conditional(k_DisableSymbol)] [Conditional(k_DisableSymbol)]
#endif #endif
public static void LogWarning(object tag, object message, Object context = null) public static void LogWarning(object tag, object message, Object context = null)
{ {
Log_Internal(LogType.Warning, tag, message, context != null ? context : tag as Object); Log_Internal(LogType.Warning, tag, message, context ? context : tag as Object);
} }
public static void LogError(object tag, object message, Object context = null) public static void LogError(object tag, object message, Object context = null)
{ {
#if ENABLE_COFFEE_LOGGER #if ENABLE_COFFEE_LOGGER
Log_Internal(LogType.Error, tag, message, context != null ? context : tag as Object); Log_Internal(LogType.Error, tag, message, context ? context : tag as Object);
#else #else
Debug.LogError($"{tag}: {message}", context); Debug.LogError($"{tag}: {message}", context);
#endif #endif
} }
#if !ENABLE_COFFEE_LOGGER #if !ENABLE_COFFEE_LOGGER
[Conditional(k_DisableSymbol)] [Conditional(k_DisableSymbol)]
#endif #endif
@@ -119,6 +124,7 @@ namespace Coffee.UIParticleInternal
#endif #endif
} }
#if !ENABLE_COFFEE_LOGGER #if !ENABLE_COFFEE_LOGGER
[Conditional(k_DisableSymbol)] [Conditional(k_DisableSymbol)]
#endif #endif
@@ -164,6 +170,7 @@ namespace Coffee.UIParticleInternal
#endif #endif
} }
#if !ENABLE_COFFEE_LOGGER #if !ENABLE_COFFEE_LOGGER
[Conditional(k_DisableSymbol)] [Conditional(k_DisableSymbol)]
#endif #endif
@@ -202,6 +209,7 @@ namespace Coffee.UIParticleInternal
#endif #endif
} }
#if !ENABLE_COFFEE_LOGGER #if !ENABLE_COFFEE_LOGGER
[Conditional(k_DisableSymbol)] [Conditional(k_DisableSymbol)]
#endif #endif

View File

@@ -15,7 +15,7 @@ namespace Coffee.UIParticleInternal
#if UNITY_EDITOR #if UNITY_EDITOR
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
public static void Clear() private static void Clear()
{ {
s_Repository.Clear(); s_Repository.Clear();
} }
@@ -55,6 +55,7 @@ namespace Coffee.UIParticleInternal
Profiler.EndSample(); Profiler.EndSample();
} }
/// <summary> /// <summary>
/// Adds or retrieves a cached material based on the hash. /// Adds or retrieves a cached material based on the hash.
/// </summary> /// </summary>

View File

@@ -1,132 +0,0 @@
using System;
using System.Diagnostics;
using UnityEditor;
using UnityEngine;
using Object = UnityEngine.Object;
#if UNITY_EDITOR
using System.IO;
using System.Linq;
using System.Reflection;
#if UNITY_2021_2_OR_NEWER
using UnityEditor.SceneManagement;
#else
using UnityEditor.Experimental.SceneManagement;
#endif
#endif
namespace Coffee.UIParticleInternal
{
internal static class Misc
{
public static T[] FindObjectsOfType<T>() where T : Object
{
#if UNITY_2023_1_OR_NEWER
return Object.FindObjectsByType<T>(FindObjectsInactive.Include, FindObjectsSortMode.None);
#else
return Object.FindObjectsOfType<T>();
#endif
}
public static void Destroy(Object obj)
{
if (obj == null) return;
#if UNITY_EDITOR
if (!Application.isPlaying)
{
Object.DestroyImmediate(obj);
}
else
#endif
{
Object.Destroy(obj);
}
}
public static void DestroyImmediate(Object obj)
{
if (obj == null) return;
#if UNITY_EDITOR
if (Application.isEditor)
{
Object.DestroyImmediate(obj);
}
else
#endif
{
Object.Destroy(obj);
}
}
[Conditional("UNITY_EDITOR")]
public static void SetDirty(Object obj)
{
#if UNITY_EDITOR
if (obj == null) return;
EditorUtility.SetDirty(obj);
#endif
}
#if UNITY_EDITOR
public static T[] GetAllComponentsInPrefabStage<T>() where T : Component
{
var prefabStage = PrefabStageUtility.GetCurrentPrefabStage();
if (prefabStage == null) return Array.Empty<T>();
return prefabStage.prefabContentsRoot.GetComponentsInChildren<T>(true);
}
public static bool isBatchOrBuilding => Application.isBatchMode || BuildPipeline.isBuildingPlayer;
#endif
[Conditional("UNITY_EDITOR")]
public static void QueuePlayerLoopUpdate()
{
#if UNITY_EDITOR
if (!EditorApplication.isPlaying)
{
EditorApplication.QueuePlayerLoopUpdate();
}
#endif
}
}
#if !UNITY_2021_2_OR_NEWER
[AttributeUsage(AttributeTargets.Class)]
[Conditional("UNITY_EDITOR")]
internal class IconAttribute : Attribute
{
private readonly string _path;
public IconAttribute(string path)
{
_path = path;
}
#if UNITY_EDITOR
private static Action<Object, Texture2D> s_SetIconForObject = typeof(EditorGUIUtility)
.GetMethod("SetIconForObject", BindingFlags.Static | BindingFlags.NonPublic)
.CreateDelegate(typeof(Action<Object, Texture2D>), null) as Action<Object, Texture2D>;
[InitializeOnLoadMethod]
private static void InitializeOnLoadMethod()
{
if (Misc.isBatchOrBuilding) return;
var types = TypeCache.GetTypesWithAttribute<IconAttribute>();
var scripts = MonoImporter.GetAllRuntimeMonoScripts();
foreach (var type in types)
{
var script = scripts.FirstOrDefault(x => x.GetClass() == type);
if (script == null) continue;
var path = type.GetCustomAttribute<IconAttribute>()?._path;
var icon = AssetDatabase.LoadAssetAtPath<Texture2D>(path);
if (icon == null) continue;
s_SetIconForObject(script, icon);
}
}
#endif
}
#endif
}

View File

@@ -6,58 +6,15 @@ namespace Coffee.UIParticleInternal
/// <summary> /// <summary>
/// Object pool. /// Object pool.
/// </summary> /// </summary>
internal class InternalObjectPool<T> where T : class internal class ObjectPool<T>
{ {
#if UNITY_2021_1_OR_NEWER
private readonly Predicate<T> _onValid; // Delegate for checking if instances are valid
private readonly UnityEngine.Pool.ObjectPool<T> _pool;
public InternalObjectPool(Func<T> onCreate, Predicate<T> onValid, Action<T> onReturn)
{
_pool = new UnityEngine.Pool.ObjectPool<T>(onCreate, null, onReturn);
_onValid = onValid;
}
/// <summary>
/// Rent an instance from the pool.
/// When you no longer need it, return it with <see cref="Return" />.
/// </summary>
public T Rent()
{
while (0 < _pool.CountInactive)
{
var instance = _pool.Get();
if (_onValid(instance))
{
return instance;
}
}
// If there are no instances in the pool, create a new one.
Logging.Log(this, $"A new instance is created (pooled: {_pool.CountInactive}, created: {_pool.CountAll}).");
return _pool.Get();
}
/// <summary>
/// Return an instance to the pool and assign null.
/// Be sure to return the instance obtained with <see cref="Rent" /> with this method.
/// </summary>
public void Return(ref T instance)
{
if (instance == null) return; // Ignore if already pooled or null.
_pool.Release(instance);
Logging.Log(this, $"An instance is released (pooled: {_pool.CountInactive}, created: {_pool.CountAll}).");
instance = default; // Set the reference to null.
}
#else
private readonly Func<T> _onCreate; // Delegate for creating instances private readonly Func<T> _onCreate; // Delegate for creating instances
private readonly Action<T> _onReturn; // Delegate for returning instances to the pool private readonly Action<T> _onReturn; // Delegate for returning instances to the pool
private readonly Predicate<T> _onValid; // Delegate for checking if instances are valid private readonly Predicate<T> _onValid; // Delegate for checking if instances are valid
private readonly Stack<T> _pool = new Stack<T>(32); // Object pool private readonly Stack<T> _pool = new Stack<T>(32); // Object pool
private int _count; // Total count of created instances private int _count; // Total count of created instances
public InternalObjectPool(Func<T> onCreate, Predicate<T> onValid, Action<T> onReturn) public ObjectPool(Func<T> onCreate, Predicate<T> onValid, Action<T> onReturn)
{ {
_onCreate = onCreate; _onCreate = onCreate;
_onValid = onValid; _onValid = onValid;
@@ -97,40 +54,15 @@ namespace Coffee.UIParticleInternal
Logging.Log(this, $"An instance is released (pooled: {_pool.Count}, created: {_count})."); Logging.Log(this, $"An instance is released (pooled: {_pool.Count}, created: {_count}).");
instance = default; // Set the reference to null. instance = default; // Set the reference to null.
} }
#endif
} }
/// <summary> /// <summary>
/// Object pool for <see cref="List{T}" />. /// Object pool for <see cref="List{T}" />.
/// </summary> /// </summary>
internal static class InternalListPool<T> internal static class ListPool<T>
{ {
#if UNITY_2021_1_OR_NEWER private static readonly ObjectPool<List<T>> s_ListPool =
/// <summary> new ObjectPool<List<T>>(() => new List<T>(), _ => true, x => x.Clear());
/// Rent an instance from the pool.
/// When you no longer need it, return it with <see cref="Return" />.
/// </summary>
public static List<T> Rent()
{
return UnityEngine.Pool.ListPool<T>.Get();
}
/// <summary>
/// Return an instance to the pool and assign null.
/// Be sure to return the instance obtained with <see cref="Rent" /> with this method.
/// </summary>
public static void Return(ref List<T> toRelease)
{
if (toRelease != null)
{
UnityEngine.Pool.ListPool<T>.Release(toRelease);
}
toRelease = null;
}
#else
private static readonly InternalObjectPool<List<T>> s_ListPool =
new InternalObjectPool<List<T>>(() => new List<T>(), _ => true, x => x.Clear());
/// <summary> /// <summary>
/// Rent an instance from the pool. /// Rent an instance from the pool.
@@ -149,6 +81,5 @@ namespace Coffee.UIParticleInternal
{ {
s_ListPool.Return(ref toRelease); s_ListPool.Return(ref toRelease);
} }
#endif
} }
} }

View File

@@ -90,7 +90,7 @@ namespace Coffee.UIParticleInternal
Profiler.BeginSample("(COF)[ObjectRepository] GetFromCache"); Profiler.BeginSample("(COF)[ObjectRepository] GetFromCache");
if (_cache.TryGetValue(hash, out var entry)) if (_cache.TryGetValue(hash, out var entry))
{ {
if (entry.storedObject == null) if (!entry.storedObject)
{ {
Release(ref entry.storedObject); Release(ref entry.storedObject);
Profiler.EndSample(); Profiler.EndSample();
@@ -116,7 +116,7 @@ namespace Coffee.UIParticleInternal
private void Add(Hash128 hash, ref T obj, T newObject) private void Add(Hash128 hash, ref T obj, T newObject)
{ {
if (newObject == null) if (!newObject)
{ {
Release(ref obj); Release(ref obj);
obj = newObject; obj = newObject;
@@ -151,7 +151,7 @@ namespace Coffee.UIParticleInternal
&& _cache.TryGetValue(hash, out var entry)) && _cache.TryGetValue(hash, out var entry))
{ {
entry.reference--; entry.reference--;
if (entry.reference <= 0 || entry.storedObject == null) if (entry.reference <= 0 || !entry.storedObject)
{ {
Remove(entry); Remove(entry);
} }
@@ -192,7 +192,7 @@ namespace Coffee.UIParticleInternal
public void Release(Action<T> onRelease) public void Release(Action<T> onRelease)
{ {
reference = 0; reference = 0;
if (storedObject != null) if (storedObject)
{ {
onRelease?.Invoke(storedObject); onRelease?.Invoke(storedObject);
} }

View File

@@ -14,8 +14,6 @@ namespace Coffee.UIParticleInternal
private static readonly FastAction s_AfterCanvasRebuildAction = new FastAction(); private static readonly FastAction s_AfterCanvasRebuildAction = new FastAction();
private static readonly FastAction s_LateAfterCanvasRebuildAction = new FastAction(); private static readonly FastAction s_LateAfterCanvasRebuildAction = new FastAction();
private static readonly FastAction s_BeforeCanvasRebuildAction = new FastAction(); private static readonly FastAction s_BeforeCanvasRebuildAction = new FastAction();
private static readonly FastAction s_OnScreenSizeChangedAction = new FastAction();
private static Vector2Int s_LastScreenSize;
static UIExtraCallbacks() static UIExtraCallbacks()
{ {
@@ -50,15 +48,6 @@ namespace Coffee.UIParticleInternal
remove => s_AfterCanvasRebuildAction.Remove(value); remove => s_AfterCanvasRebuildAction.Remove(value);
} }
/// <summary>
/// Event that occurs when the screen size changes.
/// </summary>
public static event Action onScreenSizeChanged
{
add => s_OnScreenSizeChangedAction.Add(value);
remove => s_OnScreenSizeChangedAction.Remove(value);
}
/// <summary> /// <summary>
/// Initializes the UIExtraCallbacks to ensure proper event handling. /// Initializes the UIExtraCallbacks to ensure proper event handling.
/// </summary> /// </summary>
@@ -88,17 +77,6 @@ namespace Coffee.UIParticleInternal
/// </summary> /// </summary>
private static void OnBeforeCanvasRebuild() private static void OnBeforeCanvasRebuild()
{ {
var screenSize = new Vector2Int(Screen.width, Screen.height);
if (s_LastScreenSize != screenSize)
{
if (s_LastScreenSize != default)
{
s_OnScreenSizeChangedAction.Invoke();
}
s_LastScreenSize = screenSize;
}
s_BeforeCanvasRebuildAction.Invoke(); s_BeforeCanvasRebuildAction.Invoke();
InitializeAfterCanvasRebuild(); InitializeAfterCanvasRebuild();
} }

View File

@@ -3,26 +3,22 @@ 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")]
[assembly: InternalsVisibleTo("Coffee.UIParticle.Editor.Tests")]
[assembly: InternalsVisibleTo("Coffee.UIParticle.PerformanceDemo")]
[assembly: InternalsVisibleTo("Coffee.UIParticle.Demo")]
namespace Coffee.UIExtensions namespace Coffee.UIExtensions
{ {
/// <summary> /// <summary>
/// Render maskable and sortable particle effect ,without Camera, RenderTexture or Canvas. /// Render maskable and sortable particle effect ,without Camera, RenderTexture or Canvas.
/// </summary> /// </summary>
[Icon("Packages/com.coffee.ui-particle/Editor/UIParticleIcon.png")]
[ExecuteAlways] [ExecuteAlways]
[RequireComponent(typeof(RectTransform))] [RequireComponent(typeof(RectTransform))]
[RequireComponent(typeof(CanvasRenderer))] [RequireComponent(typeof(CanvasRenderer))]
public class UIParticle : MaskableGraphic, ISerializationCallbackReceiver public class UIParticle : UIBehaviour, ISerializationCallbackReceiver
{ {
public enum AutoScalingMode public enum AutoScalingMode
{ {
@@ -64,7 +60,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(10, 10, 10); private Vector3 m_Scale3D = new Vector3(1, 1, 1);
[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.")]
@@ -122,23 +118,47 @@ namespace Coffee.UIExtensions
private float m_CustomViewSize = 10; private float m_CustomViewSize = 10;
[SerializeField] [SerializeField]
[Tooltip("Time scale multiplier.")] private bool m_Maskable = true;
private float m_TimeScaleMultiplier = 1;
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;
/// <summary> public RectTransform rectTransform => transform as RectTransform;
/// Should this graphic be considered a target for ray-casting?
/// </summary> public Canvas canvas
public override bool raycastTarget
{ {
get => false; get
set { } {
if (_canvas) return _canvas;
var tr = transform;
while (tr && !_canvas)
{
if (tr.TryGetComponent(out _canvas)) return _canvas;
tr = tr.parent;
}
return null;
}
}
/// <summary>
/// Does this graphic allow masking.
/// </summary>
public bool maskable
{
get => m_Maskable;
set
{
if (value == m_Maskable) return;
m_Maskable = value;
UpdateRendererMaterial();
}
} }
/// <summary> /// <summary>
@@ -263,15 +283,6 @@ namespace Coffee.UIExtensions
set => m_CustomViewSize = Mathf.Max(0.1f, value); set => m_CustomViewSize = Mathf.Max(0.1f, value);
} }
/// <summary>
/// Time scale multiplier.
/// </summary>
public float timeScaleMultiplier
{
get => m_TimeScaleMultiplier;
set => m_TimeScaleMultiplier = value;
}
internal bool useMeshSharing => m_MeshSharing != MeshSharing.None; internal bool useMeshSharing => m_MeshSharing != MeshSharing.None;
internal bool isPrimary => internal bool isPrimary =>
@@ -324,15 +335,15 @@ namespace Coffee.UIExtensions
public Vector3 parentScale { get; private set; } public Vector3 parentScale { get; private set; }
public Vector3 canvasScale { get; private set; } private Vector3 canvasScale { get; 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);
@@ -342,7 +353,7 @@ namespace Coffee.UIExtensions
RefreshParticles(); RefreshParticles();
} }
base.OnEnable(); UpdateRendererMaterial();
} }
/// <summary> /// <summary>
@@ -359,9 +370,15 @@ namespace Coffee.UIExtensions
_isScaleStored = false; _isScaleStored = false;
UIParticleUpdater.Unregister(this); UIParticleUpdater.Unregister(this);
_renderers.ForEach(r => r.Reset()); _renderers.ForEach(r => r.Reset());
UnregisterDirtyMaterialCallback(UpdateRendererMaterial); _canvas = null;
}
base.OnDisable(); /// <summary>
/// Called when the state of the parent Canvas is changed.
/// </summary>
protected override void OnCanvasHierarchyChanged()
{
_canvas = null;
} }
/// <summary> /// <summary>
@@ -371,6 +388,14 @@ 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()
{ {
} }
@@ -471,7 +496,7 @@ namespace Coffee.UIExtensions
for (var i = 0; i < _renderers.Count; i++) for (var i = 0; i < _renderers.Count; i++)
{ {
var r = _renderers[i]; var r = _renderers[i];
if (r == null || r.material == null) continue; if (!r || !r.material) continue;
result.Add(r.material); result.Add(r.material);
} }
} }
@@ -489,7 +514,7 @@ namespace Coffee.UIExtensions
/// </summary> /// </summary>
public void SetParticleSystemInstance(GameObject instance, bool destroyOldParticles) public void SetParticleSystemInstance(GameObject instance, bool destroyOldParticles)
{ {
if (instance == null) return; if (!instance) return;
var childCount = transform.childCount; var childCount = transform.childCount;
for (var i = 0; i < childCount; i++) for (var i = 0; i < childCount; i++)
@@ -518,7 +543,7 @@ namespace Coffee.UIExtensions
/// </summary> /// </summary>
public void SetParticleSystemPrefab(GameObject prefab) public void SetParticleSystemPrefab(GameObject prefab)
{ {
if (prefab == null) return; if (!prefab) return;
SetParticleSystemInstance(Instantiate(prefab.gameObject), true); SetParticleSystemInstance(Instantiate(prefab.gameObject), true);
} }
@@ -538,14 +563,12 @@ namespace Coffee.UIExtensions
/// </summary> /// </summary>
private void RefreshParticles(GameObject root) private void RefreshParticles(GameObject root)
{ {
if (root == null) return; if (!root) return;
root.GetComponentsInChildren(true, particles); root.GetComponentsInChildren(true, particles);
for (var i = particles.Count - 1; 0 <= i; i--) for (var i = particles.Count - 1; 0 <= i; i--)
{ {
var ps = particles[i]; var ps = particles[i];
if (!ps if (!ps || ps.GetComponentInParent<UIParticle>(true) != this)
|| ps.gameObject.CompareTag("EditorOnly") // Ignore "EditorOnly" tagged ParticleSystems.
|| ps.GetComponentInParent<UIParticle>(true) != this) // Ignore ParticleSystems that are not under this UIParticle.
{ {
particles.RemoveAt(i); particles.RemoveAt(i);
} }
@@ -593,15 +616,13 @@ namespace Coffee.UIExtensions
for (var i = 0; i < particleSystems.Count; i++) for (var i = 0; i < particleSystems.Count; i++)
{ {
var ps = particleSystems[i]; var ps = particleSystems[i];
if (ps == null) continue; if (!ps) continue;
GetRenderer(j++).Set(this, ps, false);
var mainEmitter = ps.GetMainEmitter(particleSystems);
GetRenderer(j++).Set(this, ps, false, mainEmitter);
// If the trail is enabled, set it additionally. // If the trail is enabled, set it additionally.
if (ps.trails.enabled) if (ps.trails.enabled)
{ {
GetRenderer(j++).Set(this, ps, true, mainEmitter); GetRenderer(j++).Set(this, ps, true);
} }
} }
} }
@@ -644,7 +665,7 @@ namespace Coffee.UIExtensions
for (var i = 0; i < _renderers.Count; i++) for (var i = 0; i < _renderers.Count; i++)
{ {
var r = _renderers[i]; var r = _renderers[i];
if (r != null) continue; if (r) continue;
RefreshParticles(particles); RefreshParticles(particles);
break; break;
@@ -654,7 +675,7 @@ namespace Coffee.UIExtensions
for (var i = 0; i < _renderers.Count; i++) for (var i = 0; i < _renderers.Count; i++)
{ {
var r = _renderers[i]; var r = _renderers[i];
if (r == null) continue; if (!r) continue;
r.UpdateMesh(bakeCamera); r.UpdateMesh(bakeCamera);
} }
@@ -667,23 +688,12 @@ 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++)
{ {
var r = _renderers[i]; var r = _renderers[i];
if (r == null) continue; if (!r) continue;
r.maskable = maskable; r.maskable = maskable;
r.SetMaterialDirty(); r.SetMaterialDirty();
} }
@@ -696,7 +706,7 @@ namespace Coffee.UIExtensions
_renderers.Add(UIParticleRenderer.AddRenderer(this, index)); _renderers.Add(UIParticleRenderer.AddRenderer(this, index));
} }
if (_renderers[index] == null) if (!_renderers[index])
{ {
_renderers[index] = UIParticleRenderer.AddRenderer(this, index); _renderers[index] = UIParticleRenderer.AddRenderer(this, index);
} }
@@ -706,13 +716,13 @@ namespace Coffee.UIExtensions
private Camera GetBakeCamera() private Camera GetBakeCamera()
{ {
if (canvas == null) return Camera.main; if (!canvas) return Camera.main;
if (!useCustomView && canvas.renderMode != RenderMode.ScreenSpaceOverlay && canvas.rootCanvas.worldCamera) if (!useCustomView && canvas.renderMode != RenderMode.ScreenSpaceOverlay && canvas.rootCanvas.worldCamera)
{ {
return canvas.rootCanvas.worldCamera; return canvas.rootCanvas.worldCamera;
} }
if (_bakeCamera != null) if (_bakeCamera)
{ {
_bakeCamera.orthographicSize = useCustomView ? customViewSize : 10; _bakeCamera.orthographicSize = useCustomView ? customViewSize : 10;
return _bakeCamera; return _bakeCamera;
@@ -731,7 +741,7 @@ namespace Coffee.UIExtensions
} }
// Create baking camera. // Create baking camera.
if (_bakeCamera == null) if (!_bakeCamera)
{ {
var go = new GameObject("[generated] UIParticle BakingCamera"); var go = new GameObject("[generated] UIParticle BakingCamera");
go.SetActive(false); go.SetActive(false);
@@ -753,7 +763,7 @@ namespace Coffee.UIExtensions
_bakeCamera.useOcclusionCulling = false; _bakeCamera.useOcclusionCulling = false;
_bakeCamera.gameObject.SetActive(false); _bakeCamera.gameObject.SetActive(false);
_bakeCamera.gameObject.hideFlags = UIParticleProjectSettings.globalHideFlags; _bakeCamera.gameObject.hideFlags = HideFlags.HideAndDontSave;
return _bakeCamera; return _bakeCamera;
} }

View File

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

View File

@@ -148,7 +148,7 @@ namespace Coffee.UIExtensions
// Collect UIParticle if needed (same size as m_ParticleSystems) // Collect UIParticle if needed (same size as m_ParticleSystems)
CollectUIParticlesIfNeeded(); CollectUIParticlesIfNeeded();
for (var particleIndex = 0; particleIndex < m_ParticleSystems.Count; particleIndex++) for (var particleIndex = 0; particleIndex < this.m_ParticleSystems.Count; particleIndex++)
{ {
var particleSystem = m_ParticleSystems[particleIndex]; var particleSystem = m_ParticleSystems[particleIndex];
@@ -163,21 +163,21 @@ namespace Coffee.UIExtensions
particleSystem.GetParticles(particles, count); particleSystem.GetParticles(particles, count);
var uiParticle = _uiParticles[particleIndex]; var uiParticle = _uiParticles[particleIndex];
var dstPos = GetDestinationPosition(uiParticle, particleSystem); var dstPos = this.GetDestinationPosition(uiParticle, particleSystem);
for (var i = 0; i < count; i++) for (var i = 0; i < count; i++)
{ {
// Attracted // Attracted
var p = particles[i]; var p = particles[i];
if (0f < p.remainingLifetime && Vector3.Distance(p.position, dstPos) < m_DestinationRadius) if (0f < p.remainingLifetime && Vector3.Distance(p.position, dstPos) < this.m_DestinationRadius)
{ {
p.remainingLifetime = 0f; p.remainingLifetime = 0f;
particles[i] = p; particles[i] = p;
if (m_OnAttracted != null) if (this.m_OnAttracted != null)
{ {
try try
{ {
m_OnAttracted.Invoke(); this.m_OnAttracted.Invoke();
} }
catch (Exception e) catch (Exception e)
{ {
@@ -189,7 +189,7 @@ namespace Coffee.UIExtensions
} }
// Calc attracting time // Calc attracting time
var delayTime = p.startLifetime * m_DelayRate; var delayTime = p.startLifetime * this.m_DelayRate;
var duration = p.startLifetime - delayTime; var duration = p.startLifetime - delayTime;
var time = Mathf.Max(0, p.startLifetime - p.remainingLifetime - delayTime); var time = Mathf.Max(0, p.startLifetime - p.remainingLifetime - delayTime);
@@ -197,7 +197,7 @@ namespace Coffee.UIExtensions
if (time <= 0) continue; if (time <= 0) continue;
// Attract // Attract
p.position = GetAttractedPosition(p.position, dstPos, duration, time); p.position = this.GetAttractedPosition(p.position, dstPos, duration, time);
p.velocity *= 0.5f; p.velocity *= 0.5f;
particles[i] = p; particles[i] = p;
} }
@@ -208,7 +208,7 @@ namespace Coffee.UIExtensions
private Vector3 GetDestinationPosition(UIParticle uiParticle, ParticleSystem particleSystem) private Vector3 GetDestinationPosition(UIParticle uiParticle, ParticleSystem particleSystem)
{ {
var isUI = uiParticle != null && uiParticle.enabled; var isUI = uiParticle && uiParticle.enabled;
var psPos = particleSystem.transform.position; var psPos = particleSystem.transform.position;
var attractorPos = transform.position; var attractorPos = transform.position;
var dstPos = attractorPos; var dstPos = attractorPos;

View File

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

View File

@@ -17,18 +17,6 @@ namespace Coffee.UIExtensions
set => instance.m_EnableLinearToGamma = value; set => instance.m_EnableLinearToGamma = value;
} }
[Header("Editor")]
[Tooltip("Hide the automatically generated objects.\n" +
" - UIParticleRenderer\n" +
" - UIParticle BakingCamera")]
[SerializeField]
private bool m_HideGeneratedObjects = true;
public static HideFlags globalHideFlags => instance.m_HideGeneratedObjects
? HideFlags.DontSave | HideFlags.NotEditable | HideFlags.HideInHierarchy | HideFlags.HideInInspector
: HideFlags.DontSave | HideFlags.NotEditable;
#if UNITY_EDITOR #if UNITY_EDITOR
[SettingsProvider] [SettingsProvider]
private static SettingsProvider CreateSettingsProvider() private static SettingsProvider CreateSettingsProvider()

View File

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

View File

@@ -4,6 +4,7 @@
#elif UNITY_2022_3_OR_NEWER #elif UNITY_2022_3_OR_NEWER
#define PS_BAKE_API_V2 #define PS_BAKE_API_V2
#endif #endif
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Coffee.UIParticleInternal; using Coffee.UIParticleInternal;
@@ -15,7 +16,6 @@ using UnityEngine.UI;
namespace Coffee.UIExtensions namespace Coffee.UIExtensions
{ {
[Icon("Packages/com.coffee.ui-particle/Editor/UIParticleIcon.png")]
[ExecuteAlways] [ExecuteAlways]
[RequireComponent(typeof(RectTransform))] [RequireComponent(typeof(RectTransform))]
[RequireComponent(typeof(CanvasRenderer))] [RequireComponent(typeof(CanvasRenderer))]
@@ -41,7 +41,6 @@ namespace Coffee.UIExtensions
private Vector2Int _prevScreenSize; private Vector2Int _prevScreenSize;
private bool _preWarm; private bool _preWarm;
private ParticleSystemRenderer _renderer; private ParticleSystemRenderer _renderer;
private ParticleSystem _mainEmitter;
public override Texture mainTexture => _isTrail ? null : _particleSystem.GetTextureForSprite(); public override Texture mainTexture => _isTrail ? null : _particleSystem.GetTextureForSprite();
@@ -55,7 +54,7 @@ namespace Coffee.UIExtensions
s_Corners[1] = transform.TransformPoint(_lastBounds.min.x, _lastBounds.max.y, 0); s_Corners[1] = transform.TransformPoint(_lastBounds.min.x, _lastBounds.max.y, 0);
s_Corners[2] = transform.TransformPoint(_lastBounds.max.x, _lastBounds.max.y, 0); s_Corners[2] = transform.TransformPoint(_lastBounds.max.x, _lastBounds.max.y, 0);
s_Corners[3] = transform.TransformPoint(_lastBounds.max.x, _lastBounds.min.y, 0); s_Corners[3] = transform.TransformPoint(_lastBounds.max.x, _lastBounds.min.y, 0);
if (canvas != null) if (canvas)
{ {
var worldToLocalMatrix = canvas.rootCanvas.transform.worldToLocalMatrix; var worldToLocalMatrix = canvas.rootCanvas.transform.worldToLocalMatrix;
for (var i = 0; i < 4; ++i) for (var i = 0; i < 4; ++i)
@@ -95,7 +94,7 @@ namespace Coffee.UIExtensions
{ {
get get
{ {
if (_materialForRendering == null) if (!_materialForRendering)
{ {
_materialForRendering = base.materialForRendering; _materialForRendering = base.materialForRendering;
} }
@@ -106,7 +105,7 @@ namespace Coffee.UIExtensions
public void Reset(int index = -1) public void Reset(int index = -1)
{ {
if (_renderer != null) if (_renderer)
{ {
_renderer.enabled = true; _renderer.enabled = true;
} }
@@ -114,14 +113,13 @@ namespace Coffee.UIExtensions
_parent = null; _parent = null;
_particleSystem = null; _particleSystem = null;
_renderer = null; _renderer = null;
_mainEmitter = null;
if (0 <= index) if (0 <= index)
{ {
_index = index; _index = index;
} }
//_emitter = null; //_emitter = null;
if (isActiveAndEnabled) if (this && isActiveAndEnabled)
{ {
material = null; material = null;
canvasRenderer.Clear(); canvasRenderer.Clear();
@@ -139,8 +137,7 @@ namespace Coffee.UIExtensions
{ {
base.OnEnable(); base.OnEnable();
hideFlags = UIParticleProjectSettings.globalHideFlags; if (!s_CombineInstances[0].mesh)
if (s_CombineInstances[0].mesh == null)
{ {
s_CombineInstances[0].mesh = new Mesh s_CombineInstances[0].mesh = new Mesh
{ {
@@ -164,7 +161,7 @@ namespace Coffee.UIExtensions
// Create renderer object. // Create renderer object.
var go = new GameObject("[generated] UIParticleRenderer", typeof(UIParticleRenderer)) var go = new GameObject("[generated] UIParticleRenderer", typeof(UIParticleRenderer))
{ {
hideFlags = UIParticleProjectSettings.globalHideFlags, hideFlags = HideFlags.HideAndDontSave,
layer = parent.gameObject.layer layer = parent.gameObject.layer
}; };
@@ -204,6 +201,7 @@ namespace Coffee.UIExtensions
return modifiedMaterial; return modifiedMaterial;
} }
//
var hash = new Hash128( var hash = new Hash128(
modifiedMaterial ? (uint)modifiedMaterial.GetInstanceID() : 0, modifiedMaterial ? (uint)modifiedMaterial.GetInstanceID() : 0,
texture ? (uint)texture.GetInstanceID() : 0, texture ? (uint)texture.GetInstanceID() : 0,
@@ -226,7 +224,7 @@ namespace Coffee.UIExtensions
return _modifiedMaterial; return _modifiedMaterial;
} }
public void Set(UIParticle parent, ParticleSystem ps, bool isTrail, ParticleSystem mainEmitter) public void Set(UIParticle parent, ParticleSystem ps, bool isTrail)
{ {
_parent = parent; _parent = parent;
maskable = parent.maskable; maskable = parent.maskable;
@@ -249,7 +247,10 @@ namespace Coffee.UIExtensions
ps.TryGetComponent(out _renderer); ps.TryGetComponent(out _renderer);
_renderer.enabled = false; _renderer.enabled = false;
//_emitter = emitter;
_isTrail = isTrail; _isTrail = isTrail;
_renderer.GetSharedMaterials(s_Materials); _renderer.GetSharedMaterials(s_Materials);
material = s_Materials[isTrail ? 1 : 0]; material = s_Materials[isTrail ? 1 : 0];
s_Materials.Clear(); s_Materials.Clear();
@@ -266,7 +267,6 @@ namespace Coffee.UIExtensions
_prevScreenSize = new Vector2Int(Screen.width, Screen.height); _prevScreenSize = new Vector2Int(Screen.width, Screen.height);
_prevCanvasScale = canvas ? canvas.scaleFactor : 1f; _prevCanvasScale = canvas ? canvas.scaleFactor : 1f;
_delay = true; _delay = true;
_mainEmitter = mainEmitter;
canvasRenderer.SetTexture(null); canvasRenderer.SetTexture(null);
@@ -283,6 +283,10 @@ namespace Coffee.UIExtensions
|| !transform.lossyScale.GetScaled(_parent.scale3DForCalc).IsVisible() // Scale is not visible. || !transform.lossyScale.GetScaled(_parent.scale3DForCalc).IsVisible() // Scale is not visible.
|| (!_particleSystem.IsAlive() && !_particleSystem.isPlaying) // No particle. || (!_particleSystem.IsAlive() && !_particleSystem.isPlaying) // No particle.
|| (_isTrail && !_particleSystem.trails.enabled) // Trail, but it is not enabled. || (_isTrail && !_particleSystem.trails.enabled) // Trail, but it is not enabled.
#if UNITY_2018_3_OR_NEWER
|| canvasRenderer.GetInheritedAlpha() <
0.01f // #102: Do not bake particle system to mesh when the alpha is zero.
#endif
) )
{ {
Profiler.BeginSample("[UIParticleRenderer] Clear Mesh"); Profiler.BeginSample("[UIParticleRenderer] Clear Mesh");
@@ -294,31 +298,13 @@ namespace Coffee.UIExtensions
return; return;
} }
// Reset custom data.
// var customData = _particleSystem.customData;
// if (!customData.enabled || customData.GetMode(ParticleSystemCustomData.Custom1) == ParticleSystemCustomDataMode.Disabled)
// {
// customData.SetVector(ParticleSystemCustomData.Custom1, 0, 0);
// customData.SetVector(ParticleSystemCustomData.Custom1, 1, 0);
// customData.SetVector(ParticleSystemCustomData.Custom1, 2, 0);
// customData.SetVector(ParticleSystemCustomData.Custom1, 3, 0);
// }
//
// if (!customData.enabled || customData.GetMode(ParticleSystemCustomData.Custom2) == ParticleSystemCustomDataMode.Disabled)
// {
// customData.SetVector(ParticleSystemCustomData.Custom2, 0, 0);
// customData.SetVector(ParticleSystemCustomData.Custom2, 1, 0);
// customData.SetVector(ParticleSystemCustomData.Custom2, 2, 0);
// customData.SetVector(ParticleSystemCustomData.Custom2, 3, 0);
// }
var main = _particleSystem.main; var main = _particleSystem.main;
var scale = GetWorldScale(); var scale = GetWorldScale();
var psPos = _particleSystem.transform.position; var psPos = _particleSystem.transform.position;
// Simulate particles. // Simulate particles.
Profiler.BeginSample("[UIParticle] Bake Mesh > Simulate Particles"); Profiler.BeginSample("[UIParticle] Bake Mesh > Simulate Particles");
if (!_isTrail && _parent.canSimulate && !_mainEmitter) if (!_isTrail && _parent.canSimulate)
{ {
#if UNITY_EDITOR #if UNITY_EDITOR
if (!Application.isPlaying) if (!Application.isPlaying)
@@ -329,13 +315,6 @@ namespace Coffee.UIExtensions
#endif #endif
{ {
ResolveResolutionChange(psPos, scale); ResolveResolutionChange(psPos, scale);
// fix: second and subsequent bursts not displayed when world simulation and non-looping. (#326)
if (!_particleSystem.IsLocalSpace() && !main.loop && _particleSystem.time == 0)
{
_delay = true;
}
Simulate(scale, _parent.isPaused || _delay); Simulate(scale, _parent.isPaused || _delay);
if (_delay && !_parent.isPaused) if (_delay && !_parent.isPaused)
@@ -443,16 +422,17 @@ namespace Coffee.UIExtensions
workerMesh.LinearToGamma(); workerMesh.LinearToGamma();
} }
var components = InternalListPool<Component>.Rent(); var components = ListPool<Component>.Rent();
GetComponents(typeof(IMeshModifier), components); GetComponents(typeof(IMeshModifier), components);
#pragma warning disable CS0618 // Type or member is obsolete
for (var i = 0; i < components.Count; i++) for (var i = 0; i < components.Count; i++)
{ {
#pragma warning disable CS0618 // Type or member is obsolete
((IMeshModifier)components[i]).ModifyMesh(workerMesh); ((IMeshModifier)components[i]).ModifyMesh(workerMesh);
#pragma warning restore CS0618 // Type or member is obsolete
} }
#pragma warning restore CS0618 // Type or member is obsolete
InternalListPool<Component>.Return(ref components); ListPool<Component>.Return(ref components);
} }
Profiler.EndSample(); Profiler.EndSample();
@@ -464,7 +444,7 @@ namespace Coffee.UIExtensions
// Get grouped renderers. // Get grouped renderers.
Profiler.BeginSample("[UIParticleRenderer] Set Mesh"); Profiler.BeginSample("[UIParticleRenderer] Set Mesh");
var renderers = InternalListPool<UIParticleRenderer>.Rent(); var renderers = ListPool<UIParticleRenderer>.Rent();
if (_parent.useMeshSharing) if (_parent.useMeshSharing)
{ {
UIParticleUpdater.GetGroupedRenderers(_parent.groupId, _index, renderers); UIParticleUpdater.GetGroupedRenderers(_parent.groupId, _index, renderers);
@@ -481,7 +461,7 @@ namespace Coffee.UIExtensions
r.canvasRenderer.SetMaterial(materialForRendering, 0); r.canvasRenderer.SetMaterial(materialForRendering, 0);
} }
InternalListPool<UIParticleRenderer>.Return(ref renderers); ListPool<UIParticleRenderer>.Return(ref renderers);
if (_parent.canRender) if (_parent.canRender)
{ {
@@ -564,30 +544,6 @@ namespace Coffee.UIExtensions
return Matrix4x4.Translate(psPos) return Matrix4x4.Translate(psPos)
* Matrix4x4.Scale(scale); * Matrix4x4.Scale(scale);
case ParticleSystemSimulationSpace.World: case ParticleSystemSimulationSpace.World:
if (_isTrail)
{
return Matrix4x4.Translate(psPos)
* Matrix4x4.Scale(scale)
* Matrix4x4.Translate(-psPos);
}
if (_mainEmitter)
{
if (_mainEmitter.IsLocalSpace())
{
return Matrix4x4.Translate(psPos)
* Matrix4x4.Scale(scale)
* Matrix4x4.Translate(-psPos);
}
else
{
psPos = _particleSystem.transform.position - _mainEmitter.transform.position;
return Matrix4x4.Translate(psPos)
* Matrix4x4.Scale(scale)
* Matrix4x4.Translate(-psPos);
}
}
return Matrix4x4.Scale(scale); return Matrix4x4.Scale(scale);
case ParticleSystemSimulationSpace.Custom: case ParticleSystemSimulationSpace.Custom:
return Matrix4x4.Translate(_particleSystem.main.customSimulationSpace.position.GetScaled(scale)) return Matrix4x4.Translate(_particleSystem.main.customSimulationSpace.position.GetScaled(scale))
@@ -650,7 +606,6 @@ namespace Coffee.UIExtensions
: main.useUnscaledTime : main.useUnscaledTime
? Time.unscaledDeltaTime ? Time.unscaledDeltaTime
: Time.deltaTime; : Time.deltaTime;
deltaTime *= _parent.timeScaleMultiplier;
// Pre-warm: // Pre-warm:
if (0 < deltaTime && _preWarm) if (0 < deltaTime && _preWarm)
@@ -731,7 +686,7 @@ namespace Coffee.UIExtensions
if (s_Mpb.isEmpty) return; if (s_Mpb.isEmpty) return;
// #41: Copy the value from MaterialPropertyBlock to CanvasRenderer // #41: Copy the value from MaterialPropertyBlock to CanvasRenderer
if (materialForRendering == null) return; if (!materialForRendering) return;
for (var i = 0; i < _parent.m_AnimatableProperties.Length; i++) for (var i = 0; i < _parent.m_AnimatableProperties.Length; i++)
{ {

View File

@@ -16,50 +16,37 @@ namespace Coffee.UIExtensions
public static void Register(UIParticle particle) public static void Register(UIParticle particle)
{ {
if (particle == null) return; if (!particle) return;
s_ActiveParticles.Add(particle); s_ActiveParticles.Add(particle);
} }
public static void Unregister(UIParticle particle) public static void Unregister(UIParticle particle)
{ {
if (particle == null) return; if (!particle) return;
s_ActiveParticles.Remove(particle); s_ActiveParticles.Remove(particle);
} }
public static void Register(UIParticleAttractor attractor) public static void Register(UIParticleAttractor attractor)
{ {
if (attractor == null) return; if (!attractor) return;
s_ActiveAttractors.Add(attractor); s_ActiveAttractors.Add(attractor);
} }
public static void Unregister(UIParticleAttractor attractor) public static void Unregister(UIParticleAttractor attractor)
{ {
if (attractor == null) return; if (!attractor) return;
s_ActiveAttractors.Remove(attractor); s_ActiveAttractors.Remove(attractor);
} }
#if UNITY_EDITOR #if UNITY_EDITOR
[InitializeOnLoadMethod] [InitializeOnLoadMethod]
private static void InitializeOnLoad()
{
UIExtraCallbacks.onAfterCanvasRebuild += Refresh;
EditorApplication.playModeStateChanged += state =>
{
UIExtraCallbacks.onAfterCanvasRebuild -= Refresh;
if (state == PlayModeStateChange.EnteredEditMode || state == PlayModeStateChange.EnteredPlayMode)
{
UIExtraCallbacks.onAfterCanvasRebuild += Refresh;
}
};
}
#else #else
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)] [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
#endif
private static void InitializeOnLoad() private static void InitializeOnLoad()
{ {
UIExtraCallbacks.onAfterCanvasRebuild += Refresh; UIExtraCallbacks.onAfterCanvasRebuild += Refresh;
} }
#endif
private static void Refresh() private static void Refresh()
{ {
@@ -71,7 +58,7 @@ namespace Coffee.UIExtensions
for (var i = 0; i < s_ActiveParticles.Count; i++) for (var i = 0; i < s_ActiveParticles.Count; i++)
{ {
var uip = s_ActiveParticles[i]; var uip = s_ActiveParticles[i];
if (uip == null || uip.canvas == null || !uip.isPrimary || !s_UpdatedGroupIds.Add(uip.groupId)) continue; if (!uip || !uip.canvas || !uip.isPrimary || !s_UpdatedGroupIds.Add(uip.groupId)) continue;
uip.UpdateTransformScale(); uip.UpdateTransformScale();
uip.UpdateRenderers(); uip.UpdateRenderers();
@@ -81,7 +68,7 @@ namespace Coffee.UIExtensions
for (var i = 0; i < s_ActiveParticles.Count; i++) for (var i = 0; i < s_ActiveParticles.Count; i++)
{ {
var uip = s_ActiveParticles[i]; var uip = s_ActiveParticles[i];
if (uip == null || uip.canvas == null) continue; if (!uip || !uip.canvas) continue;
uip.UpdateTransformScale(); uip.UpdateTransformScale();
@@ -125,7 +112,7 @@ namespace Coffee.UIExtensions
var uip = s_ActiveParticles[i]; var uip = s_ActiveParticles[i];
if (!uip.useMeshSharing || uip.groupId != groupId) continue; if (!uip.useMeshSharing || uip.groupId != groupId) continue;
if (uip.isPrimary) return uip; if (uip.isPrimary) return uip;
if (primary == null && uip.canSimulate) primary = uip; if (!primary && uip.canSimulate) primary = uip;
} }
return primary; return primary;

View File

@@ -12,8 +12,12 @@ namespace Coffee.UIParticleInternal
public static ParticleSystem.Particle[] GetParticleArray(int size) public static ParticleSystem.Particle[] GetParticleArray(int size)
{ {
if (s_TmpParticles.Length < size) if (s_TmpParticles.Length < size)
{
while (s_TmpParticles.Length < size)
{ {
size = Mathf.NextPowerOfTwo(size); size = Mathf.NextPowerOfTwo(size);
}
s_TmpParticles = new ParticleSystem.Particle[size]; s_TmpParticles = new ParticleSystem.Particle[size];
} }
@@ -84,11 +88,11 @@ namespace Coffee.UIParticleInternal
var bRenderer = b.GetComponent<ParticleSystemRenderer>(); var bRenderer = b.GetComponent<ParticleSystemRenderer>();
// Render queue: ascending // Render queue: ascending
var aMat = aRenderer.sharedMaterial != null ? aRenderer.sharedMaterial : aRenderer.trailMaterial; var aMat = aRenderer.sharedMaterial ? aRenderer.sharedMaterial : aRenderer.trailMaterial;
var bMat = bRenderer.sharedMaterial != null ? bRenderer.sharedMaterial : bRenderer.trailMaterial; var bMat = bRenderer.sharedMaterial ? bRenderer.sharedMaterial : bRenderer.trailMaterial;
if (aMat == null && bMat == null) return 0; if (!aMat && !bMat) return 0;
if (aMat == null) return -1; if (!aMat) return -1;
if (bMat == null) return 1; if (!bMat) return 1;
if (sortByMaterial) if (sortByMaterial)
{ {
@@ -142,7 +146,7 @@ namespace Coffee.UIParticleInternal
public static Texture2D GetTextureForSprite(this ParticleSystem self) public static Texture2D GetTextureForSprite(this ParticleSystem self)
{ {
if (self == null) return null; if (!self) return null;
// Get sprite's texture. // Get sprite's texture.
var tsaModule = self.textureSheetAnimation; var tsaModule = self.textureSheetAnimation;
@@ -151,7 +155,7 @@ namespace Coffee.UIParticleInternal
for (var i = 0; i < tsaModule.spriteCount; i++) for (var i = 0; i < tsaModule.spriteCount; i++)
{ {
var sprite = tsaModule.GetSprite(i); var sprite = tsaModule.GetSprite(i);
if (sprite == null) continue; if (!sprite) continue;
return sprite.GetActualTexture(); return sprite.GetActualTexture();
} }
@@ -163,38 +167,9 @@ namespace Coffee.UIParticleInternal
{ {
foreach (var p in self) foreach (var p in self)
{ {
if (p == null) continue; if (!p) continue;
action.Invoke(p); action.Invoke(p);
} }
} }
public static ParticleSystem GetMainEmitter(this ParticleSystem self, List<ParticleSystem> list)
{
if (self == null || list == null || list.Count == 0) return null;
for (var i = 0; i < list.Count; i++)
{
var parent = list[i];
if (parent != self && IsSubEmitterOf(self, parent)) return parent;
}
return null;
}
public static bool IsSubEmitterOf(this ParticleSystem self, ParticleSystem parent)
{
if (self == null || parent == null) return false;
var subEmitters = parent.subEmitters;
if (!subEmitters.enabled) return false; // No sub emitters.
var count = subEmitters.subEmittersCount;
for (var i = 0; i < count; i++)
{
if (subEmitters.GetSubEmitterSystem(i) == self) return true;
}
return false;
}
} }
} }

View File

@@ -15,7 +15,7 @@ namespace Coffee.UIExtensions.Demo
private void Start() private void Start()
{ {
if (m_Origin == null) return; if (!m_Origin) return;
m_Origin.SetActive(false); m_Origin.SetActive(false);
var parent = m_Origin.transform.parent; var parent = m_Origin.transform.parent;

View File

@@ -42,7 +42,7 @@ public class UIElementDragger : MonoBehaviour, IBeginDragHandler, IDragHandler,
break; break;
case Target.Custom: case Target.Custom:
_rectTransform.localPosition += delta; _rectTransform.localPosition += delta;
if (m_CustomTarget != null) if (m_CustomTarget)
{ {
if (m_UseCanvasScale) if (m_UseCanvasScale)
{ {

View File

@@ -1,4 +1,3 @@
using Coffee.UIParticleInternal;
using UnityEngine; using UnityEngine;
using UnityEngine.Serialization; using UnityEngine.Serialization;
using UnityEngine.UI; using UnityEngine.UI;
@@ -52,7 +51,11 @@ namespace Coffee.UIExtensions.Demo
public void EnableAnimations(bool flag) public void EnableAnimations(bool flag)
{ {
foreach (var animator in Misc.FindObjectsOfType<Animator>()) #if UNITY_2023_1_OR_NEWER
foreach (var animator in FindObjectsByType<Animator>(FindObjectsInactive.Include, FindObjectsSortMode.None))
#else
foreach (var animator in FindObjectsOfType<Animator>())
#endif
{ {
animator.enabled = flag; animator.enabled = flag;
} }
@@ -80,7 +83,11 @@ namespace Coffee.UIExtensions.Demo
public void UIParticle_Scale(float scale) public void UIParticle_Scale(float scale)
{ {
foreach (var uip in Misc.FindObjectsOfType<UIParticle>()) #if UNITY_2023_1_OR_NEWER
foreach (var uip in FindObjectsByType<UIParticle>(FindObjectsInactive.Include, FindObjectsSortMode.None))
#else
foreach (var uip in FindObjectsOfType<UIParticle>())
#endif
{ {
uip.scale = scale; uip.scale = scale;
} }
@@ -88,7 +95,11 @@ namespace Coffee.UIExtensions.Demo
public void ParticleSystem_WorldSpaseSimulation(bool flag) public void ParticleSystem_WorldSpaseSimulation(bool flag)
{ {
foreach (var p in Misc.FindObjectsOfType<ParticleSystem>()) #if UNITY_2023_1_OR_NEWER
foreach (var p in FindObjectsByType<ParticleSystem>(FindObjectsInactive.Include, FindObjectsSortMode.None))
#else
foreach (var p in FindObjectsOfType<ParticleSystem>())
#endif
{ {
var main = p.main; var main = p.main;
main.simulationSpace = flag main.simulationSpace = flag
@@ -124,7 +135,11 @@ namespace Coffee.UIExtensions.Demo
public void ParticleSystem_SetScale(float scale) public void ParticleSystem_SetScale(float scale)
{ {
foreach (var ps in Misc.FindObjectsOfType<ParticleSystem>()) #if UNITY_2023_1_OR_NEWER
foreach (var ps in FindObjectsByType<ParticleSystem>(FindObjectsInactive.Include, FindObjectsSortMode.None))
#else
foreach (var ps in FindObjectsOfType<ParticleSystem>())
#endif
{ {
ps.transform.localScale = new Vector3(scale, scale, scale); ps.transform.localScale = new Vector3(scale, scale, scale);
} }

View File

@@ -40,10 +40,7 @@
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]

View File

@@ -2,7 +2,7 @@
"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": "4.12.1", "version": "4.9.0",
"unity": "2018.2", "unity": "2018.2",
"license": "MIT", "license": "MIT",
"repository": { "repository": {

View File

@@ -1,11 +0,0 @@
{
"MonoBehaviour": {
"m_Enabled": true,
"m_EditorHideFlags": 0,
"m_Name": "",
"m_EditorClassIdentifier": "",
"m_OutputDllPaths": [
"Packages/com.coffee.ui-particle/Runtime/Coffee.UIParticle.R.dll"
]
}
}

View File

@@ -124,7 +124,7 @@ PlayerSettings:
bundleVersion: 1.0 bundleVersion: 1.0
preloadedAssets: preloadedAssets:
- {fileID: 11400000, guid: 86087a0847f384b538391745dad4565c, type: 2} - {fileID: 11400000, guid: 86087a0847f384b538391745dad4565c, type: 2}
- {fileID: 11400000, guid: 4b9df7b8a4193489299b8f477348ae0c, type: 2} - {fileID: 11400000, guid: e8e7744b163af4869b07b8f192c810ed, type: 2}
metroInputSource: 0 metroInputSource: 0
wsaTransparentSwapchain: 0 wsaTransparentSwapchain: 0
m_HolographicPauseOnTrackingLoss: 1 m_HolographicPauseOnTrackingLoss: 1