Compare commits

...

29 Commits

Author SHA1 Message Date
semantic-release-bot
fed927559f chore(release): 4.11.4 [skip ci]
## [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](d1386a1221))
* avoid endless loop ([eb2e862](eb2e862e80)), closes [#392](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/392)
2025-12-24 11:17:10 +00:00
mob-sakai
eb2e862e80 fix: avoid endless loop
close #392
2025-12-24 20:10:01 +09:00
mob-sakai
d1386a1221 fix: add early return for case where subEmitter module is disabled 2025-12-05 09:58:23 +09:00
semantic-release-bot
9d56c94636 chore(release): 4.11.3 [skip ci]
## [4.11.3](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.11.2...v4.11.3) (2025-10-14)

### Bug Fixes

* fix icon ([a9461ec](a9461ecb4d))
* fix URL link in README ([1c8c65d](1c8c65d25e)), closes [#376](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/376)
* fix: second and subsequent bursts not displayed when world simulation and non-looping ([df2f3ca](df2f3caafb)), 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](38aec2ea1a))
2025-10-14 11:53:52 +00:00
mob-sakai
fe179c0f0f chore: update workflow 2025-10-14 19:47:54 +09:00
mob-sakai
df2f3caafb fix: fix: second and subsequent bursts not displayed when world simulation and non-looping
close #326
2025-10-14 19:43:29 +09:00
mob-sakai
1c8c65d25e fix: fix URL link in README
close #376
2025-08-08 17:57:40 +09:00
mob-sakai
a9461ecb4d fix: fix icon 2025-06-14 09:41:44 +09:00
Serkan Şenkal
38aec2ea1a fix: 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 2025-04-09 02:59:26 +09:00
semantic-release-bot
bb2d588e0c chore(release): 4.11.2 [skip ci]
## [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](0da652520c))
* NRE on enable ([0cff50e](0cff50ef69)), closes [#359](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/359)
2025-03-15 07:59:37 +00:00
mob-sakai
078005a1a7 chore: fix NanoMonitor link url 2025-03-15 16:58:52 +09:00
mob-sakai
0cff50ef69 fix: NRE on enable
close #359
2025-03-14 19:44:02 +09:00
mob-sakai
0da652520c fix: IL2CPP build fails on older versions of Unity 2025-03-14 19:29:41 +09:00
mob-sakai
4199492e3a chore: update internal 2025-03-14 19:29:22 +09:00
mob-sakai
1f88bb255e chore: fix settings icon 2025-03-14 19:24:22 +09:00
semantic-release-bot
e3791866b7 chore(release): 4.11.1 [skip ci]
## [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](6dfbdae38d))
2025-02-21 09:35:05 +00:00
mob-sakai
6dfbdae38d fix: component icons will no longer be displayed in the scene view 2025-02-21 18:22:24 +09:00
mob-sakai
b63220b871 doc: update readme 2025-02-21 17:57:12 +09:00
semantic-release-bot
3fd2bea599 chore(release): 4.11.0 [skip ci]
# [4.11.0](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.10.7...v4.11.0) (2025-02-21)

### Features

* add 'TimeScaleMultiplier' option ([925af0b](925af0b604))
2025-02-21 07:17:09 +00:00
mob-sakai
925af0b604 feat: add 'TimeScaleMultiplier' option 2025-02-21 16:10:06 +09:00
semantic-release-bot
d1a1e23e50 chore(release): 4.10.7 [skip ci]
## [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](47ee45cbbe)), closes [#351](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/351)
2025-01-14 11:49:21 +00:00
mob-sakai
47ee45cbbe fix: editor crashed on exit play mode (editor, windows)
close #351
2025-01-07 10:25:23 +09:00
semantic-release-bot
1b0110320b chore(release): 4.10.6 [skip ci]
## [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](8276684c3b)), closes [#348](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/348)
* sub-emitter's `inherit velocity` module doubles at runtime ([67de3d1](67de3d1bd3)), closes [#349](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/349)
2025-01-03 14:24:40 +00:00
mob-sakai
a1ca74f854 chore: update coffee.internal 2025-01-03 23:13:17 +09:00
mob-sakai
8276684c3b fix: sub-emitter particles may not render correctly in certain scenarios
close #348
2025-01-03 23:13:17 +09:00
mob-sakai
67de3d1bd3 fix: sub-emitter's inherit velocity module doubles at runtime
close #349
2025-01-03 23:13:17 +09:00
semantic-release-bot
90d966e659 chore(release): 4.10.5 [skip ci]
## [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](934f4b8f1c)), closes [#346](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/346)
2024-12-23 03:54:11 +00:00
mob-sakai
0036b03d12 refactor: update coffee.internal 2024-12-23 12:53:15 +09:00
mob-sakai
934f4b8f1c fix: '3D' scale toggle in the inspector does not keep on reload
close #346
2024-12-22 13:10:21 +09:00
32 changed files with 439 additions and 2542 deletions

View File

@@ -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@v4 uses: actions/checkout@v5
- name: 🔖 Run semantic release - name: 🔖 Run semantic release
uses: cycjimmy/semantic-release-action@v4 uses: cycjimmy/semantic-release-action@v5
id: release id: release
with: with:
working_directory: Packages/src working_directory: Packages/src
@@ -67,7 +67,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@v4 uses: actions/checkout@v5
with: with:
ref: ${{ needs.release.outputs.merge_to }} ref: ${{ needs.release.outputs.merge_to }}
fetch-depth: 0 fetch-depth: 0
@@ -88,7 +88,7 @@ jobs:
contents: write contents: write
steps: steps:
- name: 🚚 Checkout (${{ needs.release.outputs.tag }}) - name: 🚚 Checkout (${{ needs.release.outputs.tag }})
uses: actions/checkout@v4 uses: actions/checkout@v5
with: with:
ref: ${{ needs.release.outputs.tag }} ref: ${{ needs.release.outputs.tag }}
fetch-depth: 0 fetch-depth: 0

View File

@@ -10,6 +10,7 @@ env:
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|2021.1|2023.3)"
PROJECT_PATH: .
on: on:
workflow_dispatch: workflow_dispatch:
@@ -21,7 +22,7 @@ on:
push: push:
branches: branches:
- develop - develop
- develop-preview - "develop-*"
tags: tags:
- "!*" - "!*"
paths-ignore: paths-ignore:
@@ -71,11 +72,11 @@ jobs:
steps: steps:
- name: 🚚 Checkout ($${{ github.ref }}) - name: 🚚 Checkout ($${{ github.ref }})
if: github.event_name == 'push' if: github.event_name == 'push'
uses: actions/checkout@v4 uses: actions/checkout@v5
- name: 🚚 Checkout pull request (pull_request_target) - name: 🚚 Checkout pull request (pull_request_target)
if: github.event_name == 'pull_request_target' if: github.event_name == 'pull_request_target'
uses: actions/checkout@v4 uses: actions/checkout@v5
with: with:
ref: ${{ github.event.pull_request.head.sha }} ref: ${{ github.event.pull_request.head.sha }}
fetch-depth: 0 fetch-depth: 0
@@ -85,25 +86,27 @@ jobs:
run: | run: |
git config user.name "GitHub Actions" git config user.name "GitHub Actions"
git config user.email "actions@github.com" git config user.email "actions@github.com"
git merge origin/${{ github.event.pull_request.base.ref }} --no-edit 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: Library path: ${{ env.PROJECT_PATH }}/Library
key: Library-${{ matrix.unityVersion }}-${{ github.event.pull_request.head.sha || github.sha }} key: ${{ env.PROJECT_PATH }}-Library-${{ matrix.unityVersion }}-${{ github.event.pull_request.head.sha || github.sha }}
restore-keys: | restore-keys: |
Library-${{ matrix.unityVersion }}- ${{ env.PROJECT_PATH }}-Library-${{ matrix.unityVersion }}-
Library- ${{ env.PROJECT_PATH }}-Library-
- name: 🛠️ Build Unity Project (Test) - name: 🛠️ Build Unity Project (Test)
uses: game-ci/unity-builder@v4 uses: game-ci/unity-builder@main
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: env:
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }} UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }} UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
@@ -118,6 +121,7 @@ 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 }}
env: env:
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }} UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }} UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}

View File

@@ -18,11 +18,12 @@ MonoBehaviour:
m_EnabledInEditor: 1 m_EnabledInEditor: 1
m_AlwaysIncludeAssembly: 1 m_AlwaysIncludeAssembly: 1
m_InstantiateOnLoad: 1 m_InstantiateOnLoad: 1
m_Prefab: {fileID: 7211429669315726685, guid: b73940fc30a2f4eb9a73783e9c1f8da6, m_Prefab: {fileID: 4567906826058368312, guid: 7cebff2d255b9433cbe23b243c193329,
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

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

View File

@@ -10,7 +10,7 @@ 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: UIParticle m_Name: UIParticleProjectSettings
m_EditorClassIdentifier: m_EditorClassIdentifier:
m_EnableLinearToGamma: 1 m_EnableLinearToGamma: 1
m_HideGeneratedObjects: 1 m_HideGeneratedObjects: 1

View File

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

View File

@@ -1,16 +1,21 @@
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
{ {
// A Test behaves as an ordinary method [TestCase(-1)]
[Test] [TestCase(0)]
public void NewTestScriptSimplePasses() [TestCase(2048)]
[TestCase(3000)]
public void GetParticleArray(int requiredSize)
{ {
// Use the Assert class to test conditions var array = ParticleSystemExtensions.GetParticleArray(requiredSize);
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,6 +1,7 @@
{ {
"dependencies": { "dependencies": {
"com.coffee.development": "https://github.com/mob-sakai/Coffee.Internal.git?path=Packages/Development", "com.coffee.development": "https://github.com/mob-sakai/Coffee.Internal.git?path=Packages/Development",
"com.coffee.minimal-resource": "https://github.com/mob-sakai/Coffee.Internal.git?path=Packages/MinimalResource",
"com.coffee.nano-monitor": "https://github.com/mob-sakai/Coffee.Internal.git?path=Packages/NanoMonitor", "com.coffee.nano-monitor": "https://github.com/mob-sakai/Coffee.Internal.git?path=Packages/NanoMonitor",
"com.unity.ide.rider": "3.0.31", "com.unity.ide.rider": "3.0.31",
"com.unity.test-framework": "1.1.33", "com.unity.test-framework": "1.1.33",

View File

@@ -5,7 +5,14 @@
"depth": 0, "depth": 0,
"source": "git", "source": "git",
"dependencies": {}, "dependencies": {},
"hash": "4e5f735ccf956ee469b5014ae781068c49a2825d" "hash": "3c280f1a8f4db5038b881ff07f270efd9638fa31"
},
"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",
@@ -14,7 +21,7 @@
"dependencies": { "dependencies": {
"com.unity.ugui": "1.0.0" "com.unity.ugui": "1.0.0"
}, },
"hash": "4e5f735ccf956ee469b5014ae781068c49a2825d" "hash": "3c280f1a8f4db5038b881ff07f270efd9638fa31"
}, },
"com.coffee.ui-particle": { "com.coffee.ui-particle": {
"version": "file:src", "version": "file:src",

View File

@@ -1,3 +1,65 @@
## [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) ## [4.10.4](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.10.3...v4.10.4) (2024-12-19)

View File

@@ -28,6 +28,11 @@ namespace Coffee.UIExtensions
[CanEditMultipleObjects] [CanEditMultipleObjects]
internal class UIParticleEditor : GraphicEditor internal class UIParticleEditor : GraphicEditor
{ {
internal class State : ScriptableSingleton<State>
{
public bool is3DScaleMode;
}
//################################ //################################
// Constant or Static Members. // Constant or Static Members.
//################################ //################################
@@ -46,7 +51,6 @@ 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;
@@ -58,8 +62,10 @@ 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
@@ -95,6 +101,7 @@ 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)
@@ -163,6 +170,19 @@ 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>
@@ -181,7 +201,11 @@ namespace Coffee.UIExtensions
// Scale // Scale
EditorGUI.BeginDisabledGroup(!_meshSharing.hasMultipleDifferentValues && _meshSharing.intValue == 4); EditorGUI.BeginDisabledGroup(!_meshSharing.hasMultipleDifferentValues && _meshSharing.intValue == 4);
s_XYZMode = DrawFloatOrVector3Field(_scale3D, s_XYZMode); if (DrawFloatOrVector3Field(_scale3D, _is3DScaleMode) != _is3DScaleMode)
{
State.instance.is3DScaleMode = _is3DScaleMode = !_is3DScaleMode;
}
EditorGUI.EndDisabledGroup(); EditorGUI.EndDisabledGroup();
// AnimatableProperties // AnimatableProperties
@@ -222,6 +246,9 @@ 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();

View File

Before

Width:  |  Height:  |  Size: 418 B

After

Width:  |  Height:  |  Size: 418 B

View File

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

View File

@@ -144,7 +144,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.git/releases) and extract it. 1. Download a source code zip file from [Releases](https://github.com/mob-sakai/ParticleEffectForUGUI/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.
@@ -158,7 +158,7 @@ _This package requires **Unity 2018.3 or later**._
`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/mob-sakai/ParticleEffectForUGUI/assets/12690315/1cf5753b-33fc-4cef-91c3-413c515a954f) ![](https://github.com/user-attachments/assets/bc9eb783-afce-4102-ac61-aee9ea8d6f2f)
- **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,6 +180,7 @@ _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
@@ -210,7 +211,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-maskrectmask2d-component) the [How to Make a Custom Shader to Support Mask/RectMask2D Component](#how-to-make-a-custom-shader-to-support-mask-and-rectmask2d-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)

Binary file not shown.

View File

@@ -0,0 +1,33 @@
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 = ListPool<T>.Rent(); var results = InternalListPool<T>.Rent();
self.GetComponentsInChildren_Internal(results, depth); self.GetComponentsInChildren_Internal(results, depth);
var array = results.ToArray(); var array = results.ToArray();
ListPool<T>.Return(ref results); InternalListPool<T>.Return(ref results);
return array; return array;
} }
@@ -204,7 +204,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 Resources.FindObjectsOfTypeAll<MonoScript>()) foreach (var script in MonoImporter.GetAllRuntimeMonoScripts())
{ {
if (script.GetClass() != typeof(T)) if (script.GetClass() != typeof(T))
{ {

View File

@@ -133,6 +133,8 @@ namespace Coffee.UIParticleInternal
#if UNITY_EDITOR #if UNITY_EDITOR
private string _jsonText; private string _jsonText;
public static bool hasInstance => s_Instance;
public static T instance public static T instance
{ {
get get

View File

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

View File

@@ -15,7 +15,7 @@ namespace Coffee.UIParticleInternal
#if UNITY_EDITOR #if UNITY_EDITOR
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
private static void Clear() public static void Clear()
{ {
s_Repository.Clear(); s_Repository.Clear();
} }

View File

@@ -1,6 +1,18 @@
using System;
using System.Diagnostics; using System.Diagnostics;
using UnityEditor; using UnityEditor;
using UnityEngine; 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 namespace Coffee.UIParticleInternal
{ {
@@ -51,7 +63,70 @@ namespace Coffee.UIParticleInternal
#if UNITY_EDITOR #if UNITY_EDITOR
if (!obj) return; if (!obj) return;
EditorUtility.SetDirty(obj); 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 #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) continue;
var path = type.GetCustomAttribute<IconAttribute>()?._path;
var icon = AssetDatabase.LoadAssetAtPath<Texture2D>(path);
if (!icon) continue;
s_SetIconForObject(script, icon);
}
}
#endif
}
#endif
} }

View File

@@ -6,15 +6,58 @@ namespace Coffee.UIParticleInternal
/// <summary> /// <summary>
/// Object pool. /// Object pool.
/// </summary> /// </summary>
internal class ObjectPool<T> internal class InternalObjectPool<T> where T : class
{ {
#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 ObjectPool(Func<T> onCreate, Predicate<T> onValid, Action<T> onReturn) public InternalObjectPool(Func<T> onCreate, Predicate<T> onValid, Action<T> onReturn)
{ {
_onCreate = onCreate; _onCreate = onCreate;
_onValid = onValid; _onValid = onValid;
@@ -54,15 +97,40 @@ 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 ListPool<T> internal static class InternalListPool<T>
{ {
private static readonly ObjectPool<List<T>> s_ListPool = #if UNITY_2021_1_OR_NEWER
new ObjectPool<List<T>>(() => new List<T>(), _ => true, x => x.Clear()); /// <summary>
/// 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.
@@ -81,5 +149,6 @@ namespace Coffee.UIParticleInternal
{ {
s_ListPool.Return(ref toRelease); s_ListPool.Return(ref toRelease);
} }
#endif
} }
} }

View File

@@ -9,6 +9,7 @@ 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.PerformanceDemo")]
[assembly: InternalsVisibleTo("Coffee.UIParticle.Demo")] [assembly: InternalsVisibleTo("Coffee.UIParticle.Demo")]
@@ -17,6 +18,7 @@ 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))]
@@ -119,6 +121,10 @@ namespace Coffee.UIExtensions
"Change the bake view size.")] "Change the bake view size.")]
private float m_CustomViewSize = 10; private float m_CustomViewSize = 10;
[SerializeField]
[Tooltip("Time scale multiplier.")]
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 int _groupId; private int _groupId;
@@ -257,6 +263,15 @@ 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 =>
@@ -577,12 +592,14 @@ namespace Coffee.UIExtensions
{ {
var ps = particleSystems[i]; var ps = particleSystems[i];
if (!ps) 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); GetRenderer(j++).Set(this, ps, true, mainEmitter);
} }
} }
} }

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

@@ -15,6 +15,7 @@ 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))]
@@ -40,6 +41,7 @@ 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();
@@ -112,6 +114,7 @@ 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;
@@ -223,7 +226,7 @@ namespace Coffee.UIExtensions
return _modifiedMaterial; return _modifiedMaterial;
} }
public void Set(UIParticle parent, ParticleSystem ps, bool isTrail) public void Set(UIParticle parent, ParticleSystem ps, bool isTrail, ParticleSystem mainEmitter)
{ {
_parent = parent; _parent = parent;
maskable = parent.maskable; maskable = parent.maskable;
@@ -246,10 +249,7 @@ 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,6 +266,7 @@ 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);
@@ -282,10 +283,6 @@ 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");
@@ -303,7 +300,7 @@ namespace Coffee.UIExtensions
// Simulate particles. // Simulate particles.
Profiler.BeginSample("[UIParticle] Bake Mesh > Simulate Particles"); Profiler.BeginSample("[UIParticle] Bake Mesh > Simulate Particles");
if (!_isTrail && _parent.canSimulate) if (!_isTrail && _parent.canSimulate && !_mainEmitter)
{ {
#if UNITY_EDITOR #if UNITY_EDITOR
if (!Application.isPlaying) if (!Application.isPlaying)
@@ -314,6 +311,13 @@ 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)
@@ -421,7 +425,7 @@ namespace Coffee.UIExtensions
workerMesh.LinearToGamma(); workerMesh.LinearToGamma();
} }
var components = ListPool<Component>.Rent(); var components = InternalListPool<Component>.Rent();
GetComponents(typeof(IMeshModifier), components); GetComponents(typeof(IMeshModifier), components);
for (var i = 0; i < components.Count; i++) for (var i = 0; i < components.Count; i++)
{ {
@@ -430,7 +434,7 @@ namespace Coffee.UIExtensions
#pragma warning restore CS0618 // Type or member is obsolete #pragma warning restore CS0618 // Type or member is obsolete
} }
ListPool<Component>.Return(ref components); InternalListPool<Component>.Return(ref components);
} }
Profiler.EndSample(); Profiler.EndSample();
@@ -442,7 +446,7 @@ namespace Coffee.UIExtensions
// Get grouped renderers. // Get grouped renderers.
Profiler.BeginSample("[UIParticleRenderer] Set Mesh"); Profiler.BeginSample("[UIParticleRenderer] Set Mesh");
var renderers = ListPool<UIParticleRenderer>.Rent(); var renderers = InternalListPool<UIParticleRenderer>.Rent();
if (_parent.useMeshSharing) if (_parent.useMeshSharing)
{ {
UIParticleUpdater.GetGroupedRenderers(_parent.groupId, _index, renderers); UIParticleUpdater.GetGroupedRenderers(_parent.groupId, _index, renderers);
@@ -459,7 +463,7 @@ namespace Coffee.UIExtensions
r.canvasRenderer.SetMaterial(materialForRendering, 0); r.canvasRenderer.SetMaterial(materialForRendering, 0);
} }
ListPool<UIParticleRenderer>.Return(ref renderers); InternalListPool<UIParticleRenderer>.Return(ref renderers);
if (_parent.canRender) if (_parent.canRender)
{ {
@@ -548,6 +552,24 @@ namespace Coffee.UIExtensions
* Matrix4x4.Scale(scale) * Matrix4x4.Scale(scale)
* Matrix4x4.Translate(-psPos); * 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))
@@ -610,6 +632,7 @@ 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)

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

@@ -40,13 +40,26 @@ namespace Coffee.UIExtensions
#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()
{ {

View File

@@ -13,11 +13,7 @@ namespace Coffee.UIParticleInternal
{ {
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];
} }
@@ -171,5 +167,34 @@ namespace Coffee.UIParticleInternal
action.Invoke(p); action.Invoke(p);
} }
} }
public static ParticleSystem GetMainEmitter(this ParticleSystem self, List<ParticleSystem> list)
{
if (!self || 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 || !parent) 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

@@ -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.10.4", "version": "4.11.4",
"unity": "2018.2", "unity": "2018.2",
"license": "MIT", "license": "MIT",
"repository": { "repository": {

View File

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