You've already forked ParticleEffectForUGUI
mirror of
https://github.com/mob-sakai/ParticleEffectForUGUI.git
synced 2026-05-15 04:30:09 +00:00
Compare commits
3 Commits
v5.0.0-pre
...
asset_upda
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
36ab069eba | ||
|
|
66c76fb92b | ||
|
|
b3a49514b5 |
53
.github/workflows/release.yml
vendored
53
.github/workflows/release.yml
vendored
@@ -4,9 +4,8 @@ on:
|
|||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
|
- preview
|
||||||
- release
|
- release
|
||||||
- release-preview
|
|
||||||
- release-v4
|
|
||||||
tags-ignore:
|
tags-ignore:
|
||||||
- "**"
|
- "**"
|
||||||
|
|
||||||
@@ -23,8 +22,7 @@ jobs:
|
|||||||
released: ${{ steps.release.outputs.new_release_published }}
|
released: ${{ steps.release.outputs.new_release_published }}
|
||||||
tag: ${{ steps.release.outputs.new_release_git_tag }}
|
tag: ${{ steps.release.outputs.new_release_git_tag }}
|
||||||
version: ${{ steps.release.outputs.new_release_version }}
|
version: ${{ steps.release.outputs.new_release_version }}
|
||||||
merge_to: ${{ steps.summary.outputs.merge_to }}
|
notes: ${{ steps.release.outputs.new_release_notes }}
|
||||||
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@v4
|
||||||
@@ -40,51 +38,37 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ github.token }}
|
GITHUB_TOKEN: ${{ github.token }}
|
||||||
|
|
||||||
- id: summary
|
- run: |
|
||||||
run: |
|
|
||||||
echo "🔖 New release published: '${{ steps.release.outputs.new_release_published }}'" | tee -a $GITHUB_STEP_SUMMARY
|
echo "🔖 New release published: '${{ steps.release.outputs.new_release_published }}'" | tee -a $GITHUB_STEP_SUMMARY
|
||||||
echo "🔖 New release version: '${{ steps.release.outputs.new_release_version }}'" | tee -a $GITHUB_STEP_SUMMARY
|
echo "🔖 New release version: '${{ steps.release.outputs.new_release_version }}'" | tee -a $GITHUB_STEP_SUMMARY
|
||||||
echo "🔖 New release channel: '${{ steps.release.outputs.new_release_channel }}'" | tee -a $GITHUB_STEP_SUMMARY
|
echo "🔖 New release channel: '${{ steps.release.outputs.new_release_channel }}'" | tee -a $GITHUB_STEP_SUMMARY
|
||||||
echo "🔖 New release git tag: '${{ steps.release.outputs.new_release_git_tag }}'" | tee -a $GITHUB_STEP_SUMMARY
|
echo "🔖 New release git tag: '${{ steps.release.outputs.new_release_git_tag }}'" | tee -a $GITHUB_STEP_SUMMARY
|
||||||
|
|
||||||
if [ '${{ steps.release.outputs.new_release_published }}' = 'false' ]; then
|
|
||||||
echo "No new release published." | tee -a $GITHUB_STEP_SUMMARY
|
|
||||||
elif [ '${{ github.ref_name }}' = 'release' ]; then
|
|
||||||
echo "merge_to=develop" | tee -a $GITHUB_OUTPUT
|
|
||||||
echo "split_to=main" | tee -a $GITHUB_OUTPUT
|
|
||||||
elif [ '${{ github.ref_name }}' = 'release-preview' ]; then
|
|
||||||
echo "merge_to=develop-preview" | tee -a $GITHUB_OUTPUT
|
|
||||||
echo "split_to=preview" | tee -a $GITHUB_OUTPUT
|
|
||||||
elif [ '${{ github.ref_name }}' = 'release-4.x' ]; then
|
|
||||||
echo "merge_to=develop-4.x" | tee -a $GITHUB_OUTPUT
|
|
||||||
echo "split_to=4.x" | tee -a $GITHUB_OUTPUT
|
|
||||||
fi
|
|
||||||
|
|
||||||
merge-to:
|
merge-to-develop:
|
||||||
if: needs.release.outputs.merge_to != ''
|
if: needs.release.outputs.released == 'true'
|
||||||
needs: release
|
needs: release
|
||||||
name: 🔀 Merge to ${{ needs.release.outputs.merge_to }}
|
name: 🔀 Merge to develop
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
permissions:
|
permissions:
|
||||||
contents: write
|
contents: write
|
||||||
steps:
|
steps:
|
||||||
- name: 🚚 Checkout (${{ needs.release.outputs.merge_to }})
|
- name: 🚚 Checkout (develop)
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
ref: ${{ needs.release.outputs.merge_to }}
|
ref: develop
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- name: 🔀 Merge '${{ needs.release.outputs.tag }}' into '${{ needs.release.outputs.merge_to }}'
|
- name: 🔀 Merge '${{ needs.release.outputs.tag }}' into 'develop'
|
||||||
run: |
|
run: |
|
||||||
git config --local user.email "github-actions[bot]@users.noreply.github.com"
|
git config --local user.email "github-actions[bot]@users.noreply.github.com"
|
||||||
git config --local user.name "github-actions[bot]"
|
git config --local user.name "github-actions[bot]"
|
||||||
|
|
||||||
git merge ${{ needs.release.outputs.tag }}
|
git merge ${{ needs.release.outputs.tag }}
|
||||||
git push origin ${{ needs.release.outputs.merge_to }}
|
git push origin develop
|
||||||
|
|
||||||
split-to:
|
split-to-main:
|
||||||
if: needs.release.outputs.split_to != ''
|
if: needs.release.outputs.released == 'true'
|
||||||
needs: release
|
needs: release
|
||||||
name: 🔀 Split package to ${{ needs.release.outputs.split_to }}
|
name: 🔀 Split package
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
permissions:
|
permissions:
|
||||||
contents: write
|
contents: write
|
||||||
@@ -94,10 +78,9 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
ref: ${{ needs.release.outputs.tag }}
|
ref: ${{ needs.release.outputs.tag }}
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- name: 🔀 Split subtree 'Packages/src' to '${{ needs.release.outputs.split_to }}'
|
- name: 🔀 Split subtree 'Packages/src' to 'main'
|
||||||
run: |
|
run: |
|
||||||
split_to=${{ needs.release.outputs.split_to }}
|
git branch main origin/main
|
||||||
git branch $split_to origin/$split_to
|
git subtree split --prefix=Packages/src --branch main
|
||||||
git subtree split --prefix=Packages/src --branch $split_to
|
git tag ${{ needs.release.outputs.version }} main
|
||||||
git tag ${{ needs.release.outputs.version }} $split_to
|
git push origin ${{ needs.release.outputs.version }} main:main
|
||||||
git push origin ${{ needs.release.outputs.version }} $split_to:$split_to
|
|
||||||
|
|||||||
3
.github/workflows/test.yml
vendored
3
.github/workflows/test.yml
vendored
@@ -15,8 +15,7 @@ on:
|
|||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- develop
|
- develop
|
||||||
- develop-preview
|
- develop_v5
|
||||||
- develop-4.x
|
|
||||||
tags:
|
tags:
|
||||||
- "!*"
|
- "!*"
|
||||||
paths-ignore:
|
paths-ignore:
|
||||||
|
|||||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -28,4 +28,3 @@ Assets/Plugins/
|
|||||||
obj/
|
obj/
|
||||||
bin/
|
bin/
|
||||||
UserSettings/
|
UserSettings/
|
||||||
*.app
|
|
||||||
|
|||||||
@@ -1,15 +0,0 @@
|
|||||||
%YAML 1.1
|
|
||||||
%TAG !u! tag:unity3d.com,2011:
|
|
||||||
--- !u!114 &11400000
|
|
||||||
MonoBehaviour:
|
|
||||||
m_ObjectHideFlags: 0
|
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
|
||||||
m_PrefabInstance: {fileID: 0}
|
|
||||||
m_PrefabAsset: {fileID: 0}
|
|
||||||
m_GameObject: {fileID: 0}
|
|
||||||
m_Enabled: 1
|
|
||||||
m_EditorHideFlags: 0
|
|
||||||
m_Script: {fileID: 11500000, guid: f22a23b9d98e440478697f4adf30e61c, type: 3}
|
|
||||||
m_Name: UIParticle
|
|
||||||
m_EditorClassIdentifier:
|
|
||||||
m_LinearToGamma: 1
|
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
"depth": 0,
|
"depth": 0,
|
||||||
"source": "git",
|
"source": "git",
|
||||||
"dependencies": {},
|
"dependencies": {},
|
||||||
"hash": "4a57c0a498ba7ce667290ec39510b1474030471a"
|
"hash": "41a1b604af8769b600d9c75db02ff35ec30611dc"
|
||||||
},
|
},
|
||||||
"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 +14,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"com.unity.ugui": "1.0.0"
|
"com.unity.ugui": "1.0.0"
|
||||||
},
|
},
|
||||||
"hash": "4a57c0a498ba7ce667290ec39510b1474030471a"
|
"hash": "41a1b604af8769b600d9c75db02ff35ec30611dc"
|
||||||
},
|
},
|
||||||
"com.coffee.simple-scene-navigator": {
|
"com.coffee.simple-scene-navigator": {
|
||||||
"version": "https://github.com/mob-sakai/Coffee.Internal.git?path=Packages/SceneNavigator",
|
"version": "https://github.com/mob-sakai/Coffee.Internal.git?path=Packages/SceneNavigator",
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"com.unity.ugui": "1.0.0"
|
"com.unity.ugui": "1.0.0"
|
||||||
},
|
},
|
||||||
"hash": "4a57c0a498ba7ce667290ec39510b1474030471a"
|
"hash": "41a1b604af8769b600d9c75db02ff35ec30611dc"
|
||||||
},
|
},
|
||||||
"com.coffee.sub-asset-editor": {
|
"com.coffee.sub-asset-editor": {
|
||||||
"version": "https://github.com/mob-sakai/SubAssetEditor.git",
|
"version": "https://github.com/mob-sakai/SubAssetEditor.git",
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
{
|
{
|
||||||
"branches": [
|
"branches": [
|
||||||
"release",
|
"release",
|
||||||
"release-4.x",
|
|
||||||
{
|
{
|
||||||
"name": "release-preview",
|
"name": "preview",
|
||||||
"prerelease": "preview"
|
"prerelease": true
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"plugins": [
|
"plugins": [
|
||||||
|
|||||||
@@ -1,57 +1,3 @@
|
|||||||
# [5.0.0-preview.3](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v5.0.0-preview.2...v5.0.0-preview.3) (2024-06-21)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* generated baking-camera object remains in the prefab or scene ([fd66928](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/fd66928efe584aeb4f6347b9a9dca97d9512eb88))
|
|
||||||
|
|
||||||
# [5.0.0-preview.2](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v5.0.0-preview.1...v5.0.0-preview.2) (2024-06-20)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* 'Resource ID out of range in GetResource' error in overlay rendering mode ([ff78b6f](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/ff78b6fe32ceed8ddad50e63dcb7a202eab95266)), closes [#308](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/308)
|
|
||||||
* `UIParticle.transform.localScale` does not scale particles ([491ee7b](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/491ee7b0c3e528e1e577ae5ff2588d7c3bd8ecdb)), closes [#313](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/313)
|
|
||||||
* despite not using the size module, particles become smaller based on their z position ([c96ddf2](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/c96ddf293e855f7ebccaaaf3b112092955545e61)), closes [#316](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/316)
|
|
||||||
* the ParticleSystem's localPosition drifts at certain scales due to floating-point precision issues ([a9c2b19](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/a9c2b19edf00e1c86c928ef23405906952ede852)), closes [#299](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/299) [#312](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/312)
|
|
||||||
* UIParticle is scaled by canvas size even when `AutoScalingMode.None` and `ScalingMode.Local` ([63b24d8](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/63b24d8a8b478b3165733ece3eec524e88b28855)), closes [#313](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/313)
|
|
||||||
* UIParticle is scaled incorrectly with nested canvases ([c95d8c6](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/c95d8c6b1774396ff252d13121ad32a3cab0fe5c)), closes [#313](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/313)
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* remove overlay window (editor) ([fc3fbdd](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/fc3fbdd230595ad3471875ec6fec384a3dad0d17))
|
|
||||||
* reset previous position on start play for world space simulation ([e741584](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/e7415845074143abae23e3ae7eedc767a01d020d)), closes [#303](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/303)
|
|
||||||
* restore `Transform.localScale` when setting `autoScalingMode` to something other than `Transform` ([dfb94f4](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/dfb94f4badfb3035a4374579c53293460b4fd946))
|
|
||||||
|
|
||||||
# [5.0.0-preview.1](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.6.6...v5.0.0-preview.1) (2024-05-23)
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* add project settings for UIParticle ([b6e6185](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/b6e6185c521fef0f118f61cfdfdac07b87555c01))
|
|
||||||
* change the default value of `UIParticle.scale` from `10` to `1` ([1b3c0f9](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/1b3c0f92dcc6a1974d1ea074821e5264200e9711)), closes [#310](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/310)
|
|
||||||
* UIParticle no longer inherits from MaskableGraphic ([b6d921b](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/b6d921b3e47f749b5028d22b0e89b6eb3a1af7de))
|
|
||||||
|
|
||||||
|
|
||||||
### BREAKING CHANGES
|
|
||||||
|
|
||||||
* Some members inherited from MaskableGraphic will no longer be available.
|
|
||||||
|
|
||||||
## [4.6.6](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.6.5...v4.6.6) (2024-05-23)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* fix release workflow ([30b0076](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/30b00762f6da166c043587798b1552f27b4cc604))
|
|
||||||
|
|
||||||
## [4.6.5](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.6.4...v4.6.5) (2024-05-23)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* update workflows (for preview and v4) ([3eab097](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/3eab0979b9b85919b804442ab05735b7120eade5))
|
|
||||||
|
|
||||||
## [4.6.4](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.6.3...v4.6.4) (2024-05-22)
|
## [4.6.4](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.6.3...v4.6.4) (2024-05-22)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
3
Packages/src/Editor/AssetModification.meta
Normal file
3
Packages/src/Editor/AssetModification.meta
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 1006234332be4f329fc1830319b31aaa
|
||||||
|
timeCreated: 1704502465
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
using Coffee.UIExtensions;
|
||||||
|
using Coffee.UIParticleInternal.AssetModification;
|
||||||
|
using UnityEditor;
|
||||||
|
|
||||||
|
#pragma warning disable CS0612 // Type or member is obsolete
|
||||||
|
|
||||||
|
namespace Coffee.UIParticleInternal
|
||||||
|
{
|
||||||
|
internal class UIParticleComponentModifier_AbsoluteMode : ComponentModifier<UIParticle>
|
||||||
|
{
|
||||||
|
protected override bool ModifyComponent(UIParticle uip, bool dryRun)
|
||||||
|
{
|
||||||
|
if (!uip.m_AbsoluteMode) return false;
|
||||||
|
|
||||||
|
uip.m_AbsoluteMode = false;
|
||||||
|
uip.positionMode = UIParticle.PositionMode.Absolute;
|
||||||
|
|
||||||
|
if (!dryRun)
|
||||||
|
{
|
||||||
|
EditorUtility.SetDirty(uip);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string Report()
|
||||||
|
{
|
||||||
|
return " -> UIParticle.absoluteMode is obsolete. Use UIParticle.positionMode instead.\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: f22a23b9d98e440478697f4adf30e61c
|
guid: d3378b5e701274218b04cb5588b8a3bd
|
||||||
MonoImporter:
|
MonoImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
using Coffee.UIExtensions;
|
||||||
|
using Coffee.UIParticleInternal.AssetModification;
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
#pragma warning disable CS0612 // Type or member is obsolete
|
||||||
|
|
||||||
|
namespace Coffee.UIParticleInternal
|
||||||
|
{
|
||||||
|
internal class UIParticleComponentModifier_AutoScaling : ComponentModifier<UIParticle>
|
||||||
|
{
|
||||||
|
protected override bool ModifyComponent(UIParticle uip, bool dryRun)
|
||||||
|
{
|
||||||
|
if (!uip.m_AutoScaling) return false;
|
||||||
|
|
||||||
|
uip.m_AutoScaling = false;
|
||||||
|
uip.autoScalingMode = UIParticle.AutoScalingMode.Transform;
|
||||||
|
uip.transform.localScale = Vector3.one;
|
||||||
|
|
||||||
|
if (!dryRun)
|
||||||
|
{
|
||||||
|
EditorUtility.SetDirty(uip);
|
||||||
|
EditorUtility.SetDirty(uip.transform);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string Report()
|
||||||
|
{
|
||||||
|
return
|
||||||
|
" -> UIParticle.ignoreCanvasScaler and UIParticle.autoScaling are obsolete." +
|
||||||
|
" Use UIParticle.autoScalingMode instead.\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 3d6d0ca7ae8c641aa98b66fd91c05264
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
using Coffee.UIExtensions;
|
||||||
|
using Coffee.UIParticleInternal.AssetModification;
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
#pragma warning disable CS0612 // Type or member is obsolete
|
||||||
|
|
||||||
|
namespace Coffee.UIParticleInternal
|
||||||
|
{
|
||||||
|
internal class UIParticleComponentModifier_IsTrail : ComponentModifier<UIParticle>
|
||||||
|
{
|
||||||
|
protected override bool ModifyComponent(UIParticle uip, bool dryRun)
|
||||||
|
{
|
||||||
|
if (!uip.m_IsTrail) return false;
|
||||||
|
|
||||||
|
if (!dryRun)
|
||||||
|
{
|
||||||
|
var go = uip.gameObject;
|
||||||
|
Object.DestroyImmediate(uip);
|
||||||
|
EditorUtility.SetDirty(go);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string Report()
|
||||||
|
{
|
||||||
|
return " -> UIParticle for trail is no longer needed. Removed.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: dfbc9e244a2a040179e7f5b58ec0b978
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Coffee.UIParticleInternal.AssetModification;
|
||||||
|
using UnityEditor;
|
||||||
|
|
||||||
|
namespace Coffee.UIParticleInternal
|
||||||
|
{
|
||||||
|
internal class UIParticleModifierRunner : Runner
|
||||||
|
{
|
||||||
|
public UIParticleModifierRunner()
|
||||||
|
: base("UIParticle v5", new List<(string, Func<string, Modifier>)>
|
||||||
|
{
|
||||||
|
(".unity", x => new SceneModifier
|
||||||
|
{
|
||||||
|
path = x,
|
||||||
|
componentModifiers = new IComponentModifier[]
|
||||||
|
{
|
||||||
|
new UIParticleRendererComponentModifier(),
|
||||||
|
new UIParticleComponentModifier_AutoScaling(),
|
||||||
|
new UIParticleComponentModifier_AbsoluteMode(),
|
||||||
|
new UIParticleComponentModifier_IsTrail()
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
(".prefab", x => new PrefabModifier
|
||||||
|
{
|
||||||
|
path = x,
|
||||||
|
componentModifiers = new IComponentModifier[]
|
||||||
|
{
|
||||||
|
new UIParticleRendererComponentModifier(),
|
||||||
|
new UIParticleComponentModifier_AutoScaling(),
|
||||||
|
new UIParticleComponentModifier_AbsoluteMode(),
|
||||||
|
new UIParticleComponentModifier_IsTrail()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
[MenuItem("UIParticleModifierRunner/Run")]
|
||||||
|
private static void Run()
|
||||||
|
{
|
||||||
|
new UIParticleModifierRunner().RunIfUserWantsTo();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: edd678db452e49869caeca7e7d269e5d
|
||||||
|
timeCreated: 1704502476
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
using Coffee.UIExtensions;
|
||||||
|
using Coffee.UIParticleInternal.AssetModification;
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Coffee.UIParticleInternal
|
||||||
|
{
|
||||||
|
internal class UIParticleRendererComponentModifier : ComponentModifier<UIParticleRenderer>
|
||||||
|
{
|
||||||
|
protected override bool ModifyComponent(UIParticleRenderer c, bool dryRun)
|
||||||
|
{
|
||||||
|
if (c.hideFlags.HasFlag(HideFlags.DontSave | HideFlags.NotEditable)) return false;
|
||||||
|
|
||||||
|
if (!dryRun)
|
||||||
|
{
|
||||||
|
var go = c.gameObject;
|
||||||
|
Object.DestroyImmediate(c);
|
||||||
|
EditorUtility.SetDirty(go);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string Report()
|
||||||
|
{
|
||||||
|
return " -> UIParticleRenderer component is now auto-generated object. Remove them.\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b2a025408e4a7486a941102775d2c73b
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: e8e7744b163af4869b07b8f192c810ed
|
guid: 269bcefd175184eebbfa31421171fadf
|
||||||
NativeFormatImporter:
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
mainObjectFileID: 11400000
|
|
||||||
userData:
|
userData:
|
||||||
assetBundleName:
|
assetBundleName:
|
||||||
assetBundleVariant:
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Coffee.UIParticleInternal.AssetModification
|
||||||
|
{
|
||||||
|
internal abstract class ComponentModifier<T> : IComponentModifier where T : Component
|
||||||
|
{
|
||||||
|
private static readonly List<T> s_Components = new List<T>();
|
||||||
|
|
||||||
|
public bool isModified { get; private set; }
|
||||||
|
|
||||||
|
public bool ModifyComponent(GameObject root, bool dryRun)
|
||||||
|
{
|
||||||
|
root.GetComponentsInChildren(true, s_Components);
|
||||||
|
foreach (var c in s_Components)
|
||||||
|
{
|
||||||
|
if (PrefabUtility.IsPartOfAnyPrefab(c.gameObject)) continue;
|
||||||
|
|
||||||
|
if (ModifyComponent(c, dryRun))
|
||||||
|
{
|
||||||
|
isModified = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return isModified;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract string Report();
|
||||||
|
|
||||||
|
protected abstract bool ModifyComponent(T component, bool dryRun);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 338da2d8cec784add924489fc4a7bb01
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Coffee.UIParticleInternal.AssetModification
|
||||||
|
{
|
||||||
|
internal abstract class GameObjectModifier : Modifier
|
||||||
|
{
|
||||||
|
private static readonly StringBuilder s_ReportLog = new StringBuilder();
|
||||||
|
public IComponentModifier[] componentModifiers;
|
||||||
|
|
||||||
|
protected bool ModifyGameObject(GameObject root, bool dryRun)
|
||||||
|
{
|
||||||
|
foreach (var modifier in componentModifiers)
|
||||||
|
{
|
||||||
|
modifier.ModifyComponent(root, dryRun);
|
||||||
|
}
|
||||||
|
|
||||||
|
return componentModifiers.Any(x => x.isModified);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override string ModificationReport()
|
||||||
|
{
|
||||||
|
if (!hasUpgraded) return string.Empty;
|
||||||
|
|
||||||
|
s_ReportLog.Length = 0;
|
||||||
|
foreach (var componentModifier in componentModifiers)
|
||||||
|
{
|
||||||
|
if (componentModifier.isModified)
|
||||||
|
{
|
||||||
|
s_ReportLog.Append(componentModifier.Report());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 < s_ReportLog.Length)
|
||||||
|
{
|
||||||
|
s_ReportLog.Length--;
|
||||||
|
}
|
||||||
|
|
||||||
|
return s_ReportLog.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: f16bc447ca4934ca3b9329d1d870440a
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Coffee.UIParticleInternal.AssetModification
|
||||||
|
{
|
||||||
|
internal interface IComponentModifier
|
||||||
|
{
|
||||||
|
bool isModified { get; }
|
||||||
|
bool ModifyComponent(GameObject root, bool dryRun);
|
||||||
|
string Report();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 1e50323d0799f4daf8ef476f7bf403a4
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Coffee.UIParticleInternal.AssetModification
|
||||||
|
{
|
||||||
|
internal interface ITextModifier
|
||||||
|
{
|
||||||
|
bool ModifyText(StringBuilder sb, string text);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 2ad967b4f039b4deba09ed0c1401cf83
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
41
Packages/src/Editor/Internal/AssetModification/Modifier.cs
Normal file
41
Packages/src/Editor/Internal/AssetModification/Modifier.cs
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Coffee.UIParticleInternal.AssetModification
|
||||||
|
{
|
||||||
|
internal abstract class Modifier
|
||||||
|
{
|
||||||
|
private string _error;
|
||||||
|
public string path;
|
||||||
|
|
||||||
|
protected abstract string id { get; }
|
||||||
|
protected bool hasUpgraded { private set; get; }
|
||||||
|
|
||||||
|
public void Modify(bool dryRun)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
hasUpgraded = RunModify(dryRun);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
_error = e.Message;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetModificationReport()
|
||||||
|
{
|
||||||
|
return !string.IsNullOrEmpty(_error)
|
||||||
|
? $"<b><color=red>[{id} (Error)]</color> {path}</b> {_error}\n"
|
||||||
|
: hasUpgraded
|
||||||
|
? $"<b><color=green>[{id}]</color> {path}</b> {ModificationReport()}\n"
|
||||||
|
: string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract bool RunModify(bool dryRun);
|
||||||
|
|
||||||
|
protected virtual string ModificationReport()
|
||||||
|
{
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: c716fe53d75054d309923c577f5059a4
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
using System;
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Coffee.UIParticleInternal.AssetModification
|
||||||
|
{
|
||||||
|
internal class PrefabModifier : GameObjectModifier
|
||||||
|
{
|
||||||
|
protected override string id => "Prefab";
|
||||||
|
|
||||||
|
protected override bool RunModify(bool dryRun)
|
||||||
|
{
|
||||||
|
using (var scope = new EditScope(path))
|
||||||
|
{
|
||||||
|
var changed = ModifyGameObject(scope.root, dryRun);
|
||||||
|
|
||||||
|
if (!dryRun && changed)
|
||||||
|
{
|
||||||
|
scope.Save();
|
||||||
|
}
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly struct EditScope : IDisposable
|
||||||
|
{
|
||||||
|
private readonly string _path;
|
||||||
|
public readonly GameObject root;
|
||||||
|
|
||||||
|
public EditScope(string path)
|
||||||
|
{
|
||||||
|
_path = path;
|
||||||
|
root = PrefabUtility.LoadPrefabContents(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
PrefabUtility.UnloadPrefabContents(root);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Save()
|
||||||
|
{
|
||||||
|
PrefabUtility.SaveAsPrefabAsset(root, _path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: a50643d4fde75458cae1f0d4ef9549ad
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
97
Packages/src/Editor/Internal/AssetModification/Runner.cs
Normal file
97
Packages/src/Editor/Internal/AssetModification/Runner.cs
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEditor.SceneManagement;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Coffee.UIParticleInternal.AssetModification
|
||||||
|
{
|
||||||
|
internal class Runner
|
||||||
|
{
|
||||||
|
private readonly List<(string ext, Func<string, Modifier> create)> _factory;
|
||||||
|
private readonly string _name;
|
||||||
|
|
||||||
|
protected Runner(string name, List<(string ext, Func<string, Modifier> create)> factory)
|
||||||
|
{
|
||||||
|
_name = name;
|
||||||
|
_factory = factory;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Modifier CreateFromPath(string assetPath)
|
||||||
|
{
|
||||||
|
var ext = Path.GetExtension(assetPath);
|
||||||
|
return _factory
|
||||||
|
.FirstOrDefault(x => x.ext == ext)
|
||||||
|
.create?.Invoke(assetPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Modifier[] GetModifiers(string[] assetPaths)
|
||||||
|
{
|
||||||
|
return assetPaths
|
||||||
|
.Where(x => x.StartsWith("Assets/", StringComparison.Ordinal))
|
||||||
|
.Select(CreateFromPath)
|
||||||
|
.Where(x => x != null)
|
||||||
|
.OrderBy(x => Path.GetExtension(x.path))
|
||||||
|
.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RunIfUserWantsTo()
|
||||||
|
{
|
||||||
|
var select = EditorUtility.DisplayDialogComplex($"Upgrade {_name}",
|
||||||
|
"Upgrade all assets in this project?\n\n" +
|
||||||
|
"'Go Ahead': Upgrades all assets in this project using the old APIs. You should make a backup before proceeding.\n\n" +
|
||||||
|
"'Dry Run': Outputs the upgrade summary to the console without changing.", "I Made a Backup. Go Ahead!",
|
||||||
|
"No Thanks", "Dry Run");
|
||||||
|
if (select == 1) return;
|
||||||
|
|
||||||
|
if (!EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo()) return;
|
||||||
|
|
||||||
|
var assetPaths = AssetDatabase.GetAllAssetPaths();
|
||||||
|
var dryRun = select == 2;
|
||||||
|
Run(assetPaths, dryRun);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Run(string[] assetPaths, bool dryRun)
|
||||||
|
{
|
||||||
|
var modifiers = GetModifiers(assetPaths);
|
||||||
|
var canceled = false;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
AssetDatabase.StartAssetEditing();
|
||||||
|
EditorSceneManager.NewScene(NewSceneSetup.EmptyScene, NewSceneMode.Single);
|
||||||
|
|
||||||
|
for (var i = 0; i < modifiers.Length; i++)
|
||||||
|
{
|
||||||
|
var percentage = (float)i / modifiers.Length;
|
||||||
|
var m = modifiers[i];
|
||||||
|
if (EditorUtility.DisplayCancelableProgressBar("Upgrading...", m.path, percentage))
|
||||||
|
{
|
||||||
|
canceled = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
m.Modify(dryRun);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.LogException(e);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
sb.Append(dryRun ? "<b>[DryRun]</b> " : "");
|
||||||
|
sb.AppendLine($"<b>Modify '{_name}' is {(canceled ? "canceled" : "completed")}.</b>");
|
||||||
|
sb.AppendLine("==== Modifications ====");
|
||||||
|
Debug.Log(modifiers.Aggregate(sb, (x, m) => x.Append(m.GetModificationReport())));
|
||||||
|
EditorUtility.ClearProgressBar();
|
||||||
|
AssetDatabase.StopAssetEditing();
|
||||||
|
AssetDatabase.Refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: f28067cf4bfca4d92bd5262ac5c7a652
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
using System;
|
||||||
|
using UnityEditor.SceneManagement;
|
||||||
|
using UnityEngine.SceneManagement;
|
||||||
|
|
||||||
|
namespace Coffee.UIParticleInternal.AssetModification
|
||||||
|
{
|
||||||
|
internal class SceneModifier : GameObjectModifier
|
||||||
|
{
|
||||||
|
protected override string id => "Scene";
|
||||||
|
|
||||||
|
protected override bool RunModify(bool dryRun)
|
||||||
|
{
|
||||||
|
using (var scope = new EditScope(path))
|
||||||
|
{
|
||||||
|
var changed = false;
|
||||||
|
foreach (var root in scope.scene.GetRootGameObjects())
|
||||||
|
{
|
||||||
|
if (ModifyGameObject(root, dryRun))
|
||||||
|
{
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!dryRun && changed)
|
||||||
|
{
|
||||||
|
scope.Save();
|
||||||
|
}
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly struct EditScope : IDisposable
|
||||||
|
{
|
||||||
|
public readonly Scene scene;
|
||||||
|
|
||||||
|
public EditScope(string path)
|
||||||
|
{
|
||||||
|
scene = EditorSceneManager.OpenScene(path, OpenSceneMode.Additive);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
EditorSceneManager.CloseScene(scene, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Save()
|
||||||
|
{
|
||||||
|
EditorSceneManager.SaveScene(scene);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 6764c0c6fd61a4f66a8b0e3467be420d
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Coffee.UIParticleInternal.AssetModification
|
||||||
|
{
|
||||||
|
internal class TextAssetModifier : Modifier
|
||||||
|
{
|
||||||
|
public ITextModifier[] textModifiers;
|
||||||
|
protected override string id => "Text";
|
||||||
|
protected virtual string savePath => path;
|
||||||
|
|
||||||
|
protected override bool RunModify(bool dryRun)
|
||||||
|
{
|
||||||
|
var changed = false;
|
||||||
|
using (var scope = new EditScope(path, savePath))
|
||||||
|
{
|
||||||
|
foreach (var line in scope.lines)
|
||||||
|
{
|
||||||
|
if (ModifyLine(scope.sb, line))
|
||||||
|
{
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
scope.sb.AppendLine(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!dryRun && changed)
|
||||||
|
{
|
||||||
|
scope.Save();
|
||||||
|
}
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool ModifyLine(StringBuilder sb, string line)
|
||||||
|
{
|
||||||
|
foreach (var modifier in textModifiers)
|
||||||
|
{
|
||||||
|
if (modifier.ModifyText(sb, line))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly struct EditScope : IDisposable
|
||||||
|
{
|
||||||
|
private static readonly StringBuilder s_File = new StringBuilder();
|
||||||
|
private readonly string _path;
|
||||||
|
private readonly string _savePath;
|
||||||
|
public IEnumerable<string> lines => File.ReadLines(_path);
|
||||||
|
public StringBuilder sb => s_File;
|
||||||
|
|
||||||
|
public EditScope(string path, string savePath)
|
||||||
|
{
|
||||||
|
s_File.Length = 0;
|
||||||
|
_path = path;
|
||||||
|
_savePath = savePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Save()
|
||||||
|
{
|
||||||
|
File.WriteAllText(_savePath, sb.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 431e5b95f2f5c4f19926a7fc5342e118
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
|
namespace Coffee.UIParticleInternal.AssetModification
|
||||||
|
{
|
||||||
|
internal class TextReplaceModifier : ITextModifier
|
||||||
|
{
|
||||||
|
private readonly Regex _pattern;
|
||||||
|
private readonly string _replace;
|
||||||
|
|
||||||
|
public TextReplaceModifier(string pattern, string replace)
|
||||||
|
{
|
||||||
|
_pattern = new Regex(pattern);
|
||||||
|
_replace = replace;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool ModifyText(StringBuilder sb, string text)
|
||||||
|
{
|
||||||
|
if (!_pattern.IsMatch(text)) return false;
|
||||||
|
|
||||||
|
sb.AppendLine(_pattern.Replace(text, _replace));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: afc6ba9550e5e4c25951b03db43a4fd0
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -2,22 +2,19 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using UnityEditor;
|
using UnityEditor;
|
||||||
|
using UnityEditor.UI;
|
||||||
using UnityEditorInternal;
|
using UnityEditorInternal;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.UI;
|
using UnityEngine.UI;
|
||||||
|
|
||||||
#if UNITY_2021_2_OR_NEWER
|
#if UNITY_2021_2_OR_NEWER
|
||||||
using UnityEditor.Overlays;
|
using UnityEditor.Overlays;
|
||||||
#else
|
#else
|
||||||
using System;
|
using System;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using Coffee.UIParticleInternal;
|
|
||||||
using Object = UnityEngine.Object;
|
using Object = UnityEngine.Object;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if UNITY_2021_2_OR_NEWER
|
#if UNITY_2021_2_OR_NEWER
|
||||||
using UnityEditor.SceneManagement;
|
using UnityEditor.SceneManagement;
|
||||||
|
|
||||||
#elif UNITY_2018_3_OR_NEWER
|
#elif UNITY_2018_3_OR_NEWER
|
||||||
using UnityEditor.Experimental.SceneManagement;
|
using UnityEditor.Experimental.SceneManagement;
|
||||||
#endif
|
#endif
|
||||||
@@ -26,8 +23,31 @@ namespace Coffee.UIExtensions
|
|||||||
{
|
{
|
||||||
[CustomEditor(typeof(UIParticle))]
|
[CustomEditor(typeof(UIParticle))]
|
||||||
[CanEditMultipleObjects]
|
[CanEditMultipleObjects]
|
||||||
internal class UIParticleEditor : Editor
|
internal class UIParticleEditor : GraphicEditor
|
||||||
{
|
{
|
||||||
|
#if UNITY_2021_2_OR_NEWER
|
||||||
|
#if UNITY_2022_1_OR_NEWER
|
||||||
|
[Overlay(typeof(SceneView), "Scene View/UI Particles", "UI Particles", true,
|
||||||
|
defaultDockPosition = DockPosition.Bottom,
|
||||||
|
defaultDockZone = DockZone.Floating,
|
||||||
|
defaultLayout = Layout.Panel)]
|
||||||
|
#else
|
||||||
|
[Overlay(typeof(SceneView), "Scene View/UI Particles", "UI Particles", true)]
|
||||||
|
#endif
|
||||||
|
private class UIParticleOverlay : IMGUIOverlay, ITransientOverlay
|
||||||
|
{
|
||||||
|
public bool visible => s_SerializedObject != null;
|
||||||
|
|
||||||
|
public override void OnGUI()
|
||||||
|
{
|
||||||
|
if (visible)
|
||||||
|
{
|
||||||
|
WindowFunction();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
//################################
|
//################################
|
||||||
// Constant or Static Members.
|
// Constant or Static Members.
|
||||||
//################################
|
//################################
|
||||||
@@ -39,6 +59,7 @@ namespace Coffee.UIExtensions
|
|||||||
private static readonly GUIContent s_Content3D = new GUIContent("3D");
|
private static readonly GUIContent s_Content3D = new GUIContent("3D");
|
||||||
private static readonly GUIContent s_ContentRandom = new GUIContent("Random");
|
private static readonly GUIContent s_ContentRandom = new GUIContent("Random");
|
||||||
private static readonly GUIContent s_ContentScale = new GUIContent("Scale");
|
private static readonly GUIContent s_ContentScale = new GUIContent("Scale");
|
||||||
|
private static SerializedObject s_SerializedObject;
|
||||||
private static bool s_XYZMode;
|
private static bool s_XYZMode;
|
||||||
|
|
||||||
private SerializedProperty _maskable;
|
private SerializedProperty _maskable;
|
||||||
@@ -66,14 +87,66 @@ namespace Coffee.UIExtensions
|
|||||||
"_ColorMask"
|
"_ColorMask"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
[InitializeOnLoadMethod]
|
||||||
|
private static void Init()
|
||||||
|
{
|
||||||
|
#if !UNITY_2021_2_OR_NEWER
|
||||||
|
var miSceneViewOverlayWindow = Type.GetType("UnityEditor.SceneViewOverlay, UnityEditor")
|
||||||
|
?.GetMethods(BindingFlags.Public | BindingFlags.Static)
|
||||||
|
.First(x => x.Name == "Window" && 5 <= x.GetParameters().Length);
|
||||||
|
var windowFunction = (Action<Object, SceneView>)WindowFunction;
|
||||||
|
var windowFunctionType = Type.GetType("UnityEditor.SceneViewOverlay+WindowFunction, UnityEditor");
|
||||||
|
var windowFunctionDelegate = Delegate.CreateDelegate(windowFunctionType, windowFunction.Method);
|
||||||
|
var windowTitle = new GUIContent(ObjectNames.NicifyVariableName(nameof(UIParticle)));
|
||||||
|
#if UNITY_2019_2_OR_NEWER
|
||||||
|
//public static void Window(GUIContent title, WindowFunction sceneViewFunc, int order, Object target, WindowDisplayOption option, EditorWindow window = null)
|
||||||
|
var sceneViewArgs = new object[] { windowTitle, windowFunctionDelegate, 599, null, 2, null };
|
||||||
|
#else
|
||||||
|
//public static void Window(GUIContent title, WindowFunction sceneViewFunc, int order, Object target, WindowDisplayOption option)
|
||||||
|
var sceneViewArgs = new object[] { windowTitle, windowFunctionDelegate, 599, null, 2 };
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if UNITY_2019_1_OR_NEWER
|
||||||
|
SceneView.duringSceneGui += _ =>
|
||||||
|
#else
|
||||||
|
SceneView.onSceneGUIDelegate += _ =>
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
if (s_SerializedObject != null)
|
||||||
|
{
|
||||||
|
miSceneViewOverlayWindow.Invoke(null, sceneViewArgs);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
SerializedObject CreateSerializeObject()
|
||||||
|
{
|
||||||
|
var uiParticles = Selection.gameObjects.Select(x => x.GetComponent<ParticleSystem>())
|
||||||
|
.Where(x => x)
|
||||||
|
.Select(x => x.GetComponentInParent<UIParticle>(true))
|
||||||
|
.Where(x => x && x.canvas)
|
||||||
|
.Concat(Selection.gameObjects.Select(x => x.GetComponent<UIParticle>())
|
||||||
|
.Where(x => x && x.canvas))
|
||||||
|
.Distinct()
|
||||||
|
.OfType<Object>()
|
||||||
|
.ToArray();
|
||||||
|
return 0 < uiParticles.Length ? new SerializedObject(uiParticles) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
s_SerializedObject = CreateSerializeObject();
|
||||||
|
Selection.selectionChanged += () => s_SerializedObject = CreateSerializeObject();
|
||||||
|
}
|
||||||
|
|
||||||
//################################
|
//################################
|
||||||
// Public/Protected Members.
|
// Public/Protected Members.
|
||||||
//################################
|
//################################
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This function is called when the object becomes enabled and active.
|
/// This function is called when the object becomes enabled and active.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void OnEnable()
|
protected override void OnEnable()
|
||||||
{
|
{
|
||||||
|
base.OnEnable();
|
||||||
|
|
||||||
_maskable = serializedObject.FindProperty("m_Maskable");
|
_maskable = serializedObject.FindProperty("m_Maskable");
|
||||||
_scale3D = serializedObject.FindProperty("m_Scale3D");
|
_scale3D = serializedObject.FindProperty("m_Scale3D");
|
||||||
_animatableProperties = serializedObject.FindProperty("m_AnimatableProperties");
|
_animatableProperties = serializedObject.FindProperty("m_AnimatableProperties");
|
||||||
@@ -401,14 +474,61 @@ namespace Coffee.UIExtensions
|
|||||||
|
|
||||||
private static void DrawAutoScaling(SerializedProperty prop, IEnumerable<UIParticle> uiParticles)
|
private static void DrawAutoScaling(SerializedProperty prop, IEnumerable<UIParticle> uiParticles)
|
||||||
{
|
{
|
||||||
|
var isTransformMode = prop.intValue == (int)UIParticle.AutoScalingMode.Transform;
|
||||||
|
EditorGUI.BeginChangeCheck();
|
||||||
EditorGUILayout.PropertyField(prop);
|
EditorGUILayout.PropertyField(prop);
|
||||||
|
if (!EditorGUI.EndChangeCheck() || !isTransformMode) return;
|
||||||
|
|
||||||
|
// on changed true->false, reset scale.
|
||||||
|
EditorApplication.delayCall += () =>
|
||||||
|
{
|
||||||
|
foreach (var uip in uiParticles)
|
||||||
|
{
|
||||||
|
if (!uip) continue;
|
||||||
|
uip.transform.localScale = Vector3.one;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#if UNITY_2021_2_OR_NEWER
|
||||||
|
private static void WindowFunction()
|
||||||
|
#else
|
||||||
|
private static void WindowFunction(Object _, SceneView __)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (s_SerializedObject == null || !s_SerializedObject.targetObject) return;
|
||||||
|
var uiParticles = s_SerializedObject.targetObjects.OfType<UIParticle>().ToArray();
|
||||||
|
if (uiParticles.Any(x => !x || !x.canvas)) return;
|
||||||
|
|
||||||
|
s_SerializedObject.Update();
|
||||||
|
using (new EditorGUILayout.VerticalScope(GUILayout.Width(220f)))
|
||||||
|
{
|
||||||
|
var labelWidth = EditorGUIUtility.labelWidth;
|
||||||
|
EditorGUIUtility.labelWidth = 100;
|
||||||
|
EditorGUILayout.PropertyField(s_SerializedObject.FindProperty("m_Enabled"));
|
||||||
|
s_XYZMode = DrawFloatOrVector3Field(s_SerializedObject.FindProperty("m_Scale3D"), s_XYZMode);
|
||||||
|
EditorGUILayout.PropertyField(s_SerializedObject.FindProperty("m_PositionMode"));
|
||||||
|
DrawAutoScaling(s_SerializedObject.FindProperty("m_AutoScalingMode"), uiParticles);
|
||||||
|
EditorGUIUtility.labelWidth = labelWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
s_SerializedObject.ApplyModifiedProperties();
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// ignored
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DestroyUIParticle(UIParticle p, bool ignoreCurrent = false)
|
private void DestroyUIParticle(UIParticle p, bool ignoreCurrent = false)
|
||||||
{
|
{
|
||||||
if (!p || (ignoreCurrent && target == p)) return;
|
if (!p || (ignoreCurrent && target == p)) return;
|
||||||
|
|
||||||
|
var cr = p.canvasRenderer;
|
||||||
DestroyImmediate(p);
|
DestroyImmediate(p);
|
||||||
|
DestroyImmediate(cr);
|
||||||
|
|
||||||
#if UNITY_2018_3_OR_NEWER
|
#if UNITY_2018_3_OR_NEWER
|
||||||
var stage = PrefabStageUtility.GetCurrentPrefabStage();
|
var stage = PrefabStageUtility.GetCurrentPrefabStage();
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
Copyright 2018-2024 mob-sakai
|
Copyright 2018-2023 mob-sakai
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# <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)
|
# Particle Effect For UGUI (UI Particle)
|
||||||
|
|
||||||
This package provides a component to render particle effects for uGUI in Unity 2018.2 or later.
|
This package provides a component to render particle effects for uGUI in Unity 2018.2 or later.
|
||||||
The particle rendering is maskable and sortable, without the need for an extra Camera, RenderTexture, or Canvas.
|
The particle rendering is maskable and sortable, without the need for an extra Camera, RenderTexture, or Canvas.
|
||||||
@@ -117,16 +117,6 @@ Or, use [UpmGitExtension](https://github.com/mob-sakai/UpmGitExtension) to insta
|
|||||||
|
|
||||||
<br><br>
|
<br><br>
|
||||||
|
|
||||||
## ⚙ Upgrading from 3.x/4.x to 5.x
|
|
||||||
|
|
||||||
### Breaking Changes
|
|
||||||
|
|
||||||
- The default value of `UIParticle.scale` has been changed from `10` to `1`.
|
|
||||||
- `UIParticle` no longer inherits from `MaskableGraphic`.
|
|
||||||
-
|
|
||||||
|
|
||||||
<br><br>
|
|
||||||
|
|
||||||
## 🚀 Usage
|
## 🚀 Usage
|
||||||
|
|
||||||
### UIParticle Component
|
### UIParticle Component
|
||||||
@@ -186,10 +176,9 @@ section.
|
|||||||
### Script usage
|
### Script usage
|
||||||
|
|
||||||
```cs
|
```cs
|
||||||
// Instantiate ParticleSystem prefab with UIParticle on runtime.
|
// Instant ParticleSystem prefab with UIParticle on runtime.
|
||||||
var go = GameObject.Instantiate(prefab);
|
var go = GameObject.Instantiate(prefab);
|
||||||
var uiParticle = go.AddComponent<UIParticle>();
|
var uiParticle = go.AddComponent<UIParticle>();
|
||||||
uiParticle.scale = 100;
|
|
||||||
|
|
||||||
// Control by ParticleSystem.
|
// Control by ParticleSystem.
|
||||||
particleSystem.Play();
|
particleSystem.Play();
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using UnityEditor;
|
using UnityEditor;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.Profiling;
|
using UnityEngine.Profiling;
|
||||||
@@ -12,48 +11,6 @@ namespace Coffee.UIParticleInternal
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
internal static class ComponentExtensions
|
internal static class ComponentExtensions
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Get components in children of a specific type in the hierarchy of a GameObject.
|
|
||||||
/// </summary>
|
|
||||||
public static T[] GetComponentsInChildren<T>(this Component self, int depth)
|
|
||||||
where T : Component
|
|
||||||
{
|
|
||||||
var results = ListPool<T>.Rent();
|
|
||||||
self.GetComponentsInChildren_Internal(results, depth);
|
|
||||||
var array = results.ToArray();
|
|
||||||
ListPool<T>.Return(ref results);
|
|
||||||
return array;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get components in children of a specific type in the hierarchy of a GameObject.
|
|
||||||
/// </summary>
|
|
||||||
public static void GetComponentsInChildren<T>(this Component self, List<T> results, int depth)
|
|
||||||
where T : Component
|
|
||||||
{
|
|
||||||
results.Clear();
|
|
||||||
self.GetComponentsInChildren_Internal(results, depth);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void GetComponentsInChildren_Internal<T>(this Component self, List<T> results, int depth)
|
|
||||||
where T : Component
|
|
||||||
{
|
|
||||||
if (!self || results == null || depth < 0) return;
|
|
||||||
|
|
||||||
var tr = self.transform;
|
|
||||||
if (tr.TryGetComponent<T>(out var t))
|
|
||||||
{
|
|
||||||
results.Add(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (depth - 1 < 0) return;
|
|
||||||
var childCount = tr.childCount;
|
|
||||||
for (var i = 0; i < childCount; i++)
|
|
||||||
{
|
|
||||||
tr.GetChild(i).GetComponentsInChildren(results, depth - 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get or add a component of a specific type to a GameObject.
|
/// Get or add a component of a specific type to a GameObject.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -1,13 +1,11 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
using Conditional = System.Diagnostics.ConditionalAttribute;
|
||||||
using Object = UnityEngine.Object;
|
using Object = UnityEngine.Object;
|
||||||
#if ENABLE_COFFEE_LOGGER
|
#if ENABLE_COFFEE_LOGGER
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
#else
|
|
||||||
using Conditional = System.Diagnostics.ConditionalAttribute;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace Coffee.UIParticleInternal
|
namespace Coffee.UIParticleInternal
|
||||||
|
|||||||
@@ -42,34 +42,6 @@ namespace Coffee.UIParticleInternal
|
|||||||
Profiler.EndSample();
|
Profiler.EndSample();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Adds or retrieves a cached material based on the hash.
|
|
||||||
/// </summary>
|
|
||||||
public static void Get(Hash128 hash, ref Material material, string shaderName)
|
|
||||||
{
|
|
||||||
Profiler.BeginSample("(COF)[MaterialRepository] Get");
|
|
||||||
s_Repository.Get(hash, ref material, x => new Material(Shader.Find(x))
|
|
||||||
{
|
|
||||||
hideFlags = HideFlags.DontSave | HideFlags.NotEditable
|
|
||||||
}, shaderName);
|
|
||||||
Profiler.EndSample();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Adds or retrieves a cached material based on the hash.
|
|
||||||
/// </summary>
|
|
||||||
public static void Get(Hash128 hash, ref Material material, string shaderName, string[] keywords)
|
|
||||||
{
|
|
||||||
Profiler.BeginSample("(COF)[MaterialRepository] Get");
|
|
||||||
s_Repository.Get(hash, ref material, x => new Material(Shader.Find(x.shaderName))
|
|
||||||
{
|
|
||||||
hideFlags = HideFlags.DontSave | HideFlags.NotEditable,
|
|
||||||
shaderKeywords = x.keywords
|
|
||||||
}, (shaderName, keywords));
|
|
||||||
Profiler.EndSample();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds or retrieves a cached material based on the hash.
|
/// Adds or retrieves a cached material based on the hash.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ using UnityEngine;
|
|||||||
using UnityEngine.EventSystems;
|
using UnityEngine.EventSystems;
|
||||||
using UnityEngine.Rendering;
|
using UnityEngine.Rendering;
|
||||||
using UnityEngine.Serialization;
|
using UnityEngine.Serialization;
|
||||||
|
using UnityEngine.UI;
|
||||||
using Random = UnityEngine.Random;
|
using Random = UnityEngine.Random;
|
||||||
|
|
||||||
[assembly: InternalsVisibleTo("Coffee.UIParticle.Editor")]
|
[assembly: InternalsVisibleTo("Coffee.UIParticle.Editor")]
|
||||||
@@ -18,7 +19,7 @@ namespace Coffee.UIExtensions
|
|||||||
[ExecuteAlways]
|
[ExecuteAlways]
|
||||||
[RequireComponent(typeof(RectTransform))]
|
[RequireComponent(typeof(RectTransform))]
|
||||||
[RequireComponent(typeof(CanvasRenderer))]
|
[RequireComponent(typeof(CanvasRenderer))]
|
||||||
public class UIParticle : UIBehaviour, ISerializationCallbackReceiver
|
public class UIParticle : MaskableGraphic, ISerializationCallbackReceiver
|
||||||
{
|
{
|
||||||
public enum AutoScalingMode
|
public enum AutoScalingMode
|
||||||
{
|
{
|
||||||
@@ -44,23 +45,20 @@ namespace Coffee.UIExtensions
|
|||||||
|
|
||||||
[HideInInspector]
|
[HideInInspector]
|
||||||
[SerializeField]
|
[SerializeField]
|
||||||
[Obsolete]
|
|
||||||
internal bool m_IsTrail;
|
internal bool m_IsTrail;
|
||||||
|
|
||||||
[HideInInspector]
|
[HideInInspector]
|
||||||
[FormerlySerializedAs("m_IgnoreParent")]
|
[FormerlySerializedAs("m_IgnoreParent")]
|
||||||
[SerializeField]
|
[SerializeField]
|
||||||
[Obsolete]
|
|
||||||
private bool m_IgnoreCanvasScaler;
|
private bool m_IgnoreCanvasScaler;
|
||||||
|
|
||||||
[HideInInspector]
|
[HideInInspector]
|
||||||
[SerializeField]
|
[SerializeField]
|
||||||
[Obsolete]
|
private bool m_AbsoluteMode;
|
||||||
internal bool m_AbsoluteMode;
|
|
||||||
|
|
||||||
[Tooltip("Particle effect scale")]
|
[Tooltip("Particle effect scale")]
|
||||||
[SerializeField]
|
[SerializeField]
|
||||||
private Vector3 m_Scale3D = new Vector3(1, 1, 1);
|
private Vector3 m_Scale3D = new Vector3(10, 10, 10);
|
||||||
|
|
||||||
[Tooltip("Animatable material properties.\n" +
|
[Tooltip("Animatable material properties.\n" +
|
||||||
"If you want to change the material properties of the ParticleSystem in Animation, enable it.")]
|
"If you want to change the material properties of the ParticleSystem in Animation, enable it.")]
|
||||||
@@ -95,56 +93,25 @@ namespace Coffee.UIExtensions
|
|||||||
|
|
||||||
[SerializeField]
|
[SerializeField]
|
||||||
[Tooltip("Prevent the root-Canvas scale from affecting the hierarchy-scaled ParticleSystem.")]
|
[Tooltip("Prevent the root-Canvas scale from affecting the hierarchy-scaled ParticleSystem.")]
|
||||||
[Obsolete]
|
private bool m_AutoScaling = true;
|
||||||
internal bool m_AutoScaling;
|
|
||||||
|
|
||||||
[SerializeField]
|
[SerializeField]
|
||||||
[Tooltip("Transform: Transform.lossyScale (=world scale) will be set to (1, 1, 1)." +
|
[Tooltip("Transform: Transform.lossyScale (=world scale) will be set to (1, 1, 1)." +
|
||||||
"UIParticle: UIParticle.scale will be adjusted.")]
|
"UIParticle: UIParticle.scale will be adjusted.")]
|
||||||
private AutoScalingMode m_AutoScalingMode = AutoScalingMode.Transform;
|
private AutoScalingMode m_AutoScalingMode = AutoScalingMode.Transform;
|
||||||
|
|
||||||
[SerializeField]
|
|
||||||
private bool m_Maskable = true;
|
|
||||||
|
|
||||||
private readonly List<UIParticleRenderer> _renderers = new List<UIParticleRenderer>();
|
private readonly List<UIParticleRenderer> _renderers = new List<UIParticleRenderer>();
|
||||||
private Canvas _canvas;
|
|
||||||
private int _groupId;
|
private int _groupId;
|
||||||
private Camera _bakeCamera;
|
private Camera _orthoCamera;
|
||||||
private DrivenRectTransformTracker _tracker;
|
private DrivenRectTransformTracker _tracker;
|
||||||
private Vector3 _storedScale;
|
|
||||||
private bool _isScaleStored;
|
|
||||||
|
|
||||||
public RectTransform rectTransform => transform as RectTransform;
|
|
||||||
|
|
||||||
public Canvas canvas
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (_canvas) return _canvas;
|
|
||||||
|
|
||||||
var tr = transform;
|
|
||||||
while (tr && !_canvas)
|
|
||||||
{
|
|
||||||
if (tr.TryGetComponent(out _canvas)) return _canvas;
|
|
||||||
tr = tr.parent;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Does this graphic allow masking.
|
/// Should this graphic be considered a target for ray-casting?
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool maskable
|
public override bool raycastTarget
|
||||||
{
|
{
|
||||||
get => m_Maskable;
|
get => false;
|
||||||
set
|
set { }
|
||||||
{
|
|
||||||
if (value == m_Maskable) return;
|
|
||||||
m_Maskable = value;
|
|
||||||
UpdateRendererMaterial();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -234,12 +201,7 @@ namespace Coffee.UIExtensions
|
|||||||
{
|
{
|
||||||
if (m_AutoScalingMode == value) return;
|
if (m_AutoScalingMode == value) return;
|
||||||
m_AutoScalingMode = value;
|
m_AutoScalingMode = value;
|
||||||
|
UpdateTracker();
|
||||||
if (autoScalingMode != AutoScalingMode.Transform && _isScaleStored)
|
|
||||||
{
|
|
||||||
transform.localScale = _storedScale;
|
|
||||||
_isScaleStored = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -282,9 +244,9 @@ namespace Coffee.UIExtensions
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Particle effect scale.
|
/// Particle effect scale.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Vector3 scale3DForCalc => autoScalingMode == AutoScalingMode.Transform
|
public Vector3 scale3DForCalc => autoScalingMode == AutoScalingMode.UIParticle
|
||||||
? m_Scale3D
|
? m_Scale3D.GetScaled(canvasScale)
|
||||||
: m_Scale3D.GetScaled(canvasScale, transform.localScale);
|
: m_Scale3D;
|
||||||
|
|
||||||
public List<ParticleSystem> particles => m_Particles;
|
public List<ParticleSystem> particles => m_Particles;
|
||||||
|
|
||||||
@@ -304,6 +266,8 @@ namespace Coffee.UIExtensions
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override Material materialForRendering => null;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Paused.
|
/// Paused.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -311,15 +275,15 @@ namespace Coffee.UIExtensions
|
|||||||
|
|
||||||
public Vector3 parentScale { get; private set; }
|
public Vector3 parentScale { get; private set; }
|
||||||
|
|
||||||
private Vector3 canvasScale { get; set; }
|
public Vector3 canvasScale { get; private set; }
|
||||||
|
|
||||||
protected override void OnEnable()
|
protected override void OnEnable()
|
||||||
{
|
{
|
||||||
_isScaleStored = false;
|
|
||||||
ResetGroupId();
|
ResetGroupId();
|
||||||
|
UpdateTracker();
|
||||||
UIParticleUpdater.Register(this);
|
UIParticleUpdater.Register(this);
|
||||||
|
RegisterDirtyMaterialCallback(UpdateRendererMaterial);
|
||||||
|
|
||||||
//
|
|
||||||
if (0 < particles.Count)
|
if (0 < particles.Count)
|
||||||
{
|
{
|
||||||
RefreshParticles(particles);
|
RefreshParticles(particles);
|
||||||
@@ -329,7 +293,7 @@ namespace Coffee.UIExtensions
|
|||||||
RefreshParticles();
|
RefreshParticles();
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateRendererMaterial();
|
base.OnEnable();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -337,24 +301,12 @@ namespace Coffee.UIExtensions
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
protected override void OnDisable()
|
protected override void OnDisable()
|
||||||
{
|
{
|
||||||
_tracker.Clear();
|
UpdateTracker();
|
||||||
if (autoScalingMode == AutoScalingMode.Transform && _isScaleStored)
|
|
||||||
{
|
|
||||||
transform.localScale = _storedScale;
|
|
||||||
}
|
|
||||||
|
|
||||||
_isScaleStored = false;
|
|
||||||
UIParticleUpdater.Unregister(this);
|
UIParticleUpdater.Unregister(this);
|
||||||
_renderers.ForEach(r => r.Reset());
|
_renderers.ForEach(r => r.Reset());
|
||||||
_canvas = null;
|
UnregisterDirtyMaterialCallback(UpdateRendererMaterial);
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
base.OnDisable();
|
||||||
/// Called when the state of the parent Canvas is changed.
|
|
||||||
/// </summary>
|
|
||||||
protected override void OnCanvasHierarchyChanged()
|
|
||||||
{
|
|
||||||
_canvas = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -364,13 +316,13 @@ namespace Coffee.UIExtensions
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
#if UNITY_EDITOR
|
||||||
/// This function is called when a direct or indirect parent of the transform of the GameObject has changed.
|
protected override void OnValidate()
|
||||||
/// </summary>
|
|
||||||
protected override void OnTransformParentChanged()
|
|
||||||
{
|
{
|
||||||
_canvas = null;
|
base.OnValidate();
|
||||||
|
UpdateTracker();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void ISerializationCallbackReceiver.OnBeforeSerialize()
|
void ISerializationCallbackReceiver.OnBeforeSerialize()
|
||||||
{
|
{
|
||||||
@@ -378,7 +330,6 @@ namespace Coffee.UIExtensions
|
|||||||
|
|
||||||
void ISerializationCallbackReceiver.OnAfterDeserialize()
|
void ISerializationCallbackReceiver.OnAfterDeserialize()
|
||||||
{
|
{
|
||||||
#pragma warning disable CS0612 // Type or member is obsolete
|
|
||||||
if (m_IgnoreCanvasScaler || m_AutoScaling)
|
if (m_IgnoreCanvasScaler || m_AutoScaling)
|
||||||
{
|
{
|
||||||
m_IgnoreCanvasScaler = false;
|
m_IgnoreCanvasScaler = false;
|
||||||
@@ -391,47 +342,31 @@ namespace Coffee.UIExtensions
|
|||||||
m_AbsoluteMode = false;
|
m_AbsoluteMode = false;
|
||||||
m_PositionMode = PositionMode.Absolute;
|
m_PositionMode = PositionMode.Absolute;
|
||||||
}
|
}
|
||||||
#pragma warning restore CS0612 // Type or member is obsolete
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Play the ParticleSystems.
|
|
||||||
/// </summary>
|
|
||||||
public void Play()
|
public void Play()
|
||||||
{
|
{
|
||||||
particles.Exec(p => p.Simulate(0, false, true));
|
particles.Exec(p => p.Simulate(0, false, true));
|
||||||
isPaused = false;
|
isPaused = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Pause the ParticleSystems.
|
|
||||||
/// </summary>
|
|
||||||
public void Pause()
|
public void Pause()
|
||||||
{
|
{
|
||||||
particles.Exec(p => p.Pause());
|
particles.Exec(p => p.Pause());
|
||||||
isPaused = true;
|
isPaused = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Unpause the ParticleSystems.
|
|
||||||
/// </summary>
|
|
||||||
public void Resume()
|
public void Resume()
|
||||||
{
|
{
|
||||||
isPaused = false;
|
isPaused = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Stop the ParticleSystems.
|
|
||||||
/// </summary>
|
|
||||||
public void Stop()
|
public void Stop()
|
||||||
{
|
{
|
||||||
particles.Exec(p => p.Stop());
|
particles.Exec(p => p.Stop());
|
||||||
isPaused = true;
|
isPaused = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Start emission of the ParticleSystems.
|
|
||||||
/// </summary>
|
|
||||||
public void StartEmission()
|
public void StartEmission()
|
||||||
{
|
{
|
||||||
particles.Exec(p =>
|
particles.Exec(p =>
|
||||||
@@ -441,9 +376,6 @@ namespace Coffee.UIExtensions
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Stop emission of the ParticleSystems.
|
|
||||||
/// </summary>
|
|
||||||
public void StopEmission()
|
public void StopEmission()
|
||||||
{
|
{
|
||||||
particles.Exec(p =>
|
particles.Exec(p =>
|
||||||
@@ -453,34 +385,24 @@ namespace Coffee.UIExtensions
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Clear the particles of the ParticleSystems.
|
|
||||||
/// </summary>
|
|
||||||
public void Clear()
|
public void Clear()
|
||||||
{
|
{
|
||||||
particles.Exec(p => p.Clear());
|
particles.Exec(p => p.Clear());
|
||||||
isPaused = true;
|
isPaused = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Refresh UIParticle using the ParticleSystem instance.
|
|
||||||
/// </summary>
|
|
||||||
public void SetParticleSystemInstance(GameObject instance)
|
public void SetParticleSystemInstance(GameObject instance)
|
||||||
{
|
{
|
||||||
SetParticleSystemInstance(instance, true);
|
SetParticleSystemInstance(instance, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Refresh UIParticle using the ParticleSystem instance.
|
|
||||||
/// </summary>
|
|
||||||
public void SetParticleSystemInstance(GameObject instance, bool destroyOldParticles)
|
public void SetParticleSystemInstance(GameObject instance, bool destroyOldParticles)
|
||||||
{
|
{
|
||||||
if (!instance) return;
|
if (!instance) return;
|
||||||
|
|
||||||
var childCount = transform.childCount;
|
foreach (Transform child in transform)
|
||||||
for (var i = 0; i < childCount; i++)
|
|
||||||
{
|
{
|
||||||
var go = transform.GetChild(i).gameObject;
|
var go = child.gameObject;
|
||||||
go.SetActive(false);
|
go.SetActive(false);
|
||||||
if (destroyOldParticles)
|
if (destroyOldParticles)
|
||||||
{
|
{
|
||||||
@@ -495,10 +417,6 @@ namespace Coffee.UIExtensions
|
|||||||
RefreshParticles(instance);
|
RefreshParticles(instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Refresh UIParticle using the prefab.
|
|
||||||
/// The prefab is automatically instantiated.
|
|
||||||
/// </summary>
|
|
||||||
public void SetParticleSystemPrefab(GameObject prefab)
|
public void SetParticleSystemPrefab(GameObject prefab)
|
||||||
{
|
{
|
||||||
if (!prefab) return;
|
if (!prefab) return;
|
||||||
@@ -506,31 +424,16 @@ namespace Coffee.UIExtensions
|
|||||||
SetParticleSystemInstance(Instantiate(prefab.gameObject), true);
|
SetParticleSystemInstance(Instantiate(prefab.gameObject), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Refresh UIParticle.
|
|
||||||
/// Collect ParticleSystems under the GameObject and refresh the UIParticle.
|
|
||||||
/// </summary>
|
|
||||||
public void RefreshParticles()
|
public void RefreshParticles()
|
||||||
{
|
{
|
||||||
RefreshParticles(gameObject);
|
RefreshParticles(gameObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Refresh UIParticle.
|
|
||||||
/// Collect ParticleSystems under the GameObject and refresh the UIParticle.
|
|
||||||
/// </summary>
|
|
||||||
private void RefreshParticles(GameObject root)
|
private void RefreshParticles(GameObject root)
|
||||||
{
|
{
|
||||||
if (!root) return;
|
if (!root) return;
|
||||||
root.GetComponentsInChildren(true, particles);
|
root.GetComponentsInChildren(true, particles);
|
||||||
for (var i = particles.Count - 1; 0 <= i; i--)
|
particles.RemoveAll(x => x.GetComponentInParent<UIParticle>(true) != this);
|
||||||
{
|
|
||||||
var ps = particles[i];
|
|
||||||
if (!ps || ps.GetComponentInParent<UIParticle>(true) != this)
|
|
||||||
{
|
|
||||||
particles.RemoveAt(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var i = 0; i < particles.Count; i++)
|
for (var i = 0; i < particles.Count; i++)
|
||||||
{
|
{
|
||||||
@@ -545,39 +448,31 @@ namespace Coffee.UIExtensions
|
|||||||
RefreshParticles(particles);
|
RefreshParticles(particles);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
public void RefreshParticles(List<ParticleSystem> particles)
|
||||||
/// Refresh UIParticle using a list of ParticleSystems.
|
|
||||||
/// </summary>
|
|
||||||
public void RefreshParticles(List<ParticleSystem> particleSystems)
|
|
||||||
{
|
{
|
||||||
// Collect children UIParticleRenderer components.
|
|
||||||
// #246: Nullptr exceptions when using nested UIParticle components in hierarchy
|
// #246: Nullptr exceptions when using nested UIParticle components in hierarchy
|
||||||
_renderers.Clear();
|
_renderers.Clear();
|
||||||
var childCount = transform.childCount;
|
foreach (Transform child in transform)
|
||||||
for (var i = 0; i < childCount; i++)
|
|
||||||
{
|
{
|
||||||
var child = transform.GetChild(i);
|
var uiParticleRenderer = child.GetComponent<UIParticleRenderer>();
|
||||||
if (child.TryGetComponent(out UIParticleRenderer uiParticleRenderer))
|
|
||||||
|
if (uiParticleRenderer != null)
|
||||||
{
|
{
|
||||||
_renderers.Add(uiParticleRenderer);
|
_renderers.Add(uiParticleRenderer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset the UIParticleRenderer components.
|
|
||||||
for (var i = 0; i < _renderers.Count; i++)
|
for (var i = 0; i < _renderers.Count; i++)
|
||||||
{
|
{
|
||||||
_renderers[i].Reset(i);
|
_renderers[i].Reset(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the ParticleSystem to the UIParticleRenderer. If the trail is enabled, set it additionally.
|
|
||||||
var j = 0;
|
var j = 0;
|
||||||
for (var i = 0; i < particleSystems.Count; i++)
|
for (var i = 0; i < particles.Count; i++)
|
||||||
{
|
{
|
||||||
var ps = particleSystems[i];
|
var ps = particles[i];
|
||||||
if (!ps) continue;
|
if (!ps) continue;
|
||||||
GetRenderer(j++).Set(this, ps, false);
|
GetRenderer(j++).Set(this, ps, false);
|
||||||
|
|
||||||
// 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);
|
||||||
@@ -587,26 +482,12 @@ namespace Coffee.UIExtensions
|
|||||||
|
|
||||||
internal void UpdateTransformScale()
|
internal void UpdateTransformScale()
|
||||||
{
|
{
|
||||||
_tracker.Clear();
|
|
||||||
canvasScale = canvas.rootCanvas.transform.localScale.Inverse();
|
canvasScale = canvas.rootCanvas.transform.localScale.Inverse();
|
||||||
parentScale = transform.parent.lossyScale;
|
parentScale = transform.parent.lossyScale;
|
||||||
if (autoScalingMode != AutoScalingMode.Transform)
|
if (autoScalingMode != AutoScalingMode.Transform) return;
|
||||||
{
|
|
||||||
if (_isScaleStored)
|
|
||||||
{
|
|
||||||
transform.localScale = _storedScale;
|
|
||||||
}
|
|
||||||
|
|
||||||
_isScaleStored = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var currentScale = transform.localScale;
|
|
||||||
_storedScale = currentScale;
|
|
||||||
_isScaleStored = true;
|
|
||||||
_tracker.Add(this, rectTransform, DrivenTransformProperties.Scale);
|
|
||||||
var newScale = parentScale.Inverse();
|
var newScale = parentScale.Inverse();
|
||||||
if (currentScale != newScale)
|
if (transform.localScale != newScale)
|
||||||
{
|
{
|
||||||
transform.localScale = newScale;
|
transform.localScale = newScale;
|
||||||
}
|
}
|
||||||
@@ -619,10 +500,11 @@ namespace Coffee.UIExtensions
|
|||||||
for (var i = 0; i < _renderers.Count; i++)
|
for (var i = 0; i < _renderers.Count; i++)
|
||||||
{
|
{
|
||||||
var r = _renderers[i];
|
var r = _renderers[i];
|
||||||
if (r) continue;
|
if (!r)
|
||||||
|
{
|
||||||
RefreshParticles(particles);
|
RefreshParticles(particles);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var bakeCamera = GetBakeCamera();
|
var bakeCamera = GetBakeCamera();
|
||||||
@@ -630,7 +512,6 @@ namespace Coffee.UIExtensions
|
|||||||
{
|
{
|
||||||
var r = _renderers[i];
|
var r = _renderers[i];
|
||||||
if (!r) continue;
|
if (!r) continue;
|
||||||
|
|
||||||
r.UpdateMesh(bakeCamera);
|
r.UpdateMesh(bakeCamera);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -642,6 +523,17 @@ namespace Coffee.UIExtensions
|
|||||||
: Random.Range(m_GroupId, m_GroupMaxId + 1);
|
: Random.Range(m_GroupId, m_GroupMaxId + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void UpdateMaterial()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Call to update the geometry of the Graphic onto the CanvasRenderer.
|
||||||
|
/// </summary>
|
||||||
|
protected override void UpdateGeometry()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
private void UpdateRendererMaterial()
|
private void UpdateRendererMaterial()
|
||||||
{
|
{
|
||||||
for (var i = 0; i < _renderers.Count; i++)
|
for (var i = 0; i < _renderers.Count; i++)
|
||||||
@@ -671,46 +563,64 @@ namespace Coffee.UIExtensions
|
|||||||
private Camera GetBakeCamera()
|
private Camera GetBakeCamera()
|
||||||
{
|
{
|
||||||
if (!canvas) return Camera.main;
|
if (!canvas) return Camera.main;
|
||||||
if (_bakeCamera) return _bakeCamera;
|
|
||||||
|
|
||||||
// Find existing baking camera.
|
// When render mode is ScreenSpaceCamera or WorldSpace, use world camera.
|
||||||
var childCount = transform.childCount;
|
var root = canvas.rootCanvas;
|
||||||
for (var i = 0; i < childCount; i++)
|
if (root.renderMode != RenderMode.ScreenSpaceOverlay)
|
||||||
{
|
{
|
||||||
if (transform.GetChild(i).TryGetComponent<Camera>(out var cam)
|
return root.worldCamera ? root.worldCamera : Camera.main;
|
||||||
&& cam.name == "[generated] UIParticle BakingCamera")
|
}
|
||||||
|
|
||||||
|
// When render mode is ScreenSpaceOverlay, use ortho-camera.
|
||||||
|
if (!_orthoCamera)
|
||||||
|
{
|
||||||
|
// Find existing ortho-camera.
|
||||||
|
foreach (Transform child in transform)
|
||||||
{
|
{
|
||||||
_bakeCamera = cam;
|
var cam = child.GetComponent<Camera>();
|
||||||
break;
|
if (cam && cam.name == "[generated] UIParticleOverlayCamera")
|
||||||
|
{
|
||||||
|
_orthoCamera = cam;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create ortho-camera.
|
||||||
|
if (!_orthoCamera)
|
||||||
|
{
|
||||||
|
var go = new GameObject("[generated] UIParticleOverlayCamera")
|
||||||
|
{
|
||||||
|
hideFlags = HideFlags.HideAndDontSave
|
||||||
|
};
|
||||||
|
go.SetActive(false);
|
||||||
|
go.transform.SetParent(transform, false);
|
||||||
|
_orthoCamera = go.AddComponent<Camera>();
|
||||||
|
_orthoCamera.enabled = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create baking camera.
|
//
|
||||||
if (!_bakeCamera)
|
var size = ((RectTransform)root.transform).rect.size;
|
||||||
|
_orthoCamera.orthographicSize = Mathf.Max(size.x, size.y) * root.scaleFactor;
|
||||||
|
_orthoCamera.transform.SetPositionAndRotation(new Vector3(0, 0, -1000), Quaternion.identity);
|
||||||
|
_orthoCamera.orthographic = true;
|
||||||
|
_orthoCamera.farClipPlane = 2000f;
|
||||||
|
|
||||||
|
return _orthoCamera;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateTracker()
|
||||||
|
{
|
||||||
|
#pragma warning disable CS0618 // Type or member is obsolete
|
||||||
|
if (!enabled || !autoScaling || autoScalingMode != AutoScalingMode.Transform)
|
||||||
|
#pragma warning restore CS0618 // Type or member is obsolete
|
||||||
{
|
{
|
||||||
var go = new GameObject("[generated] UIParticle BakingCamera")
|
_tracker.Clear();
|
||||||
{
|
}
|
||||||
hideFlags = HideFlags.HideAndDontSave
|
else
|
||||||
};
|
{
|
||||||
go.SetActive(false);
|
_tracker.Add(this, rectTransform, DrivenTransformProperties.Scale);
|
||||||
go.transform.SetParent(transform, false);
|
|
||||||
_bakeCamera = go.AddComponent<Camera>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup baking camera.
|
|
||||||
_bakeCamera.enabled = false;
|
|
||||||
_bakeCamera.orthographicSize = 1000;
|
|
||||||
_bakeCamera.transform.SetPositionAndRotation(new Vector3(0, 0, -1000), Quaternion.identity);
|
|
||||||
_bakeCamera.orthographic = true;
|
|
||||||
_bakeCamera.farClipPlane = 2000f;
|
|
||||||
_bakeCamera.clearFlags = CameraClearFlags.Nothing;
|
|
||||||
_bakeCamera.cullingMask = 0; // Nothing
|
|
||||||
_bakeCamera.allowHDR = false;
|
|
||||||
_bakeCamera.allowMSAA = false;
|
|
||||||
_bakeCamera.renderingPath = RenderingPath.Forward;
|
|
||||||
_bakeCamera.useOcclusionCulling = false;
|
|
||||||
|
|
||||||
return _bakeCamera;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,28 +0,0 @@
|
|||||||
#pragma warning disable CS0414
|
|
||||||
using Coffee.UIParticleInternal;
|
|
||||||
using UnityEditor;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
namespace Coffee.UIExtensions
|
|
||||||
{
|
|
||||||
public class UIParticleProjectSettings : PreloadedProjectSettings<UIParticleProjectSettings>
|
|
||||||
{
|
|
||||||
[Header("Setting")]
|
|
||||||
[SerializeField]
|
|
||||||
internal bool m_EnableLinearToGamma = true;
|
|
||||||
|
|
||||||
public static bool enableLinearToGamma
|
|
||||||
{
|
|
||||||
get => instance.m_EnableLinearToGamma;
|
|
||||||
set => instance.m_EnableLinearToGamma = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if UNITY_EDITOR
|
|
||||||
[SettingsProvider]
|
|
||||||
private static SettingsProvider CreateSettingsProvider()
|
|
||||||
{
|
|
||||||
return new PreloadedProjectSettingsProvider("Project/UI/UI Particle");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -22,25 +22,25 @@ namespace Coffee.UIExtensions
|
|||||||
[AddComponentMenu("")]
|
[AddComponentMenu("")]
|
||||||
internal class UIParticleRenderer : MaskableGraphic
|
internal class UIParticleRenderer : MaskableGraphic
|
||||||
{
|
{
|
||||||
|
private static readonly List<Component> s_Components = new List<Component>();
|
||||||
private static readonly CombineInstance[] s_CombineInstances = { new CombineInstance() };
|
private static readonly CombineInstance[] s_CombineInstances = { new CombineInstance() };
|
||||||
private static readonly List<Material> s_Materials = new List<Material>(2);
|
private static readonly List<Material> s_Materials = new List<Material>(2);
|
||||||
private static MaterialPropertyBlock s_Mpb;
|
private static MaterialPropertyBlock s_Mpb;
|
||||||
private static readonly List<UIParticleRenderer> s_Renderers = new List<UIParticleRenderer>(8);
|
private static readonly List<UIParticleRenderer> s_Renderers = new List<UIParticleRenderer>();
|
||||||
|
private static readonly List<Color32> s_Colors = new List<Color32>();
|
||||||
private static readonly Vector3[] s_Corners = new Vector3[4];
|
private static readonly Vector3[] s_Corners = new Vector3[4];
|
||||||
private bool _delay;
|
private bool _delay;
|
||||||
private int _index;
|
private int _index;
|
||||||
private bool _isTrail;
|
private bool _isTrail;
|
||||||
private Bounds _lastBounds;
|
private Bounds _lastBounds;
|
||||||
private Material _materialForRendering;
|
|
||||||
private Material _modifiedMaterial;
|
private Material _modifiedMaterial;
|
||||||
private UIParticle _parent;
|
private UIParticle _parent;
|
||||||
private ParticleSystem _particleSystem;
|
private ParticleSystem _particleSystem;
|
||||||
private float _prevCanvasScale;
|
private float _prevCanvasScale;
|
||||||
private Vector3 _prevPsPos;
|
private Vector3 _prevPsPos;
|
||||||
private Vector3 _prevScale;
|
private Vector3 _prevScale;
|
||||||
private bool _isPrevStored;
|
|
||||||
private Vector2Int _prevScreenSize;
|
private Vector2Int _prevScreenSize;
|
||||||
private bool _preWarm;
|
private bool _prewarm;
|
||||||
private ParticleSystemRenderer _renderer;
|
private ParticleSystemRenderer _renderer;
|
||||||
|
|
||||||
public override Texture mainTexture => _isTrail ? null : _particleSystem.GetTextureForSprite();
|
public override Texture mainTexture => _isTrail ? null : _particleSystem.GetTextureForSprite();
|
||||||
@@ -91,19 +91,6 @@ namespace Coffee.UIExtensions
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Material materialForRendering
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (!_materialForRendering)
|
|
||||||
{
|
|
||||||
_materialForRendering = base.materialForRendering;
|
|
||||||
}
|
|
||||||
|
|
||||||
return _materialForRendering;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Reset(int index = -1)
|
public void Reset(int index = -1)
|
||||||
{
|
{
|
||||||
if (_renderer)
|
if (_renderer)
|
||||||
@@ -123,7 +110,8 @@ namespace Coffee.UIExtensions
|
|||||||
if (this && isActiveAndEnabled)
|
if (this && isActiveAndEnabled)
|
||||||
{
|
{
|
||||||
material = null;
|
material = null;
|
||||||
canvasRenderer.Clear();
|
workerMesh.Clear();
|
||||||
|
canvasRenderer.SetMesh(workerMesh);
|
||||||
_lastBounds = new Bounds();
|
_lastBounds = new Bounds();
|
||||||
enabled = false;
|
enabled = false;
|
||||||
}
|
}
|
||||||
@@ -154,7 +142,6 @@ namespace Coffee.UIExtensions
|
|||||||
|
|
||||||
MaterialRepository.Release(ref _modifiedMaterial);
|
MaterialRepository.Release(ref _modifiedMaterial);
|
||||||
_materialForRendering = null;
|
_materialForRendering = null;
|
||||||
_isPrevStored = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static UIParticleRenderer AddRenderer(UIParticle parent, int index)
|
public static UIParticleRenderer AddRenderer(UIParticle parent, int index)
|
||||||
@@ -215,11 +202,10 @@ namespace Coffee.UIExtensions
|
|||||||
);
|
);
|
||||||
if (!MaterialRepository.Valid(hash, _modifiedMaterial))
|
if (!MaterialRepository.Valid(hash, _modifiedMaterial))
|
||||||
{
|
{
|
||||||
MaterialRepository.Get(hash, ref _modifiedMaterial, x => new Material(x.mat)
|
MaterialRepository.Get(hash, ref _modifiedMaterial, () => new Material(modifiedMaterial)
|
||||||
{
|
{
|
||||||
hideFlags = HideFlags.HideAndDontSave,
|
hideFlags = HideFlags.HideAndDontSave
|
||||||
mainTexture = x.texture ? x.texture : x.mat.mainTexture
|
});
|
||||||
}, (mat: modifiedMaterial, texture));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return _modifiedMaterial;
|
return _modifiedMaterial;
|
||||||
@@ -233,20 +219,20 @@ namespace Coffee.UIExtensions
|
|||||||
gameObject.layer = parent.gameObject.layer;
|
gameObject.layer = parent.gameObject.layer;
|
||||||
|
|
||||||
_particleSystem = ps;
|
_particleSystem = ps;
|
||||||
_preWarm = _particleSystem.main.prewarm;
|
_prewarm = _particleSystem.main.prewarm;
|
||||||
|
|
||||||
#if UNITY_EDITOR
|
#if UNITY_EDITOR
|
||||||
if (Application.isPlaying)
|
if (Application.isPlaying)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
if (_particleSystem.isPlaying || _preWarm)
|
if (_particleSystem.isPlaying || _prewarm)
|
||||||
{
|
{
|
||||||
_particleSystem.Clear();
|
_particleSystem.Clear();
|
||||||
_particleSystem.Pause();
|
_particleSystem.Pause();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ps.TryGetComponent(out _renderer);
|
_renderer = ps.GetComponent<ParticleSystemRenderer>();
|
||||||
_renderer.enabled = false;
|
_renderer.enabled = false;
|
||||||
|
|
||||||
//_emitter = emitter;
|
//_emitter = emitter;
|
||||||
@@ -418,7 +404,7 @@ namespace Coffee.UIExtensions
|
|||||||
_lastBounds = bounds;
|
_lastBounds = bounds;
|
||||||
|
|
||||||
// Convert linear color to gamma color.
|
// Convert linear color to gamma color.
|
||||||
if (UIParticleProjectSettings.enableLinearToGamma && canvas.ShouldGammaToLinearInMesh())
|
if (canvas.ShouldGammaToLinearInMesh())
|
||||||
{
|
{
|
||||||
workerMesh.LinearToGamma();
|
workerMesh.LinearToGamma();
|
||||||
}
|
}
|
||||||
@@ -438,49 +424,66 @@ namespace Coffee.UIExtensions
|
|||||||
|
|
||||||
Profiler.EndSample();
|
Profiler.EndSample();
|
||||||
|
|
||||||
// Update animatable material properties.
|
|
||||||
Profiler.BeginSample("[UIParticleRenderer] Update Animatable Material Properties");
|
|
||||||
UpdateMaterialProperties();
|
|
||||||
Profiler.EndSample();
|
|
||||||
|
|
||||||
// Get grouped renderers.
|
// Get grouped renderers.
|
||||||
Profiler.BeginSample("[UIParticleRenderer] Set Mesh");
|
|
||||||
s_Renderers.Clear();
|
s_Renderers.Clear();
|
||||||
if (_parent.useMeshSharing)
|
if (_parent.useMeshSharing)
|
||||||
{
|
{
|
||||||
UIParticleUpdater.GetGroupedRenderers(_parent.groupId, _index, s_Renderers);
|
UIParticleUpdater.GetGroupedRenderers(_parent.groupId, _index, s_Renderers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set mesh to the CanvasRenderer.
|
||||||
|
Profiler.BeginSample("[UIParticleRenderer] Set Mesh");
|
||||||
for (var i = 0; i < s_Renderers.Count; i++)
|
for (var i = 0; i < s_Renderers.Count; i++)
|
||||||
{
|
{
|
||||||
if (s_Renderers[i] == this) continue;
|
if (s_Renderers[i] == this) continue;
|
||||||
|
|
||||||
s_Renderers[i].canvasRenderer.SetMesh(workerMesh);
|
s_Renderers[i].canvasRenderer.SetMesh(workerMesh);
|
||||||
s_Renderers[i]._lastBounds = _lastBounds;
|
s_Renderers[i]._lastBounds = _lastBounds;
|
||||||
s_Renderers[i].canvasRenderer.materialCount = 1;
|
|
||||||
s_Renderers[i].canvasRenderer.SetMaterial(materialForRendering, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_parent.canRender)
|
if (!_parent.canRender)
|
||||||
{
|
|
||||||
canvasRenderer.SetMesh(workerMesh);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
workerMesh.Clear();
|
workerMesh.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
canvasRenderer.SetMesh(workerMesh);
|
||||||
|
Profiler.EndSample();
|
||||||
|
|
||||||
|
// Update animatable material properties.
|
||||||
|
Profiler.BeginSample("[UIParticleRenderer] Update Animatable Material Properties");
|
||||||
|
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
if (_modifiedMaterial != material)
|
||||||
|
{
|
||||||
|
_renderer.GetSharedMaterials(s_Materials);
|
||||||
|
material = s_Materials[_isTrail ? 1 : 0];
|
||||||
|
s_Materials.Clear();
|
||||||
|
SetMaterialDirty();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
UpdateMaterialProperties();
|
||||||
|
if (_parent.useMeshSharing)
|
||||||
|
{
|
||||||
|
if (!_currentMaterialForRendering)
|
||||||
|
{
|
||||||
|
_currentMaterialForRendering = materialForRendering;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < s_Renderers.Count; i++)
|
||||||
|
{
|
||||||
|
if (s_Renderers[i] == this) continue;
|
||||||
|
|
||||||
|
s_Renderers[i].canvasRenderer.materialCount = 1;
|
||||||
|
s_Renderers[i].canvasRenderer.SetMaterial(_currentMaterialForRendering, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Profiler.EndSample();
|
Profiler.EndSample();
|
||||||
|
|
||||||
s_Renderers.Clear();
|
s_Renderers.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void SetMaterialDirty()
|
|
||||||
{
|
|
||||||
_materialForRendering = null;
|
|
||||||
base.SetMaterialDirty();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Call to update the geometry of the Graphic onto the CanvasRenderer.
|
/// Call to update the geometry of the Graphic onto the CanvasRenderer.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -510,7 +513,7 @@ namespace Coffee.UIExtensions
|
|||||||
&& _particleSystem.main.scalingMode == ParticleSystemScalingMode.Local
|
&& _particleSystem.main.scalingMode == ParticleSystemScalingMode.Local
|
||||||
&& _parent.canvas)
|
&& _parent.canvas)
|
||||||
{
|
{
|
||||||
scale = scale.GetScaled(_parent.canvas.rootCanvas.transform.localScale);
|
scale = scale.GetScaled(_parent.canvas.transform.localScale);
|
||||||
}
|
}
|
||||||
|
|
||||||
Profiler.EndSample();
|
Profiler.EndSample();
|
||||||
@@ -547,7 +550,10 @@ namespace Coffee.UIExtensions
|
|||||||
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))
|
||||||
* Matrix4x4.Scale(scale);
|
//* Matrix4x4.Translate(wpos)
|
||||||
|
* Matrix4x4.Scale(scale)
|
||||||
|
//* Matrix4x4.Translate(-wpos)
|
||||||
|
;
|
||||||
default:
|
default:
|
||||||
throw new NotSupportedException();
|
throw new NotSupportedException();
|
||||||
}
|
}
|
||||||
@@ -563,16 +569,15 @@ namespace Coffee.UIExtensions
|
|||||||
var screenSize = new Vector2Int(Screen.width, Screen.height);
|
var screenSize = new Vector2Int(Screen.width, Screen.height);
|
||||||
var isWorldSpace = _particleSystem.IsWorldSpace();
|
var isWorldSpace = _particleSystem.IsWorldSpace();
|
||||||
var canvasScale = _parent.canvas ? _parent.canvas.scaleFactor : 1f;
|
var canvasScale = _parent.canvas ? _parent.canvas.scaleFactor : 1f;
|
||||||
var resolutionChanged = _prevScreenSize != screenSize
|
var resolutionChanged = _prevScreenSize != screenSize || _prevCanvasScale != canvasScale;
|
||||||
|| !Mathf.Approximately(_prevCanvasScale, canvasScale);
|
if (resolutionChanged && isWorldSpace)
|
||||||
if (resolutionChanged && isWorldSpace && _isPrevStored)
|
|
||||||
{
|
{
|
||||||
// Update particle array size and get particles.
|
// Update particle array size and get particles.
|
||||||
var size = _particleSystem.particleCount;
|
var size = _particleSystem.particleCount;
|
||||||
var particles = ParticleSystemExtensions.GetParticleArray(size);
|
var particles = ParticleSystemExtensions.GetParticleArray(size);
|
||||||
_particleSystem.GetParticles(particles, size);
|
_particleSystem.GetParticles(particles, size);
|
||||||
|
|
||||||
// Resolution resolver:
|
// Resolusion resolver:
|
||||||
// (psPos / scale) / (prevPsPos / prevScale) -> psPos * scale.inv * prevPsPos.inv * prevScale
|
// (psPos / scale) / (prevPsPos / prevScale) -> psPos * scale.inv * prevPsPos.inv * prevScale
|
||||||
var modifier = psPos.GetScaled(
|
var modifier = psPos.GetScaled(
|
||||||
scale.Inverse(),
|
scale.Inverse(),
|
||||||
@@ -591,7 +596,6 @@ namespace Coffee.UIExtensions
|
|||||||
_delay = true;
|
_delay = true;
|
||||||
_prevScale = scale;
|
_prevScale = scale;
|
||||||
_prevPsPos = psPos;
|
_prevPsPos = psPos;
|
||||||
_isPrevStored = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_prevCanvasScale = canvas ? canvas.scaleFactor : 1f;
|
_prevCanvasScale = canvas ? canvas.scaleFactor : 1f;
|
||||||
@@ -607,25 +611,23 @@ namespace Coffee.UIExtensions
|
|||||||
? Time.unscaledDeltaTime
|
? Time.unscaledDeltaTime
|
||||||
: Time.deltaTime;
|
: Time.deltaTime;
|
||||||
|
|
||||||
// Pre-warm:
|
// Prewarm:
|
||||||
if (0 < deltaTime && _preWarm)
|
if (0 < deltaTime && _prewarm)
|
||||||
{
|
{
|
||||||
deltaTime += main.duration;
|
deltaTime += main.duration;
|
||||||
_preWarm = false;
|
_prewarm = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// get world position.
|
// get world position.
|
||||||
var isLocalSpace = _particleSystem.IsLocalSpace();
|
var isLocalSpace = _particleSystem.IsLocalSpace();
|
||||||
var psTransform = _particleSystem.transform;
|
var psTransform = _particleSystem.transform;
|
||||||
var originLocalPosition = psTransform.localPosition;
|
|
||||||
var originLocalRotation = psTransform.localRotation;
|
|
||||||
var originWorldPosition = psTransform.position;
|
var originWorldPosition = psTransform.position;
|
||||||
var originWorldRotation = psTransform.rotation;
|
var originWorldRotation = psTransform.rotation;
|
||||||
var emission = _particleSystem.emission;
|
var emission = _particleSystem.emission;
|
||||||
var rateOverDistance = emission.enabled
|
var rateOverDistance = emission.enabled
|
||||||
&& 0 < emission.rateOverDistance.constant
|
&& 0 < emission.rateOverDistance.constant
|
||||||
&& 0 < emission.rateOverDistanceMultiplier;
|
&& 0 < emission.rateOverDistanceMultiplier;
|
||||||
if (rateOverDistance && !paused && _isPrevStored)
|
if (rateOverDistance && !paused)
|
||||||
{
|
{
|
||||||
// (For rate-over-distance emission,) Move to previous scaled position, simulate (delta = 0).
|
// (For rate-over-distance emission,) Move to previous scaled position, simulate (delta = 0).
|
||||||
var prevScaledPos = isLocalSpace
|
var prevScaledPos = isLocalSpace
|
||||||
@@ -641,8 +643,7 @@ namespace Coffee.UIExtensions
|
|||||||
: originWorldPosition.GetScaled(scale.Inverse());
|
: originWorldPosition.GetScaled(scale.Inverse());
|
||||||
psTransform.SetPositionAndRotation(scaledPos, originWorldRotation);
|
psTransform.SetPositionAndRotation(scaledPos, originWorldRotation);
|
||||||
_particleSystem.Simulate(deltaTime, false, false, false);
|
_particleSystem.Simulate(deltaTime, false, false, false);
|
||||||
psTransform.localPosition = originLocalPosition;
|
psTransform.SetPositionAndRotation(originWorldPosition, originWorldRotation);
|
||||||
psTransform.localRotation = originLocalRotation;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if UNITY_EDITOR
|
#if UNITY_EDITOR
|
||||||
@@ -686,12 +687,12 @@ namespace Coffee.UIExtensions
|
|||||||
if (s_Mpb.isEmpty) return;
|
if (s_Mpb.isEmpty) return;
|
||||||
|
|
||||||
// #41: Copy the value from MaterialPropertyBlock to CanvasRenderer
|
// #41: Copy the value from MaterialPropertyBlock to CanvasRenderer
|
||||||
if (!materialForRendering) return;
|
if (!_modifiedMaterial) return;
|
||||||
|
|
||||||
for (var i = 0; i < _parent.m_AnimatableProperties.Length; i++)
|
for (var i = 0; i < _parent.m_AnimatableProperties.Length; i++)
|
||||||
{
|
{
|
||||||
var ap = _parent.m_AnimatableProperties[i];
|
var ap = _parent.m_AnimatableProperties[i];
|
||||||
ap.UpdateMaterialProperties(materialForRendering, s_Mpb);
|
ap.UpdateMaterialProperties(_modifiedMaterial, s_Mpb);
|
||||||
}
|
}
|
||||||
|
|
||||||
s_Mpb.Clear();
|
s_Mpb.Clear();
|
||||||
|
|||||||
@@ -58,8 +58,9 @@ namespace Coffee.UIExtensions
|
|||||||
for (var i = 0; i < s_ActiveParticles.Count; i++)
|
for (var i = 0; i < s_ActiveParticles.Count; i++)
|
||||||
{
|
{
|
||||||
var uip = s_ActiveParticles[i];
|
var uip = s_ActiveParticles[i];
|
||||||
if (!uip || !uip.canvas || !uip.isPrimary || !s_UpdatedGroupIds.Add(uip.groupId)) continue;
|
if (!uip || !uip.canvas || !uip.isPrimary || s_UpdatedGroupIds.Contains(uip.groupId)) continue;
|
||||||
|
|
||||||
|
s_UpdatedGroupIds.Add(uip.groupId);
|
||||||
uip.UpdateTransformScale();
|
uip.UpdateTransformScale();
|
||||||
uip.UpdateRenderers();
|
uip.UpdateRenderers();
|
||||||
}
|
}
|
||||||
@@ -76,8 +77,9 @@ namespace Coffee.UIExtensions
|
|||||||
{
|
{
|
||||||
uip.UpdateRenderers();
|
uip.UpdateRenderers();
|
||||||
}
|
}
|
||||||
else if (s_UpdatedGroupIds.Add(uip.groupId))
|
else if (!s_UpdatedGroupIds.Contains(uip.groupId))
|
||||||
{
|
{
|
||||||
|
s_UpdatedGroupIds.Add(uip.groupId);
|
||||||
uip.UpdateRenderers();
|
uip.UpdateRenderers();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14461,7 +14461,7 @@ Canvas:
|
|||||||
m_GameObject: {fileID: 1074082869}
|
m_GameObject: {fileID: 1074082869}
|
||||||
m_Enabled: 1
|
m_Enabled: 1
|
||||||
serializedVersion: 3
|
serializedVersion: 3
|
||||||
m_RenderMode: 1
|
m_RenderMode: 0
|
||||||
m_Camera: {fileID: 1023393581}
|
m_Camera: {fileID: 1023393581}
|
||||||
m_PlaneDistance: 100
|
m_PlaneDistance: 100
|
||||||
m_PixelPerfect: 0
|
m_PixelPerfect: 0
|
||||||
|
|||||||
@@ -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": "5.0.0-preview.3",
|
"version": "4.6.4",
|
||||||
"unity": "2018.2",
|
"unity": "2018.2",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
|||||||
Reference in New Issue
Block a user