Compare commits

..

9 Commits

Author SHA1 Message Date
semantic-release-bot
88d956ece8 chore(release): 5.0.0-preview.14 [skip ci]
# [5.0.0-preview.14](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/5.0.0-preview.13...5.0.0-preview.14) (2025-01-03)

### 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:26:44 +00:00
mob-sakai
2842b3db7d Merge branch 'develop' into develop-preview 2025-01-03 23:14:17 +09:00
semantic-release-bot
c2958d5d7d chore(release): 5.0.0-preview.13 [skip ci]
# [5.0.0-preview.13](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/5.0.0-preview.12...5.0.0-preview.13) (2025-01-03)

### Features

* change the default value of `UIParticle.scale` from `10` to `1` ([9955eef](9955eefdc2))
* UIParticle no longer inherits from MaskableGraphic ([c09bfb8](c09bfb81ab))

### BREAKING CHANGES

* Some members inherited from MaskableGraphic will no longer be available.
2025-01-03 14:12:36 +00:00
mob-sakai
7456b5d555 docs: update documents 2025-01-03 23:08:20 +09:00
mob-sakai
9955eefdc2 feat: change the default value of UIParticle.scale from 10 to 1 2025-01-03 23:02:15 +09:00
mob-sakai
c09bfb81ab feat: UIParticle no longer inherits from MaskableGraphic
BREAKING CHANGE: Some members inherited from MaskableGraphic will no longer be available.
2025-01-03 23:02:15 +09:00
mob-sakai
fab2ed1697 chore: update coffee.internal 2025-01-03 22:58:23 +09:00
mob-sakai
ef4dbc3cba fix: sub-emitter particles may not render correctly in certain scenarios
close #248
2025-01-03 22:50:36 +09:00
mob-sakai
27551a4d47 fix: sub-emitter's inherit velocity module doubles at runtime
close #249
2025-01-03 22:29:07 +09:00
41 changed files with 2811 additions and 502 deletions

28
.github/workflows/deploy.yml vendored Normal file
View File

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

View File

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

View File

@@ -7,10 +7,9 @@ run-name: 🧪 Test (${{ github.event.pull_request.title || github.ref_name }})
env:
# MINIMUM_VERSION: The minimum version of Unity.
MINIMUM_VERSION: 2020.3
MINIMUM_VERSION: 2019.4
# EXCLUDE_FILTER: The excluded versions of Unity.
EXCLUDE_FILTER: "(2017|2018|2023.3)"
PROJECT_PATH: .
EXCLUDE_FILTER: "(2020.2.0|2021.1|2023.3)"
on:
workflow_dispatch:
@@ -22,7 +21,7 @@ on:
push:
branches:
- develop
- "develop-*"
- develop-preview
tags:
- "!*"
paths-ignore:
@@ -46,9 +45,9 @@ jobs:
id: setup
run: |
echo "==== Target Unity Versions ===="
LATEST_VERSIONS=`npx unity-changeset@latest list --versions --latest-patch --min ${MINIMUM_VERSION} --json --all --ignore-alpha`
LATEST_VERSIONS=`npx unity-changeset@latest 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 --ignore-alpha`
ADDITIONAL_VERSIONS=`npx unity-changeset list --versions --grep '0f' --min ${MINIMUM_VERSION} --json`
else
ADDITIONAL_VERSIONS=[]
fi
@@ -72,11 +71,11 @@ jobs:
steps:
- name: 🚚 Checkout ($${{ github.ref }})
if: github.event_name == 'push'
uses: actions/checkout@v6
uses: actions/checkout@v4
- name: 🚚 Checkout pull request (pull_request_target)
if: github.event_name == 'pull_request_target'
uses: actions/checkout@v6
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }}
fetch-depth: 0
@@ -86,27 +85,25 @@ jobs:
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
git merge origin/${{ github.event.pull_request.base.ref }} --no-edit
- name: 📥 Cache library
uses: actions/cache@v5
uses: actions/cache@v4
with:
path: ${{ env.PROJECT_PATH }}/Library
key: ${{ env.PROJECT_PATH }}-Library-${{ matrix.unityVersion }}-${{ github.event.pull_request.head.sha || github.sha }}
path: Library
key: Library-${{ matrix.unityVersion }}-${{ github.event.pull_request.head.sha || github.sha }}
restore-keys: |
${{ env.PROJECT_PATH }}-Library-${{ matrix.unityVersion }}-
${{ env.PROJECT_PATH }}-Library-
Library-${{ matrix.unityVersion }}-
Library-
- name: 🛠️ Build Unity Project (Test)
uses: game-ci/unity-builder@v5
uses: game-ci/unity-builder@v4
timeout-minutes: 45
with:
customImage: ghcr.io/mob-sakai/unity3d:${{ matrix.unityVersion }}
targetPlatform: StandaloneLinux64
allowDirtyBuild: true
customParameters: -nographics
projectPath: ${{ env.PROJECT_PATH }}
env:
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
@@ -121,7 +118,6 @@ jobs:
customParameters: -nographics
checkName: ${{ matrix.unityVersion }} Test Results
githubToken: ${{ github.token }}
projectPath: ${{ env.PROJECT_PATH }}
env:
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}

View File

@@ -18,12 +18,11 @@ MonoBehaviour:
m_EnabledInEditor: 1
m_AlwaysIncludeAssembly: 1
m_InstantiateOnLoad: 1
m_Prefab: {fileID: 4567906826058368312, guid: 7cebff2d255b9433cbe23b243c193329,
m_Prefab: {fileID: 7211429669315726685, guid: b73940fc30a2f4eb9a73783e9c1f8da6,
type: 3}
m_Interval: 0.5
m_Anchor: 0
m_Width: 750
m_HelpUrl: https://github.com/mob-sakai/ParticleEffectForUGUI
m_CustomMonitorItems:
- m_Format: Screen:{0}x{1}
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,7 @@ MonoBehaviour:
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: f22a23b9d98e440478697f4adf30e61c, type: 3}
m_Name: UIParticleProjectSettings
m_Name: UIParticle
m_EditorClassIdentifier:
m_EnableLinearToGamma: 1
m_HideGeneratedObjects: 1

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,75 +1,4 @@
## [4.12.2](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.12.1...v4.12.2) (2026-06-08)
### Bug Fixes
* add `meshCleared` flag to optimize mesh clearing ([859fa20](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/859fa20d297c3f44e3361f20dbb7ce966407e03e))
* fix Unity6.5 compile errors and warnings ([a5ee687](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/a5ee6878212be2fc4d7b48879426f239e8753009)), closes [#400](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/400)
* potential access to UIParticleRenderer that has already been destroyed ([b740dd6](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/b740dd662d423c6bef849662ce1b0bfbb4940ed4)), closes [#403](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/403)
* updated support for some changed menu paths ([f8ac986](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/f8ac9869f141238169730e74f5d65c4fc6081f51)), closes [#397](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/397)
## [4.12.1](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.12.0...v4.12.1) (2026-03-24)
### Bug Fixes
* ignore "EditorOnly" tagged gameObjects on refresh ([031d46a](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/031d46a3216c942d2d1a6ccfadf5f0b9e3ce3006))
# [4.12.0](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.11.4...v4.12.0) (2026-03-24)
### Features
* 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)
# [5.0.0-preview.14](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/5.0.0-preview.13...5.0.0-preview.14) (2025-01-03)
### Bug Fixes
@@ -77,6 +6,19 @@
* 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)
# [5.0.0-preview.13](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/5.0.0-preview.12...5.0.0-preview.13) (2025-01-03)
### Features
* change the default value of `UIParticle.scale` from `10` to `1` ([9955eef](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/9955eefdc22cf565502f85c87cd2efd3a25fbe50))
* UIParticle no longer inherits from MaskableGraphic ([c09bfb8](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/c09bfb81abc9179bf5fc49d29eaf7fc4ed01a4dc))
### BREAKING CHANGES
* Some members inherited from MaskableGraphic will no longer be available.
## [4.10.5](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.10.4...v4.10.5) (2024-12-23)

View File

@@ -76,21 +76,12 @@ namespace Coffee.UIExtensions
for (var j = 0; j < mats.Count; j++)
{
var mat = mats[j];
if (mat == null || mat.shader == null) continue;
if (!mat || !mat.shader) continue;
#if UNITY_6000_5_OR_NEWER
for (var i = 0; i < mat.shader.GetPropertyCount(); i++)
#else
for (var i = 0; i < ShaderUtil.GetPropertyCount(mat.shader); i++)
#endif
{
#if UNITY_6000_5_OR_NEWER
var name = mat.shader.GetPropertyName(i);
var type = (AnimatableProperty.ShaderPropertyType)mat.shader.GetPropertyType(i);
#else
var name = ShaderUtil.GetPropertyName(mat.shader, i);
var type = (AnimatableProperty.ShaderPropertyType)ShaderUtil.GetPropertyType(mat.shader, i);
#endif
if (!s_Names.Add(name)) continue;
AddMenu(gm, sp, new ShaderProperty(name, type), true);

View File

@@ -2,7 +2,6 @@ using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using UnityEditor;
using UnityEditor.UI;
using UnityEditorInternal;
using UnityEngine;
using UnityEngine.Profiling;
@@ -26,7 +25,7 @@ namespace Coffee.UIExtensions
{
[CustomEditor(typeof(UIParticle))]
[CanEditMultipleObjects]
internal class UIParticleEditor : GraphicEditor
internal class UIParticleEditor : Editor
{
internal class State : ScriptableSingleton<State>
{
@@ -62,7 +61,6 @@ namespace Coffee.UIExtensions
private SerializedProperty _autoScalingMode;
private SerializedProperty _useCustomView;
private SerializedProperty _customViewSize;
private SerializedProperty _timeScaleMultiplier;
private ReorderableList _ro;
private bool _showMax;
private bool _is3DScaleMode;
@@ -87,10 +85,8 @@ namespace Coffee.UIExtensions
/// <summary>
/// This function is called when the object becomes enabled and active.
/// </summary>
protected override void OnEnable()
private void OnEnable()
{
base.OnEnable();
_maskable = serializedObject.FindProperty("m_Maskable");
_scale3D = serializedObject.FindProperty("m_Scale3D");
_animatableProperties = serializedObject.FindProperty("m_AnimatableProperties");
@@ -101,7 +97,6 @@ namespace Coffee.UIExtensions
_autoScalingMode = serializedObject.FindProperty("m_AutoScalingMode");
_useCustomView = serializedObject.FindProperty("m_UseCustomView");
_customViewSize = serializedObject.FindProperty("m_CustomViewSize");
_timeScaleMultiplier = serializedObject.FindProperty("m_TimeScaleMultiplier");
var sp = serializedObject.FindProperty("m_Particles");
_ro = new ReorderableList(sp.serializedObject, sp, true, true, true, true)
@@ -110,7 +105,7 @@ namespace Coffee.UIExtensions
{
var ps = sp.GetArrayElementAtIndex(index).objectReferenceValue as ParticleSystem;
var materialCount = 0;
if (ps != null && ps.TryGetComponent<ParticleSystemRenderer>(out var psr))
if (ps && ps.TryGetComponent<ParticleSystemRenderer>(out var psr))
{
materialCount = psr.sharedMaterials.Length;
}
@@ -124,7 +119,7 @@ namespace Coffee.UIExtensions
var p = sp.GetArrayElementAtIndex(index);
EditorGUI.ObjectField(rect, p, GUIContent.none);
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.width -= 15;
@@ -191,7 +186,7 @@ namespace Coffee.UIExtensions
public override void OnInspectorGUI()
{
var current = target as UIParticle;
if (current == null) return;
if (!current) return;
Profiler.BeginSample("(UIP:E) OnInspectorGUI");
serializedObject.Update();
@@ -246,9 +241,6 @@ namespace Coffee.UIExtensions
_customViewSize.floatValue = Mathf.Max(0.1f, _customViewSize.floatValue);
}
// Time Scale Multiplier
EditorGUILayout.PropertyField(_timeScaleMultiplier);
// Target ParticleSystems.
EditorGUI.BeginChangeCheck();
_ro.DoLayoutList();
@@ -267,7 +259,7 @@ namespace Coffee.UIExtensions
Profiler.BeginSample("(UIP:E) Non-UI built-in shader is not supported.");
foreach (var mat in s_TempMaterials)
{
if (mat == null || mat.shader == null) continue;
if (!mat || !mat.shader) continue;
var shader = mat.shader;
if (IsBuiltInObject(shader) && !shader.name.StartsWith("UI/"))
{
@@ -286,7 +278,7 @@ namespace Coffee.UIExtensions
{
foreach (var mat in s_TempMaterials)
{
if (mat == null || mat.shader == null) continue;
if (!mat || !mat.shader) continue;
var shader = mat.shader;
if (!s_Shaders.Add(shader)) continue;
@@ -464,9 +456,11 @@ namespace Coffee.UIExtensions
{
if (!p || (ignoreCurrent && target == p)) return;
var cr = p.canvasRenderer;
DestroyImmediate(p);
DestroyImmediate(cr);
Misc.DestroyImmediate(p);
if (p.TryGetComponent<CanvasRenderer>(out var cr))
{
Misc.DestroyImmediate(cr);
}
#if UNITY_2018_3_OR_NEWER
var stage = PrefabStageUtility.GetCurrentPrefabStage();

View File

@@ -6,22 +6,11 @@ namespace Coffee.UIExtensions
{
internal class UIParticleMenu
{
#if UNITY_6000_5_OR_NEWER
private const string k_MenuPathToCreateParticleSystem = "GameObject/Visual Effects/Particle System";
#else
private const string k_MenuPathToCreateParticleSystem = "GameObject/Effects/Particle System";
#endif
#if UNITY_6000_3_OR_NEWER
private const string k_MenuPathForUgui = "GameObject/UI (Canvas)";
#else
private const string k_MenuPathForUgui = "GameObject/UI";
#endif
[MenuItem(k_MenuPathForUgui + "/Particle System (Empty)", false, 2018)]
[MenuItem("GameObject/UI/Particle System (Empty)", false, 2018)]
private static void AddParticleEmpty(MenuCommand menuCommand)
{
// Create empty UI element.
EditorApplication.ExecuteMenuItem(k_MenuPathForUgui + "/Image");
EditorApplication.ExecuteMenuItem("GameObject/UI/Image");
var ui = Selection.activeGameObject;
Object.DestroyImmediate(ui.GetComponent<Image>());
@@ -32,7 +21,7 @@ namespace Coffee.UIExtensions
uiParticle.rectTransform.sizeDelta = Vector2.zero;
}
[MenuItem(k_MenuPathForUgui + "/Particle System", false, 2019)]
[MenuItem("GameObject/UI/Particle System", false, 2019)]
private static void AddParticle(MenuCommand menuCommand)
{
// Create empty UIEffect.
@@ -40,7 +29,7 @@ namespace Coffee.UIExtensions
var uiParticle = Selection.activeGameObject.GetComponent<UIParticle>();
// Create ParticleSystem.
EditorApplication.ExecuteMenuItem(k_MenuPathToCreateParticleSystem);
EditorApplication.ExecuteMenuItem("GameObject/Effects/Particle System");
var ps = Selection.activeGameObject;
ps.transform.SetParent(uiParticle.transform, false);
ps.transform.localPosition = Vector3.zero;

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

@@ -1,9 +1,9 @@
# <img alt="UIParticleIcon" src="https://github.com/mob-sakai/ParticleEffectForUGUI/assets/12690315/d76e105e-a840-4f61-a1f6-8cf311c0812d" width="26"/> Particle Effect For UGUI (UI Particle) <!-- omit in toc -->
# <img alt="UIParticleIcon" src="https://github.com/mob-sakai/ParticleEffectForUGUI/assets/12690315/d76e105e-a840-4f61-a1f6-8cf311c0812d" width="26"/> UI Particle v5 <!-- omit in toc -->
[![](https://img.shields.io/npm/v/com.coffee.ui-particle?label=openupm&registry_uri=https://package.openupm.com)](https://openupm.com/packages/com.coffee.ui-particle/)
[![](https://img.shields.io/github/v/release/mob-sakai/ParticleEffectForUGUI)](https://github.com/mob-sakai/ParticleEffectForUGUI/releases)
[![](https://img.shields.io/github/license/mob-sakai/ParticleEffectForUGUI.svg)](https://github.com/mob-sakai/ParticleEffectForUGUI/blob/main/LICENSE.md)
![](https://img.shields.io/badge/Unity-2018.2+-57b9d3.svg?style=flat&logo=unity)
![](https://img.shields.io/badge/Unity-2019.3+-57b9d3.svg?style=flat&logo=unity)
![](https://img.shields.io/badge/uGUI_2.0_Ready-57b9d3.svg?style=flat)
![](https://img.shields.io/badge/UPR%2FHDPR_Ready-57b9d3.svg?style=flat)
![](https://github.com/mob-sakai/ParticleEffectForUGUI/actions/workflows/test.yml/badge.svg?branch=develop)
@@ -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/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 -->
@@ -26,7 +26,9 @@ You can render, mask, and sort your `ParticleSystems` for UI without the need fo
- [Install via OpenUPM](#install-via-openupm)
- [Install via UPM (with Package Manager UI)](#install-via-upm-with-package-manager-ui)
- [Install via UPM (Manually)](#install-via-upm-manually)
- [Install as Embedded Package](#install-as-embedded-package)
- [Install as Embedded Package](#install-as-embedded-package)
- [🔄 Upgrading from v3/v4 to v5](#-upgrading-from-v3v4-to-v5)
- [Breaking Changes](#breaking-changes)
- [🚀 Usage](#-usage)
- [Component: UIParticle](#component-uiparticle)
- [Basic Usage](#basic-usage)
@@ -104,7 +106,7 @@ You can render, mask, and sort your `ParticleSystems` for UI without the need fo
## ⚙ Installation
_This package requires **Unity 2018.3 or later**._
_This package requires **Unity 2019.3 or later**._
#### Install via OpenUPM
@@ -116,16 +118,16 @@ _This package requires **Unity 2018.3 or later**._
```
- To update the package, use Package Manager UI (`Window > Package Manager`) or run the following command with `@{version}`:
```
openupm add com.coffee.ui-particle@4.9.0
openupm add com.coffee.ui-particle@5.0.0
```
#### Install via UPM (with Package Manager UI)
- Click `Window > Package Manager` to open Package Manager UI.
- Click `+ > Add package from git URL...` and input the repository URL: `https://github.com/mob-sakai/ParticleEffectForUGUI.git`
- Click `+ > Add package from git URL...` and input the repository URL: `https://github.com/mob-sakai/ParticleEffectForUGUI.git?path=Packages/src`
![](https://github.com/user-attachments/assets/f88f47ad-c606-44bd-9e86-ee3f72eac548)
- To update the package, change suffix `#{version}` to the target version.
- e.g. `https://github.com/mob-sakai/ParticleEffectForUGUI.git#4.9.0`
- e.g. `https://github.com/mob-sakai/ParticleEffectForUGUI.git?path=Packages/src#5.0.0`
#### Install via UPM (Manually)
@@ -133,22 +135,41 @@ _This package requires **Unity 2018.3 or later**._
```json
{
"dependencies": {
"com.coffee.ui-particle": "https://github.com/mob-sakai/ParticleEffectForUGUI.git",
"com.coffee.ui-particle": "https://github.com/mob-sakai/ParticleEffectForUGUI.git?path=Packages/src",
...
}
}
```
- To update the package, change suffix `#{version}` to the target version.
- e.g. `"com.coffee.ui-particle": "https://github.com/mob-sakai/ParticleEffectForUGUI.git#4.9.0",`
- e.g. `"com.coffee.ui-particle": "https://github.com/mob-sakai/ParticleEffectForUGUI.git?path=Packages/src#5.0.0",`
#### 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.
2. Place it in your project's `Packages` directory.
![](https://github.com/mob-sakai/mob-sakai/assets/12690315/0b7484b4-5fca-43b0-a9ef-e5dbd99bcdb4)
- If you want to fix bugs or add features, install it as an embedded package.
- To update the package, you need to re-download it and replace the contents.
1. Download the `Source code (zip)` file from [Releases](https://github.com/mob-sakai/SoftMaskForUGUI/releases) and
extract it.
2. Move the `<extracted_dir>/Packages/src` directory into your project's `Packages` directory.
![](https://github.com/user-attachments/assets/187cbcbe-5922-4ed5-acec-cf19aa17d208)
- You can rename the `src` directory if needed.
- If you intend to fix bugs or add features, installing it as an embedded package is recommended.
- To update the package, re-download it and replace the existing contents.
<br><br>
## 🔄 Upgrading from v3/v4 to v5
### Breaking Changes
- The default value of `UIParticle.scale` has been changed from `10` to `1`.
- `UIParticle` no longer inherits from `MaskableGraphic`.
- If you are installing via git URL, add `?path=Packages/src`.
```json
// v3/v4
"com.coffee.ui-particle": "https://github.com/mob-sakai/ParticleEffectForUGUI.git",
// v5
"com.coffee.ui-particle": "https://github.com/mob-sakai/ParticleEffectForUGUI.git?path=Packages/src",
```
<br><br>
@@ -158,7 +179,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.
![](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.
- **Scale**: Scale the rendering particles. When the `3D` toggle is enabled, 3D scale (x, y, z) is supported.
@@ -180,7 +201,6 @@ _This package requires **Unity 2018.3 or later**._
- **UIParticle:** UIParticle.scale will be adjusted.
- **Use Custom View:** Use this if the particles are not displayed correctly due to min/max particle size.
- **Custom view size:** Change the bake view size.
- **Time Scale Multiplier:** Time scale multiplier.
- **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
@@ -211,7 +231,7 @@ and z-position.
If you want to mask particles, set a stencil-supported shader (such as `UI/UIAdditive`) to the material for
ParticleSystem.
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.
![](https://user-images.githubusercontent.com/12690315/95017591-3b512700-0695-11eb-864e-04166ea1809a.png)

View File

@@ -37,17 +37,37 @@ namespace Coffee.UIExtensions
switch (type)
{
case ShaderPropertyType.Color:
material.SetColor(id, mpb.GetColor(id));
var color = mpb.GetColor(id);
if (color != default)
{
material.SetColor(id, color);
}
break;
case ShaderPropertyType.Vector:
material.SetVector(id, mpb.GetVector(id));
var vector = mpb.GetVector(id);
if (vector != default)
{
material.SetVector(id, vector);
}
break;
case ShaderPropertyType.Float:
case ShaderPropertyType.Range:
material.SetFloat(id, mpb.GetFloat(id));
var value = mpb.GetFloat(id);
if (!Mathf.Approximately(value, 0))
{
material.SetFloat(id, value);
}
break;
case ShaderPropertyType.Texture:
material.SetTexture(id, mpb.GetTexture(id));
var tex = mpb.GetTexture(id);
if (tex != default(Texture))
{
material.SetTexture(id, tex);
}
break;
}
}

View File

@@ -38,7 +38,7 @@ namespace Coffee.UIParticleInternal
private static void GetComponentsInChildren_Internal<T>(this Component self, List<T> results, int depth)
where T : Component
{
if (self == null || results == null || depth < 0) return;
if (!self || results == null || depth < 0) return;
var tr = self.transform;
if (tr.TryGetComponent<T>(out var t))
@@ -59,7 +59,7 @@ namespace Coffee.UIParticleInternal
/// </summary>
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)
? component
: self.gameObject.AddComponent<T>();
@@ -166,7 +166,7 @@ namespace Coffee.UIParticleInternal
#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
{
if (self == null) return null;
if (!self) return null;
if (!includeInactive) return self.GetComponentInParent<T>();
var current = self.transform;
@@ -186,7 +186,7 @@ namespace Coffee.UIParticleInternal
/// </summary>
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>
@@ -204,7 +204,7 @@ namespace Coffee.UIParticleInternal
target.enabled = false;
// Find MonoScript of the specified component.
foreach (var script in MonoImporter.GetAllRuntimeMonoScripts())
foreach (var script in Resources.FindObjectsOfTypeAll<MonoScript>())
{
if (script.GetClass() != typeof(T))
{

View File

@@ -32,10 +32,10 @@ namespace Coffee.UIParticleInternal
/// </summary>
public static Texture2D GetActualTexture(this Sprite self)
{
if (self == null) return null;
if (!self) return null;
var ret = s_GetActiveAtlasTextureMethod(self);
return ret != null ? ret : self.texture;
return ret ? ret : self.texture;
}
/// <summary>
@@ -43,7 +43,7 @@ namespace Coffee.UIParticleInternal
/// </summary>
public static SpriteAtlas GetActiveAtlas(this Sprite self)
{
if (self == null) return null;
if (!self) return null;
return s_GetActiveAtlasMethod(self);
}
@@ -53,7 +53,7 @@ namespace Coffee.UIParticleInternal
/// </summary>
internal static Texture2D GetActualTexture(this Sprite self)
{
return self != null ? self.texture : null;
return self ? self.texture : null;
}
#endif
}

View File

@@ -37,7 +37,7 @@ namespace Coffee.UIParticleInternal
foreach (var t in TypeCache.GetTypesDerivedFrom(typeof(PreloadedProjectSettings<>)))
{
var defaultSettings = GetDefaultSettings(t);
if (defaultSettings == null)
if (!defaultSettings)
{
// When create a new instance, automatically set it as default settings.
defaultSettings = CreateInstance(t) as PreloadedProjectSettings;
@@ -48,7 +48,7 @@ namespace Coffee.UIParticleInternal
SetDefaultSettings(defaultSettings);
}
if (defaultSettings != null)
if (defaultSettings)
{
defaultSettings.OnInitialize();
}
@@ -66,7 +66,7 @@ namespace Coffee.UIParticleInternal
private static Object[] GetPreloadedSettings(Type type)
{
return PlayerSettings.GetPreloadedAssets()
.Where(x => x != null && x.GetType() == type)
.Where(x => x && x.GetType() == type)
.ToArray();
}
@@ -76,12 +76,12 @@ namespace Coffee.UIParticleInternal
?? AssetDatabase.FindAssets($"t:{nameof(PreloadedProjectSettings)}")
.Select(AssetDatabase.GUIDToAssetPath)
.Select(AssetDatabase.LoadAssetAtPath<PreloadedProjectSettings>)
.FirstOrDefault(x => x != null && x.GetType() == type);
.FirstOrDefault(x => x && x.GetType() == type);
}
protected static void SetDefaultSettings(PreloadedProjectSettings asset)
{
if (asset == null) return;
if (!asset) return;
var type = asset.GetType();
if (string.IsNullOrEmpty(AssetDatabase.GetAssetPath(asset)))
@@ -103,7 +103,7 @@ namespace Coffee.UIParticleInternal
var preloadedAssets = PlayerSettings.GetPreloadedAssets();
var projectSettings = GetPreloadedSettings(type);
PlayerSettings.SetPreloadedAssets(preloadedAssets
.Where(x => x != null)
.Where(x => x)
.Except(projectSettings.Except(new[] { asset }))
.Append(asset)
.Distinct()
@@ -133,19 +133,19 @@ namespace Coffee.UIParticleInternal
#if UNITY_EDITOR
private string _jsonText;
public static bool hasInstance => s_Instance != null;
public static bool hasInstance => s_Instance;
public static T instance
{
get
{
if (s_Instance != null) return s_Instance;
if (s_Instance) return s_Instance;
s_Instance = GetDefaultSettings(typeof(T)) as T;
if (s_Instance != null) return s_Instance;
if (s_Instance) return s_Instance;
s_Instance = CreateInstance<T>();
if (s_Instance == null)
if (!s_Instance)
{
s_Instance = null;
return s_Instance;
@@ -158,8 +158,6 @@ namespace Coffee.UIParticleInternal
private void OnPlayModeStateChanged(PlayModeStateChange state)
{
if (!this) return;
switch (state)
{
case PlayModeStateChange.ExitingEditMode:
@@ -176,7 +174,7 @@ namespace Coffee.UIParticleInternal
}
}
#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
/// <summary>
@@ -185,7 +183,7 @@ namespace Coffee.UIParticleInternal
protected virtual void OnEnable()
{
#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)
{
DestroyImmediate(this, true);
@@ -195,7 +193,7 @@ namespace Coffee.UIParticleInternal
EditorApplication.playModeStateChanged += OnPlayModeStateChanged;
#endif
if (s_Instance != null) return;
if (s_Instance) return;
s_Instance = this as T;
}
@@ -224,7 +222,7 @@ namespace Coffee.UIParticleInternal
public override void OnGUI(string searchContext)
{
if (_target == null)
if (!_target)
{
if (_editor)
{

View File

@@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: 4f9f22bb079324476b1473030ad9fec3

View File

@@ -11,7 +11,7 @@ using Conditional = System.Diagnostics.ConditionalAttribute;
namespace Coffee.UIParticleInternal
{
internal static class Logger
internal static class Logging
{
#if !ENABLE_COFFEE_LOGGER
private const string k_DisableSymbol = "DISABLE_COFFEE_LOGGER";
@@ -48,7 +48,7 @@ namespace Coffee.UIParticleInternal
public static void LogIf(bool enable, object tag, object message, Object context = null)
{
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
@@ -56,7 +56,7 @@ namespace Coffee.UIParticleInternal
#endif
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
@@ -64,13 +64,13 @@ namespace Coffee.UIParticleInternal
#endif
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)
{
#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
Debug.LogError($"{tag}: {message}", context);
#endif

View File

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

View File

@@ -3,16 +3,11 @@ 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
#if UNITY_EDITOR && UNITY_2021_2_OR_NEWER
using UnityEditor.SceneManagement;
#else
#elif UNITY_EDITOR
using UnityEditor.Experimental.SceneManagement;
#endif
#endif
namespace Coffee.UIParticleInternal
{
@@ -20,9 +15,7 @@ namespace Coffee.UIParticleInternal
{
public static T[] FindObjectsOfType<T>() where T : Object
{
#if UNITY_6000_4_OR_NEWER
return Object.FindObjectsByType<T>(FindObjectsInactive.Include);
#elif UNITY_2023_1_OR_NEWER
#if UNITY_2023_1_OR_NEWER
return Object.FindObjectsByType<T>(FindObjectsInactive.Include, FindObjectsSortMode.None);
#else
return Object.FindObjectsOfType<T>();
@@ -31,7 +24,7 @@ namespace Coffee.UIParticleInternal
public static void Destroy(Object obj)
{
if (obj == null) return;
if (!obj) return;
#if UNITY_EDITOR
if (!Application.isPlaying)
{
@@ -46,7 +39,7 @@ namespace Coffee.UIParticleInternal
public static void DestroyImmediate(Object obj)
{
if (obj == null) return;
if (!obj) return;
#if UNITY_EDITOR
if (Application.isEditor)
{
@@ -63,7 +56,7 @@ namespace Coffee.UIParticleInternal
public static void SetDirty(Object obj)
{
#if UNITY_EDITOR
if (obj == null) return;
if (!obj) return;
EditorUtility.SetDirty(obj);
#endif
}
@@ -79,56 +72,5 @@ namespace Coffee.UIParticleInternal
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

@@ -34,7 +34,7 @@ namespace Coffee.UIParticleInternal
}
// If there are no instances in the pool, create a new one.
Logger.Log(this, $"A new instance is created (pooled: {_pool.CountInactive}, created: {_pool.CountAll}).");
Logging.Log(this, $"A new instance is created (pooled: {_pool.CountInactive}, created: {_pool.CountAll}).");
return _pool.Get();
}
@@ -47,7 +47,7 @@ namespace Coffee.UIParticleInternal
if (instance == null) return; // Ignore if already pooled or null.
_pool.Release(instance);
Logger.Log(this, $"An instance is released (pooled: {_pool.CountInactive}, created: {_pool.CountAll}).");
Logging.Log(this, $"An instance is released (pooled: {_pool.CountInactive}, created: {_pool.CountAll}).");
instance = default; // Set the reference to null.
}
#else
@@ -80,7 +80,7 @@ namespace Coffee.UIParticleInternal
}
// If there are no instances in the pool, create a new one.
Logger.Log(this, $"A new instance is created (pooled: {_pool.Count}, created: {++_count}).");
Logging.Log(this, $"A new instance is created (pooled: {_pool.Count}, created: {++_count}).");
return _onCreate();
}
@@ -94,7 +94,7 @@ namespace Coffee.UIParticleInternal
_onReturn(instance); // Return the instance to the pool.
_pool.Push(instance);
Logger.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.
}
#endif

View File

@@ -90,7 +90,7 @@ namespace Coffee.UIParticleInternal
Profiler.BeginSample("(COF)[ObjectRepository] GetFromCache");
if (_cache.TryGetValue(hash, out var entry))
{
if (entry.storedObject == null)
if (!entry.storedObject)
{
Release(ref entry.storedObject);
Profiler.EndSample();
@@ -103,7 +103,7 @@ namespace Coffee.UIParticleInternal
Release(ref obj);
++entry.reference;
obj = entry.storedObject;
Logger.Log(_name, $"Get(total#{count}): {entry}");
Logging.Log(_name, $"Get(total#{count}): {entry}");
}
Profiler.EndSample();
@@ -116,7 +116,7 @@ namespace Coffee.UIParticleInternal
private void Add(Hash128 hash, ref T obj, T newObject)
{
if (newObject == null)
if (!newObject)
{
Release(ref obj);
obj = newObject;
@@ -130,8 +130,8 @@ namespace Coffee.UIParticleInternal
newEntry.hash = hash;
newEntry.reference = 1;
_cache[hash] = newEntry;
_objectKey[newObject.GetHashCode()] = hash;
Logger.Log(_name, $"<color=#03c700>Add</color>(total#{count}): {newEntry}");
_objectKey[newObject.GetInstanceID()] = hash;
Logging.Log(_name, $"<color=#03c700>Add</color>(total#{count}): {newEntry}");
Release(ref obj);
obj = newObject;
Profiler.EndSample();
@@ -146,23 +146,23 @@ namespace Coffee.UIParticleInternal
// Find and release the entry.
Profiler.BeginSample("(COF)[ObjectRepository] Release");
var id = obj.GetHashCode();
var id = obj.GetInstanceID();
if (_objectKey.TryGetValue(id, out var hash)
&& _cache.TryGetValue(hash, out var entry))
{
entry.reference--;
if (entry.reference <= 0 || entry.storedObject == null)
if (entry.reference <= 0 || !entry.storedObject)
{
Remove(entry);
}
else
{
Logger.Log(_name, $"Release(total#{_cache.Count}): {entry}");
Logging.Log(_name, $"Release(total#{_cache.Count}): {entry}");
}
}
else
{
Logger.Log(_name, $"Release(total#{_cache.Count}): <color=red>Already released: {obj}</color>");
Logging.Log(_name, $"Release(total#{_cache.Count}): <color=red>Already released: {obj}</color>");
}
obj = null;
@@ -175,10 +175,10 @@ namespace Coffee.UIParticleInternal
Profiler.BeginSample("(COF)[ObjectRepository] Remove");
_cache.Remove(entry.hash);
_objectKey.Remove(entry.storedObject.GetHashCode());
_objectKey.Remove(entry.storedObject.GetInstanceID());
_pool.Push(entry);
entry.reference = 0;
Logger.Log(_name, $"<color=#f29e03>Remove</color>(total#{_cache.Count}): {entry}");
Logging.Log(_name, $"<color=#f29e03>Remove</color>(total#{_cache.Count}): {entry}");
entry.Release(_onRelease);
Profiler.EndSample();
}
@@ -192,7 +192,7 @@ namespace Coffee.UIParticleInternal
public void Release(Action<T> onRelease)
{
reference = 0;
if (storedObject != null)
if (storedObject)
{
onRelease?.Invoke(storedObject);
}

View File

@@ -1,5 +1,4 @@
using System;
using System.Reflection;
using UnityEditor;
using UnityEngine;
using UnityEngine.UI;
@@ -21,7 +20,7 @@ namespace Coffee.UIParticleInternal
static UIExtraCallbacks()
{
Canvas.willRenderCanvases += OnBeforeCanvasRebuild;
Logger.LogMulticast(typeof(Canvas), "willRenderCanvases", message: "ctor");
Logging.LogMulticast(typeof(Canvas), "willRenderCanvases", message: "ctor");
}
/// <summary>
@@ -68,17 +67,9 @@ namespace Coffee.UIParticleInternal
if (s_IsInitializedAfterCanvasRebuild) return;
s_IsInitializedAfterCanvasRebuild = true;
// Explicitly set `Canvas.willRenderCanvases += CanvasUpdateRegistry.PerformUpdate`.
CanvasUpdateRegistry.IsRebuildingLayout();
#if TMP_ENABLE
// Explicitly set `Canvas.willRenderCanvases += TMP_UpdateManager.DoRebuilds`.
typeof(TMPro.TMP_UpdateManager)
.GetProperty("instance", BindingFlags.NonPublic | BindingFlags.Static)
.GetValue(null);
#endif
Canvas.willRenderCanvases -= OnAfterCanvasRebuild;
Canvas.willRenderCanvases += OnAfterCanvasRebuild;
Logger.LogMulticast(typeof(Canvas), "willRenderCanvases",
Logging.LogMulticast(typeof(Canvas), "willRenderCanvases",
message: "InitializeAfterCanvasRebuild");
}

View File

@@ -3,13 +3,12 @@ using System.Collections.Generic;
using System.Runtime.CompilerServices;
using Coffee.UIParticleInternal;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Rendering;
using UnityEngine.Serialization;
using UnityEngine.UI;
using Random = UnityEngine.Random;
[assembly: InternalsVisibleTo("Coffee.UIParticle.Editor")]
[assembly: InternalsVisibleTo("Coffee.UIParticle.Editor.Tests")]
[assembly: InternalsVisibleTo("Coffee.UIParticle.PerformanceDemo")]
[assembly: InternalsVisibleTo("Coffee.UIParticle.Demo")]
@@ -18,11 +17,10 @@ namespace Coffee.UIExtensions
/// <summary>
/// Render maskable and sortable particle effect ,without Camera, RenderTexture or Canvas.
/// </summary>
[Icon("Packages/com.coffee.ui-particle/Editor/UIParticleIcon.png")]
[ExecuteAlways]
[RequireComponent(typeof(RectTransform))]
[RequireComponent(typeof(CanvasRenderer))]
public class UIParticle : MaskableGraphic, ISerializationCallbackReceiver
public class UIParticle : UIBehaviour, ISerializationCallbackReceiver
{
public enum AutoScalingMode
{
@@ -64,7 +62,7 @@ namespace Coffee.UIExtensions
[Tooltip("Scale the rendering particles. When the `3D` toggle is enabled, 3D scale (x, y, z) is supported.")]
[SerializeField]
private Vector3 m_Scale3D = new Vector3(10, 10, 10);
private Vector3 m_Scale3D = new Vector3(1, 1, 1);
[Tooltip("If you want to update material properties (e.g. _MainTex_ST, _Color) in AnimationClip, " +
"use this to mark as animatable.")]
@@ -122,23 +120,47 @@ namespace Coffee.UIExtensions
private float m_CustomViewSize = 10;
[SerializeField]
[Tooltip("Time scale multiplier.")]
private float m_TimeScaleMultiplier = 1;
private bool m_Maskable = true;
private readonly List<UIParticleRenderer> _renderers = new List<UIParticleRenderer>();
private Camera _bakeCamera;
private Canvas _canvas;
private int _groupId;
private bool _isScaleStored;
private Vector3 _storedScale;
private DrivenRectTransformTracker _tracker;
/// <summary>
/// Should this graphic be considered a target for ray-casting?
/// </summary>
public override bool raycastTarget
public RectTransform rectTransform => transform as RectTransform;
public Canvas canvas
{
get => false;
set { }
get
{
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>
@@ -263,15 +285,6 @@ namespace Coffee.UIExtensions
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 isPrimary =>
@@ -324,15 +337,15 @@ namespace Coffee.UIExtensions
public Vector3 parentScale { get; private set; }
public Vector3 canvasScale { get; private set; }
private Vector3 canvasScale { get; set; }
protected override void OnEnable()
{
_isScaleStored = false;
ResetGroupId();
UIParticleUpdater.Register(this);
RegisterDirtyMaterialCallback(UpdateRendererMaterial);
//
if (0 < particles.Count)
{
RefreshParticles(particles);
@@ -342,7 +355,7 @@ namespace Coffee.UIExtensions
RefreshParticles();
}
base.OnEnable();
UpdateRendererMaterial();
}
/// <summary>
@@ -358,11 +371,16 @@ namespace Coffee.UIExtensions
_isScaleStored = false;
UIParticleUpdater.Unregister(this);
_renderers.RemoveAll(r => r == null);
_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>
@@ -372,6 +390,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()
{
}
@@ -472,7 +498,7 @@ namespace Coffee.UIExtensions
for (var i = 0; i < _renderers.Count; i++)
{
var r = _renderers[i];
if (r == null || r.material == null) continue;
if (!r || !r.material) continue;
result.Add(r.material);
}
}
@@ -490,7 +516,7 @@ namespace Coffee.UIExtensions
/// </summary>
public void SetParticleSystemInstance(GameObject instance, bool destroyOldParticles)
{
if (instance == null) return;
if (!instance) return;
var childCount = transform.childCount;
for (var i = 0; i < childCount; i++)
@@ -519,7 +545,7 @@ namespace Coffee.UIExtensions
/// </summary>
public void SetParticleSystemPrefab(GameObject prefab)
{
if (prefab == null) return;
if (!prefab) return;
SetParticleSystemInstance(Instantiate(prefab.gameObject), true);
}
@@ -539,14 +565,12 @@ namespace Coffee.UIExtensions
/// </summary>
private void RefreshParticles(GameObject root)
{
if (root == null) return;
if (!root) return;
root.GetComponentsInChildren(true, particles);
for (var i = particles.Count - 1; 0 <= i; i--)
{
var ps = particles[i];
if (!ps
|| ps.gameObject.CompareTag("EditorOnly") // Ignore "EditorOnly" tagged ParticleSystems.
|| ps.GetComponentInParent<UIParticle>(true) != this) // Ignore ParticleSystems that are not under this UIParticle.
if (!ps || ps.GetComponentInParent<UIParticle>(true) != this)
{
particles.RemoveAt(i);
}
@@ -594,7 +618,7 @@ namespace Coffee.UIExtensions
for (var i = 0; i < particleSystems.Count; i++)
{
var ps = particleSystems[i];
if (ps == null) continue;
if (!ps) continue;
var mainEmitter = ps.GetMainEmitter(particleSystems);
GetRenderer(j++).Set(this, ps, false, mainEmitter);
@@ -645,7 +669,7 @@ namespace Coffee.UIExtensions
for (var i = 0; i < _renderers.Count; i++)
{
var r = _renderers[i];
if (r != null) continue;
if (r) continue;
RefreshParticles(particles);
break;
@@ -655,7 +679,7 @@ namespace Coffee.UIExtensions
for (var i = 0; i < _renderers.Count; i++)
{
var r = _renderers[i];
if (r == null) continue;
if (!r) continue;
r.UpdateMesh(bakeCamera);
}
@@ -668,23 +692,12 @@ namespace Coffee.UIExtensions
: 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()
{
for (var i = 0; i < _renderers.Count; i++)
{
var r = _renderers[i];
if (r == null) continue;
if (!r) continue;
r.maskable = maskable;
r.SetMaterialDirty();
}
@@ -697,7 +710,7 @@ namespace Coffee.UIExtensions
_renderers.Add(UIParticleRenderer.AddRenderer(this, index));
}
if (_renderers[index] == null)
if (!_renderers[index])
{
_renderers[index] = UIParticleRenderer.AddRenderer(this, index);
}
@@ -707,13 +720,13 @@ namespace Coffee.UIExtensions
private Camera GetBakeCamera()
{
if (canvas == null) return Camera.main;
if (!canvas) return Camera.main;
if (!useCustomView && canvas.renderMode != RenderMode.ScreenSpaceOverlay && canvas.rootCanvas.worldCamera)
{
return canvas.rootCanvas.worldCamera;
}
if (_bakeCamera != null)
if (_bakeCamera)
{
_bakeCamera.orthographicSize = useCustomView ? customViewSize : 10;
return _bakeCamera;
@@ -732,7 +745,7 @@ namespace Coffee.UIExtensions
}
// Create baking camera.
if (_bakeCamera == null)
if (!_bakeCamera)
{
var go = new GameObject("[generated] UIParticle BakingCamera");
go.SetActive(false);

View File

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

View File

@@ -208,7 +208,7 @@ namespace Coffee.UIExtensions
private Vector3 GetDestinationPosition(UIParticle uiParticle, ParticleSystem particleSystem)
{
var isUI = uiParticle != null && uiParticle.enabled;
var isUI = uiParticle && uiParticle.enabled;
var psPos = particleSystem.transform.position;
var attractorPos = transform.position;
var dstPos = attractorPos;

View File

@@ -15,7 +15,6 @@ using UnityEngine.UI;
namespace Coffee.UIExtensions
{
[Icon("Packages/com.coffee.ui-particle/Editor/UIParticleIcon.png")]
[ExecuteAlways]
[RequireComponent(typeof(RectTransform))]
[RequireComponent(typeof(CanvasRenderer))]
@@ -30,7 +29,6 @@ namespace Coffee.UIExtensions
private int _index;
private bool _isPrevStored;
private bool _isTrail;
private bool _meshCleared;
private Bounds _lastBounds;
private Material _materialForRendering;
private Material _modifiedMaterial;
@@ -56,7 +54,7 @@ namespace Coffee.UIExtensions
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[3] = transform.TransformPoint(_lastBounds.max.x, _lastBounds.min.y, 0);
if (canvas != null)
if (canvas)
{
var worldToLocalMatrix = canvas.rootCanvas.transform.worldToLocalMatrix;
for (var i = 0; i < 4; ++i)
@@ -96,7 +94,7 @@ namespace Coffee.UIExtensions
{
get
{
if (_materialForRendering == null)
if (!_materialForRendering)
{
_materialForRendering = base.materialForRendering;
}
@@ -107,7 +105,7 @@ namespace Coffee.UIExtensions
public void Reset(int index = -1)
{
if (_renderer != null)
if (_renderer)
{
_renderer.enabled = true;
}
@@ -122,7 +120,7 @@ namespace Coffee.UIExtensions
}
//_emitter = null;
if (isActiveAndEnabled)
if (this && isActiveAndEnabled)
{
material = null;
canvasRenderer.Clear();
@@ -141,7 +139,7 @@ namespace Coffee.UIExtensions
base.OnEnable();
hideFlags = UIParticleProjectSettings.globalHideFlags;
if (s_CombineInstances[0].mesh == null)
if (!s_CombineInstances[0].mesh)
{
s_CombineInstances[0].mesh = new Mesh
{
@@ -206,9 +204,9 @@ namespace Coffee.UIExtensions
}
var hash = new Hash128(
modifiedMaterial ? (uint)modifiedMaterial.GetHashCode() : 0,
texture ? (uint)texture.GetHashCode() : 0,
0 < _parent.m_AnimatableProperties.Length ? (uint)GetHashCode() : 0,
modifiedMaterial ? (uint)modifiedMaterial.GetInstanceID() : 0,
texture ? (uint)texture.GetInstanceID() : 0,
0 < _parent.m_AnimatableProperties.Length ? (uint)GetInstanceID() : 0,
#if UNITY_EDITOR
(uint)EditorJsonUtility.ToJson(modifiedMaterial).GetHashCode()
#else
@@ -284,40 +282,21 @@ namespace Coffee.UIExtensions
|| !transform.lossyScale.GetScaled(_parent.scale3DForCalc).IsVisible() // Scale is not visible.
|| (!_particleSystem.IsAlive() && !_particleSystem.isPlaying) // No particle.
|| (_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
)
{
// Skip clearing the mesh if it's already cleared.
if (_meshCleared) return;
Profiler.BeginSample("[UIParticleRenderer] Clear Mesh");
workerMesh.Clear();
canvasRenderer.SetMesh(workerMesh);
_lastBounds = new Bounds();
_meshCleared = true;
Profiler.EndSample();
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);
// }
_meshCleared = false;
var main = _particleSystem.main;
var scale = GetWorldScale();
var psPos = _particleSystem.transform.position;
@@ -335,13 +314,6 @@ namespace Coffee.UIExtensions
#endif
{
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);
if (_delay && !_parent.isPaused)
@@ -656,7 +628,6 @@ namespace Coffee.UIExtensions
: main.useUnscaledTime
? Time.unscaledDeltaTime
: Time.deltaTime;
deltaTime *= _parent.timeScaleMultiplier;
// Pre-warm:
if (0 < deltaTime && _preWarm)
@@ -737,7 +708,7 @@ namespace Coffee.UIExtensions
if (s_Mpb.isEmpty) return;
// #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++)
{

View File

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

View File

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

View File

@@ -13,7 +13,11 @@ namespace Coffee.UIParticleInternal
{
if (s_TmpParticles.Length < size)
{
size = Mathf.NextPowerOfTwo(size);
while (s_TmpParticles.Length < size)
{
size = Mathf.NextPowerOfTwo(size);
}
s_TmpParticles = new ParticleSystem.Particle[size];
}
@@ -84,15 +88,15 @@ namespace Coffee.UIParticleInternal
var bRenderer = b.GetComponent<ParticleSystemRenderer>();
// Render queue: ascending
var aMat = aRenderer.sharedMaterial != null ? aRenderer.sharedMaterial : aRenderer.trailMaterial;
var bMat = bRenderer.sharedMaterial != null ? bRenderer.sharedMaterial : bRenderer.trailMaterial;
if (aMat == null && bMat == null) return 0;
if (aMat == null) return -1;
if (bMat == null) return 1;
var aMat = aRenderer.sharedMaterial ? aRenderer.sharedMaterial : aRenderer.trailMaterial;
var bMat = bRenderer.sharedMaterial ? bRenderer.sharedMaterial : bRenderer.trailMaterial;
if (!aMat && !bMat) return 0;
if (!aMat) return -1;
if (!bMat) return 1;
if (sortByMaterial)
{
return aMat.GetHashCode() - bMat.GetHashCode();
return aMat.GetInstanceID() - bMat.GetInstanceID();
}
if (aMat.renderQueue != bMat.renderQueue)
@@ -131,7 +135,7 @@ namespace Coffee.UIParticleInternal
{
for (var i = 0; i < list.Count; i++)
{
if (list[i].GetHashCode() == ps.GetHashCode())
if (list[i].GetInstanceID() == ps.GetInstanceID())
{
return i;
}
@@ -142,7 +146,7 @@ namespace Coffee.UIParticleInternal
public static Texture2D GetTextureForSprite(this ParticleSystem self)
{
if (self == null) return null;
if (!self) return null;
// Get sprite's texture.
var tsaModule = self.textureSheetAnimation;
@@ -151,7 +155,7 @@ namespace Coffee.UIParticleInternal
for (var i = 0; i < tsaModule.spriteCount; i++)
{
var sprite = tsaModule.GetSprite(i);
if (sprite == null) continue;
if (!sprite) continue;
return sprite.GetActualTexture();
}
@@ -163,14 +167,14 @@ namespace Coffee.UIParticleInternal
{
foreach (var p in self)
{
if (p == null) continue;
if (!p) continue;
action.Invoke(p);
}
}
public static ParticleSystem GetMainEmitter(this ParticleSystem self, List<ParticleSystem> list)
{
if (self == null || list == null || list.Count == 0) return null;
if (!self || list == null || list.Count == 0) return null;
for (var i = 0; i < list.Count; i++)
{
@@ -183,11 +187,7 @@ namespace Coffee.UIParticleInternal
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++)
{

View File

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

View File

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

View File

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