You've already forked ParticleEffectForUGUI
mirror of
https://github.com/mob-sakai/ParticleEffectForUGUI.git
synced 2026-05-15 12:40:08 +00:00
Compare commits
92 Commits
v5.0.0-pre
...
develop
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d89d394e04 | ||
|
|
031d46a321 | ||
|
|
af0e98239b | ||
|
|
5384f61c56 | ||
|
|
fed927559f | ||
|
|
eb2e862e80 | ||
|
|
d1386a1221 | ||
|
|
9d56c94636 | ||
|
|
fe179c0f0f | ||
|
|
df2f3caafb | ||
|
|
1c8c65d25e | ||
|
|
a9461ecb4d | ||
|
|
38aec2ea1a | ||
|
|
bb2d588e0c | ||
|
|
078005a1a7 | ||
|
|
0cff50ef69 | ||
|
|
0da652520c | ||
|
|
4199492e3a | ||
|
|
1f88bb255e | ||
|
|
e3791866b7 | ||
|
|
6dfbdae38d | ||
|
|
b63220b871 | ||
|
|
3fd2bea599 | ||
|
|
925af0b604 | ||
|
|
d1a1e23e50 | ||
|
|
47ee45cbbe | ||
|
|
1b0110320b | ||
|
|
a1ca74f854 | ||
|
|
8276684c3b | ||
|
|
67de3d1bd3 | ||
|
|
90d966e659 | ||
|
|
0036b03d12 | ||
|
|
934f4b8f1c | ||
|
|
fe4fcc5ddd | ||
|
|
072aac521b | ||
|
|
95235a929b | ||
|
|
1a748f19d0 | ||
|
|
f9ce2c6c96 | ||
|
|
abe09485f6 | ||
|
|
253fb52650 | ||
|
|
3544c593e2 | ||
|
|
4faf151c87 | ||
|
|
afe00a1dde | ||
|
|
c1e3d68f60 | ||
|
|
a1ea8785bc | ||
|
|
2ee69d0424 | ||
|
|
2c1ac4b5e9 | ||
|
|
5f255ec6cd | ||
|
|
1b678c68c6 | ||
|
|
5ff6ec815a | ||
|
|
0ee1671246 | ||
|
|
6a7f08c056 | ||
|
|
1ce4e31a96 | ||
|
|
c08f0d492f | ||
|
|
7069b396e4 | ||
|
|
109caed657 | ||
|
|
2a1cd502b4 | ||
|
|
78d0219235 | ||
|
|
de5c617d12 | ||
|
|
15f9d92567 | ||
|
|
55fb8a0076 | ||
|
|
e6d8e43966 | ||
|
|
10a7fb4b7b | ||
|
|
3834780fdb | ||
|
|
307ed1bf01 | ||
|
|
669deb41d4 | ||
|
|
24e0e8697d | ||
|
|
3e3e35beca | ||
|
|
a182709472 | ||
|
|
be901724e0 | ||
|
|
88a970d93a | ||
|
|
a703c2921c | ||
|
|
de35cba34c | ||
|
|
ae3f3a8e62 | ||
|
|
835817049f | ||
|
|
7035583bdb | ||
|
|
0bb8438301 | ||
|
|
e1b66d8d90 | ||
|
|
a8ed6e6858 | ||
|
|
3fc7d9dae4 | ||
|
|
0322d7eb95 | ||
|
|
e7be0e77de | ||
|
|
3880484ce5 | ||
|
|
1d40e24c74 | ||
|
|
54a4b1cdfd | ||
|
|
5505247a94 | ||
|
|
f26920f982 | ||
|
|
5a1e65ec56 | ||
|
|
accd3f8410 | ||
|
|
05286cedfd | ||
|
|
cbd9c960e2 | ||
|
|
e924eb4596 |
@@ -25,6 +25,7 @@ indent_size = 4
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
csharp_style_namespace_declarations = block_scoped
|
||||
csharp_style_implicit_object_creation_when_type_is_apparent = false
|
||||
resharper_object_creation_when_type_evident = explicitly_typed
|
||||
|
||||
@@ -86,6 +87,9 @@ csharp_style_var_elsewhere = true:suggestion
|
||||
dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
|
||||
dotnet_style_predefined_type_for_member_access = true:suggestion
|
||||
|
||||
#
|
||||
resharper_keep_existing_embedded_arrangement = true
|
||||
|
||||
# Arguments
|
||||
csharp_arguments_literal = named:suggestion
|
||||
csharp_arguments_string_literal = named:suggestion
|
||||
@@ -134,7 +138,7 @@ dotnet_naming_style._camel_case.capitalization = camel_case
|
||||
|
||||
# Code style defaults
|
||||
dotnet_sort_system_directives_first = true
|
||||
csharp_preserve_single_line_statements = false:none
|
||||
csharp_preserve_single_line_statements = false
|
||||
csharp_prefer_static_local_function = true:suggestion
|
||||
csharp_prefer_simple_using_statement = false:none
|
||||
csharp_style_prefer_switch_expression = true:suggestion
|
||||
@@ -186,7 +190,7 @@ csharp_space_after_dot = false
|
||||
csharp_space_after_keywords_in_control_flow_statements = true
|
||||
csharp_space_after_semicolon_in_for_statement = true
|
||||
csharp_space_around_binary_operators = before_and_after
|
||||
csharp_space_around_declaration_statements = do_not_ignore
|
||||
csharp_space_around_declaration_statements = false
|
||||
csharp_space_before_colon_in_inheritance_clause = true
|
||||
csharp_space_before_comma = false
|
||||
csharp_space_before_dot = false
|
||||
|
||||
28
.github/workflows/release.yml
vendored
28
.github/workflows/release.yml
vendored
@@ -1,12 +1,12 @@
|
||||
name: 🔖 Release
|
||||
run-name: 🔖 Release (${{ github.ref_name }})
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- release
|
||||
- release-preview
|
||||
- release-v4
|
||||
- release-*
|
||||
tags-ignore:
|
||||
- "**"
|
||||
|
||||
@@ -27,10 +27,10 @@ jobs:
|
||||
split_to: ${{ steps.summary.outputs.split_to }}
|
||||
steps:
|
||||
- name: 🚚 Checkout (${{ github.ref_name }})
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: 🔖 Run semantic release
|
||||
uses: cycjimmy/semantic-release-action@v4
|
||||
uses: cycjimmy/semantic-release-action@v5
|
||||
id: release
|
||||
with:
|
||||
working_directory: Packages/src
|
||||
@@ -38,7 +38,7 @@ jobs:
|
||||
@semantic-release/changelog
|
||||
@semantic-release/git
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
|
||||
|
||||
- id: summary
|
||||
run: |
|
||||
@@ -50,14 +50,12 @@ jobs:
|
||||
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
|
||||
echo "merge_to=develop" | tee -a $GITHUB_OUTPUT $GITHUB_STEP_SUMMARY
|
||||
echo "split_to=main" | tee -a $GITHUB_OUTPUT $GITHUB_STEP_SUMMARY
|
||||
else
|
||||
channel=$(echo ${{ github.ref_name }} | sed 's/^release-//')
|
||||
echo "merge_to=develop-${channel}" | tee -a $GITHUB_OUTPUT $GITHUB_STEP_SUMMARY
|
||||
echo "split_to=${channel}" | tee -a $GITHUB_OUTPUT $GITHUB_STEP_SUMMARY
|
||||
fi
|
||||
|
||||
merge-to:
|
||||
@@ -69,7 +67,7 @@ jobs:
|
||||
contents: write
|
||||
steps:
|
||||
- name: 🚚 Checkout (${{ needs.release.outputs.merge_to }})
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
ref: ${{ needs.release.outputs.merge_to }}
|
||||
fetch-depth: 0
|
||||
@@ -90,7 +88,7 @@ jobs:
|
||||
contents: write
|
||||
steps:
|
||||
- name: 🚚 Checkout (${{ needs.release.outputs.tag }})
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
ref: ${{ needs.release.outputs.tag }}
|
||||
fetch-depth: 0
|
||||
|
||||
77
.github/workflows/test.yml
vendored
77
.github/workflows/test.yml
vendored
@@ -3,28 +3,37 @@
|
||||
# UNITY_EMAIL: Unity user email to login
|
||||
# UNITY_PASSWORD: Unity user password to login
|
||||
name: 🧪 Test
|
||||
run-name: 🧪 Test (${{ github.event.pull_request.title || github.ref_name }})
|
||||
|
||||
env:
|
||||
# MINIMUM_VERSION: The minimum version of Unity.
|
||||
MINIMUM_VERSION: 2019.4
|
||||
# EXCLUDE_FILTER: The excluded versions of Unity.
|
||||
EXCLUDE_FILTER: '(2020.2.0)'
|
||||
EXCLUDE_FILTER: "(2020.2.0|2021.1|2023.3)"
|
||||
PROJECT_PATH: .
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
usePeriodVersions:
|
||||
description: "Use the period versions (.0f1, .10f1, 20f1, ...)."
|
||||
required: false
|
||||
default: "true"
|
||||
push:
|
||||
branches:
|
||||
- develop
|
||||
- develop-preview
|
||||
- develop-4.x
|
||||
- "develop-*"
|
||||
tags:
|
||||
- "!*"
|
||||
paths-ignore:
|
||||
- "*.md"
|
||||
pull_request:
|
||||
- "**.md"
|
||||
pull_request_target:
|
||||
types:
|
||||
- opened
|
||||
- reopened
|
||||
- synchronize
|
||||
paths-ignore:
|
||||
- "**.md"
|
||||
|
||||
jobs:
|
||||
setup:
|
||||
@@ -37,9 +46,12 @@ jobs:
|
||||
id: setup
|
||||
run: |
|
||||
echo "==== Target Unity Versions ===="
|
||||
LATEST_VERSIONS=`npx unity-changeset list --versions --latest-patch --min ${MINIMUM_VERSION} --json --all`
|
||||
# ADDITIONAL_VERSIONS=`npx unity-changeset list --versions --grep '0f' --min ${MINIMUM_VERSION} --json`
|
||||
ADDITIONAL_VERSIONS=[]
|
||||
LATEST_VERSIONS=`npx unity-changeset@latest list --versions --latest-patch --min ${MINIMUM_VERSION} --json --all`
|
||||
if [ "${{ inputs.usePeriodVersions }}" = "true" ]; then
|
||||
ADDITIONAL_VERSIONS=`npx unity-changeset list --versions --grep '0f' --min ${MINIMUM_VERSION} --json`
|
||||
else
|
||||
ADDITIONAL_VERSIONS=[]
|
||||
fi
|
||||
|
||||
VERSIONS=`echo "[${LATEST_VERSIONS}, ${ADDITIONAL_VERSIONS}]" \
|
||||
| jq -c '[ flatten | sort | unique | .[] | select( test("${{ env.EXCLUDE_FILTER }}") | not ) ]'`
|
||||
@@ -48,40 +60,57 @@ jobs:
|
||||
test:
|
||||
name: 🧪 Run tests
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
|
||||
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
|
||||
UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }}
|
||||
permissions:
|
||||
checks: write
|
||||
contents: read
|
||||
needs: setup
|
||||
strategy:
|
||||
fail-fast: false
|
||||
max-parallel: 4
|
||||
max-parallel: 6
|
||||
matrix:
|
||||
unityVersion: ${{ fromJson(needs.setup.outputs.unityVersions) }}
|
||||
steps:
|
||||
- name: 🚚 Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: 🚚 Checkout ($${{ github.ref }})
|
||||
if: github.event_name == 'push'
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: 🚚 Checkout pull request (pull_request_target)
|
||||
if: github.event_name == 'pull_request_target'
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
fetch-depth: 0
|
||||
|
||||
- name: 🚚 Marge pull request (pull_request_target)
|
||||
if: github.event_name == 'pull_request_target'
|
||||
run: |
|
||||
git config user.name "GitHub Actions"
|
||||
git config user.email "actions@github.com"
|
||||
git rebase ${{ github.event.pull_request.base.sha }}
|
||||
git log --oneline -n 10
|
||||
|
||||
- name: 📥 Cache library
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: Library
|
||||
key: Library-${{ matrix.unityVersion }}-${{ github.sha }}
|
||||
path: ${{ env.PROJECT_PATH }}/Library
|
||||
key: ${{ env.PROJECT_PATH }}-Library-${{ matrix.unityVersion }}-${{ github.event.pull_request.head.sha || github.sha }}
|
||||
restore-keys: |
|
||||
Library-${{ matrix.unityVersion }}-
|
||||
Library-
|
||||
${{ env.PROJECT_PATH }}-Library-${{ matrix.unityVersion }}-
|
||||
${{ env.PROJECT_PATH }}-Library-
|
||||
|
||||
- name: 🛠️ Build Unity Project
|
||||
uses: game-ci/unity-builder@v4
|
||||
- name: 🛠️ Build Unity Project (Test)
|
||||
uses: game-ci/unity-builder@main
|
||||
timeout-minutes: 45
|
||||
with:
|
||||
customImage: ghcr.io/mob-sakai/unity3d:${{ matrix.unityVersion }}
|
||||
targetPlatform: StandaloneLinux64
|
||||
allowDirtyBuild: true
|
||||
customParameters: -nographics
|
||||
projectPath: ${{ env.PROJECT_PATH }}
|
||||
env:
|
||||
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
|
||||
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
|
||||
UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }}
|
||||
|
||||
- name: 🧪 Run tests
|
||||
uses: game-ci/unity-test-runner@v4
|
||||
@@ -92,4 +121,8 @@ jobs:
|
||||
customParameters: -nographics
|
||||
checkName: ${{ matrix.unityVersion }} Test Results
|
||||
githubToken: ${{ github.token }}
|
||||
coverageOptions: "dontClear;generateHtmlReport;generateBadgeReport;pathFilters:+**/Packages/src/**;assemblyFilters:+<packages>,-*.Editor,-*.Test"
|
||||
projectPath: ${{ env.PROJECT_PATH }}
|
||||
env:
|
||||
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
|
||||
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
|
||||
UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }}
|
||||
|
||||
7046
Assets/Demo/Cartoon FX & War FX Demo/CFXRF Demo.unity
Normal file
7046
Assets/Demo/Cartoon FX & War FX Demo/CFXRF Demo.unity
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e34a092899a9547189add96707de1b5a
|
||||
DefaultImporter:
|
||||
userData:
|
||||
@@ -80,7 +80,11 @@ namespace Coffee.UIExtensions.Demo
|
||||
.SelectMany(x => x.GetTypes())
|
||||
.FirstOrDefault(x => x.Name == typeName);
|
||||
|
||||
#if UNITY_2023_2_OR_NEWER
|
||||
return type == null ? null : FindFirstObjectByType(type);
|
||||
#else
|
||||
return type == null ? null : FindObjectOfType(type);
|
||||
#endif
|
||||
}
|
||||
|
||||
public void SetCanvasWidth(int width)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3e440931f761e4e888510a4e6045287a
|
||||
guid: 157d70e6cb69d4581b4ed450c7ffd33d
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
20178
Assets/Demo/CustomView/CustomView.unity
Normal file
20178
Assets/Demo/CustomView/CustomView.unity
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7a55e246f37df405bac88eac692e3a86
|
||||
folderAsset: yes
|
||||
guid: dfba9a6f2258941f5b4429fba806d8e9
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
42
Assets/Demo/CustomView/UI-Cloud.mat
Normal file
42
Assets/Demo/CustomView/UI-Cloud.mat
Normal file
@@ -0,0 +1,42 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 8
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: UI-Cloud
|
||||
m_Shader: {fileID: 4800000, guid: 6b5e4f608f0684d10a4673a7e1cee0f3, type: 3}
|
||||
m_ValidKeywords: []
|
||||
m_InvalidKeywords:
|
||||
- _COLORMODE_MULTIPRY
|
||||
m_LightmapFlags: 4
|
||||
m_EnableInstancingVariants: 0
|
||||
m_DoubleSidedGI: 0
|
||||
m_CustomRenderQueue: -1
|
||||
stringTagMap: {}
|
||||
disabledShaderPasses: []
|
||||
m_SavedProperties:
|
||||
serializedVersion: 3
|
||||
m_TexEnvs:
|
||||
- _MainTex:
|
||||
m_Texture: {fileID: 2800000, guid: 48901c5d75f8c456aa8f4cd3a6b0160e, type: 3}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_Ints: []
|
||||
m_Floats:
|
||||
- _ColorMask: 15
|
||||
- _ColorMode: 0
|
||||
- _DstBlend: 10
|
||||
- _SrcBlend: 1
|
||||
- _Stencil: 0
|
||||
- _StencilComp: 8
|
||||
- _StencilOp: 0
|
||||
- _StencilReadMask: 255
|
||||
- _StencilWriteMask: 255
|
||||
- _UseUIAlphaClip: 0
|
||||
m_Colors:
|
||||
- _Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_BuildTextureStacks: []
|
||||
@@ -1,8 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: be3e05903ef7041d39b3ef8ecdd47f08
|
||||
guid: 607b55fe0d4534a56902644d3797abed
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
||||
mainObjectFileID: 2100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/Demo/CustomView/UI-Cloud.png
Normal file
BIN
Assets/Demo/CustomView/UI-Cloud.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 27 KiB |
147
Assets/Demo/CustomView/UI-Cloud.png.meta
Normal file
147
Assets/Demo/CustomView/UI-Cloud.png.meta
Normal file
@@ -0,0 +1,147 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 48901c5d75f8c456aa8f4cd3a6b0160e
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 12
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
sRGBTexture: 1
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
vTOnly: 0
|
||||
ignoreMasterTextureLimit: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: 1
|
||||
aniso: 1
|
||||
mipBias: 0
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: 1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 1
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 0
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
flipbookRows: 1
|
||||
flipbookColumns: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
ignorePngGamma: 0
|
||||
applyGammaDecoding: 1
|
||||
cookieLightType: 1
|
||||
platformSettings:
|
||||
- serializedVersion: 3
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 256
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: Standalone
|
||||
maxTextureSize: 256
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: Android
|
||||
maxTextureSize: 256
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 1
|
||||
- serializedVersion: 3
|
||||
buildTarget: WebGL
|
||||
maxTextureSize: 256
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: Server
|
||||
maxTextureSize: 256
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID: 5e97eb03825dee720800000000000000
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
nameFileIdTable: {}
|
||||
spritePackingTag:
|
||||
pSDRemoveMatte: 0
|
||||
pSDShowRemoveMatteOption: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
177
Assets/Demo/CustomView/UI-Color.shader
Normal file
177
Assets/Demo/CustomView/UI-Color.shader
Normal file
@@ -0,0 +1,177 @@
|
||||
Shader "UI/Color"
|
||||
{
|
||||
Properties
|
||||
{
|
||||
_MainTex ("Main Texture", 2D) = "white" {}
|
||||
_Color ("Tint", Color) = (1,1,1,1)
|
||||
[KeywordEnum(Multipry, Additive, Subtract, Fill)] _ColorMode ("Color Mode", Int) = 0
|
||||
[Enum(UnityEngine.Rendering.BlendMode)] _SrcBlend ("Src Blend Mode", Int) = 1
|
||||
[Enum(UnityEngine.Rendering.BlendMode)] _DstBlend ("Dst Blend Mode", Int) = 10
|
||||
|
||||
_StencilComp ("Stencil Comparison", Float) = 8
|
||||
_Stencil ("Stencil ID", Float) = 0
|
||||
_StencilOp ("Stencil Operation", Float) = 0
|
||||
_StencilWriteMask ("Stencil Write Mask", Float) = 255
|
||||
_StencilReadMask ("Stencil Read Mask", Float) = 255
|
||||
|
||||
_ColorMask ("Color Mask", Float) = 15
|
||||
|
||||
[Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0
|
||||
}
|
||||
|
||||
SubShader
|
||||
{
|
||||
Tags
|
||||
{
|
||||
"Queue"="Transparent"
|
||||
"IgnoreProjector"="True"
|
||||
"RenderType"="Transparent"
|
||||
"PreviewType"="Plane"
|
||||
"CanUseSpriteAtlas"="True"
|
||||
}
|
||||
|
||||
Stencil
|
||||
{
|
||||
Ref [_Stencil]
|
||||
Comp [_StencilComp]
|
||||
Pass [_StencilOp]
|
||||
ReadMask [_StencilReadMask]
|
||||
WriteMask [_StencilWriteMask]
|
||||
}
|
||||
|
||||
Cull Off
|
||||
Lighting Off
|
||||
ZWrite Off
|
||||
ZTest [unity_GUIZTestMode]
|
||||
Blend [_SrcBlend] [_DstBlend]
|
||||
ColorMask [_ColorMask]
|
||||
|
||||
Pass
|
||||
{
|
||||
Name "Default"
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
#pragma target 2.0
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
#include "UnityUI.cginc"
|
||||
|
||||
#pragma multi_compile_local _ UNITY_UI_CLIP_RECT
|
||||
#pragma multi_compile_local _ UNITY_UI_ALPHACLIP
|
||||
|
||||
sampler2D _MainTex;
|
||||
fixed4 _Color;
|
||||
fixed4 _TextureSampleAdd;
|
||||
float4 _ClipRect;
|
||||
float4 _MainTex_ST;
|
||||
float _UIMaskSoftnessX;
|
||||
float _UIMaskSoftnessY;
|
||||
int _UIVertexColorAlwaysGammaSpace;
|
||||
int _ColorMode;
|
||||
|
||||
struct appdata_t
|
||||
{
|
||||
float4 vertex : POSITION;
|
||||
float4 color : COLOR;
|
||||
float2 texcoord : TEXCOORD0;
|
||||
UNITY_VERTEX_INPUT_INSTANCE_ID
|
||||
};
|
||||
|
||||
struct v2f
|
||||
{
|
||||
float4 vertex : SV_POSITION;
|
||||
fixed4 color : COLOR;
|
||||
float2 texcoord : TEXCOORD0;
|
||||
float4 worldPosition : TEXCOORD1;
|
||||
float4 mask : TEXCOORD2;
|
||||
UNITY_VERTEX_OUTPUT_STEREO
|
||||
};
|
||||
|
||||
v2f vert(appdata_t v)
|
||||
{
|
||||
v2f OUT;
|
||||
UNITY_SETUP_INSTANCE_ID(v);
|
||||
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT);
|
||||
float4 vPosition = UnityObjectToClipPos(v.vertex);
|
||||
OUT.worldPosition = v.vertex;
|
||||
OUT.vertex = vPosition;
|
||||
|
||||
float2 pixelSize = vPosition.w;
|
||||
pixelSize /= float2(1, 1) * abs(mul((float2x2)UNITY_MATRIX_P, _ScreenParams.xy));
|
||||
|
||||
float4 clampedRect = clamp(_ClipRect, -2e10, 2e10);
|
||||
float2 maskUV = (v.vertex.xy - clampedRect.xy) / (clampedRect.zw - clampedRect.xy);
|
||||
OUT.texcoord = TRANSFORM_TEX(v.texcoord.xy, _MainTex);
|
||||
OUT.mask = float4(v.vertex.xy * 2 - clampedRect.xy - clampedRect.zw,
|
||||
0.25 / (0.25 * half2(_UIMaskSoftnessX, _UIMaskSoftnessY) + abs(pixelSize.xy)));
|
||||
|
||||
if (_UIVertexColorAlwaysGammaSpace)
|
||||
{
|
||||
if (!IsGammaSpace())
|
||||
{
|
||||
v.color.rgb = GammaToLinearSpace(v.color.rgb);
|
||||
}
|
||||
}
|
||||
|
||||
OUT.color = v.color * _Color;
|
||||
return OUT;
|
||||
}
|
||||
|
||||
half4 apply_color(half4 color, const half4 factor, const int mode)
|
||||
{
|
||||
const half3 c = factor.rgb * color.a;
|
||||
// Mode 1: Additive
|
||||
if (mode == 1)
|
||||
{
|
||||
color.rgb += c;
|
||||
}
|
||||
// Mode 2: Subtract
|
||||
else if (mode == 2)
|
||||
{
|
||||
color.rgb -= c;
|
||||
}
|
||||
// Mode 3: Replace
|
||||
else if (mode == 3)
|
||||
{
|
||||
color.rgb = c;
|
||||
}
|
||||
// Default: Multiply
|
||||
else
|
||||
{
|
||||
color.rgb *= c;
|
||||
}
|
||||
|
||||
return color * factor.a;
|
||||
}
|
||||
|
||||
fixed4 frag(v2f IN) : SV_Target
|
||||
{
|
||||
//Round up the alpha color coming from the interpolator (to 1.0/256.0 steps)
|
||||
//The incoming alpha could have numerical instability, which makes it very sensible to
|
||||
//HDR color transparency blend, when it blends with the world's texture.
|
||||
const half alphaPrecision = half(0xff);
|
||||
const half invAlphaPrecision = half(1.0 / alphaPrecision);
|
||||
float2 uv = IN.texcoord;
|
||||
|
||||
IN.color.a = round(IN.color.a * alphaPrecision) * invAlphaPrecision;
|
||||
half4 color = tex2D(_MainTex, uv) + _TextureSampleAdd;
|
||||
|
||||
#if UNITY_UI_CLIP_RECT
|
||||
half2 m = saturate((_ClipRect.zw - _ClipRect.xy - abs(IN.mask.xy)) * IN.mask.zw);
|
||||
color.a *= m.x * m.y;
|
||||
#endif
|
||||
|
||||
#if UNITY_UI_ALPHACLIP
|
||||
clip (color.a - 0.001);
|
||||
#endif
|
||||
|
||||
// Apply color mode.
|
||||
color = apply_color(color, IN.color, _ColorMode);
|
||||
|
||||
return color;
|
||||
}
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
}
|
||||
10
Assets/Demo/CustomView/UI-Color.shader.meta
Normal file
10
Assets/Demo/CustomView/UI-Color.shader.meta
Normal file
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6b5e4f608f0684d10a4673a7e1cee0f3
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
nonModifiableTextures: []
|
||||
preprocessorOverride: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
42
Assets/Demo/CustomView/UI-Star-Add.mat
Normal file
42
Assets/Demo/CustomView/UI-Star-Add.mat
Normal file
@@ -0,0 +1,42 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 8
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: UI-Star-Add
|
||||
m_Shader: {fileID: 4800000, guid: 6b5e4f608f0684d10a4673a7e1cee0f3, type: 3}
|
||||
m_ValidKeywords: []
|
||||
m_InvalidKeywords:
|
||||
- _COLORMODE_MULTIPRY
|
||||
m_LightmapFlags: 4
|
||||
m_EnableInstancingVariants: 0
|
||||
m_DoubleSidedGI: 0
|
||||
m_CustomRenderQueue: -1
|
||||
stringTagMap: {}
|
||||
disabledShaderPasses: []
|
||||
m_SavedProperties:
|
||||
serializedVersion: 3
|
||||
m_TexEnvs:
|
||||
- _MainTex:
|
||||
m_Texture: {fileID: 2800000, guid: 8412a67c0342348169bea68bf9315a14, type: 3}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_Ints: []
|
||||
m_Floats:
|
||||
- _ColorMask: 15
|
||||
- _ColorMode: 0
|
||||
- _DstBlend: 1
|
||||
- _SrcBlend: 1
|
||||
- _Stencil: 0
|
||||
- _StencilComp: 8
|
||||
- _StencilOp: 0
|
||||
- _StencilReadMask: 255
|
||||
- _StencilWriteMask: 255
|
||||
- _UseUIAlphaClip: 0
|
||||
m_Colors:
|
||||
- _Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_BuildTextureStacks: []
|
||||
@@ -1,7 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 46deb9632f6a14713b8460bd01e879c9
|
||||
PrefabImporter:
|
||||
guid: e4d32268c77b14dd99f0e99fcfcd3a46
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 2100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
42
Assets/Demo/CustomView/UI-Star.mat
Normal file
42
Assets/Demo/CustomView/UI-Star.mat
Normal file
@@ -0,0 +1,42 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 8
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: UI-Star
|
||||
m_Shader: {fileID: 4800000, guid: 6b5e4f608f0684d10a4673a7e1cee0f3, type: 3}
|
||||
m_ValidKeywords: []
|
||||
m_InvalidKeywords:
|
||||
- _COLORMODE_MULTIPRY
|
||||
m_LightmapFlags: 4
|
||||
m_EnableInstancingVariants: 0
|
||||
m_DoubleSidedGI: 0
|
||||
m_CustomRenderQueue: -1
|
||||
stringTagMap: {}
|
||||
disabledShaderPasses: []
|
||||
m_SavedProperties:
|
||||
serializedVersion: 3
|
||||
m_TexEnvs:
|
||||
- _MainTex:
|
||||
m_Texture: {fileID: 2800000, guid: 8412a67c0342348169bea68bf9315a14, type: 3}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_Ints: []
|
||||
m_Floats:
|
||||
- _ColorMask: 15
|
||||
- _ColorMode: 0
|
||||
- _DstBlend: 10
|
||||
- _SrcBlend: 1
|
||||
- _Stencil: 0
|
||||
- _StencilComp: 8
|
||||
- _StencilOp: 0
|
||||
- _StencilReadMask: 255
|
||||
- _StencilWriteMask: 255
|
||||
- _UseUIAlphaClip: 0
|
||||
m_Colors:
|
||||
- _Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_BuildTextureStacks: []
|
||||
@@ -1,7 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b73940fc30a2f4eb9a73783e9c1f8da6
|
||||
PrefabImporter:
|
||||
guid: 4c756ed674dab453eb1d0a7d9360a9c1
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 2100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/Demo/CustomView/UI-Star.png
Normal file
BIN
Assets/Demo/CustomView/UI-Star.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
147
Assets/Demo/CustomView/UI-Star.png.meta
Normal file
147
Assets/Demo/CustomView/UI-Star.png.meta
Normal file
@@ -0,0 +1,147 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8412a67c0342348169bea68bf9315a14
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 12
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
sRGBTexture: 1
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
vTOnly: 0
|
||||
ignoreMasterTextureLimit: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: 1
|
||||
aniso: 1
|
||||
mipBias: 0
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: 1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 1
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 2
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 0
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
flipbookRows: 1
|
||||
flipbookColumns: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
ignorePngGamma: 0
|
||||
applyGammaDecoding: 1
|
||||
cookieLightType: 1
|
||||
platformSettings:
|
||||
- serializedVersion: 3
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 128
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: Standalone
|
||||
maxTextureSize: 128
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: Android
|
||||
maxTextureSize: 128
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 1
|
||||
- serializedVersion: 3
|
||||
buildTarget: WebGL
|
||||
maxTextureSize: 128
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: 63
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 1
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: Server
|
||||
maxTextureSize: 128
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID: 5e97eb03825dee720800000000000000
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
nameFileIdTable: {}
|
||||
spritePackingTag:
|
||||
pSDRemoveMatte: 0
|
||||
pSDShowRemoveMatteOption: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
42
Assets/Demo/CustomView/UI-StretchTrait.mat
Normal file
42
Assets/Demo/CustomView/UI-StretchTrait.mat
Normal file
@@ -0,0 +1,42 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 8
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: UI-StretchTrait
|
||||
m_Shader: {fileID: 4800000, guid: 6b5e4f608f0684d10a4673a7e1cee0f3, type: 3}
|
||||
m_ValidKeywords: []
|
||||
m_InvalidKeywords:
|
||||
- _COLORMODE_MULTIPRY
|
||||
m_LightmapFlags: 4
|
||||
m_EnableInstancingVariants: 0
|
||||
m_DoubleSidedGI: 0
|
||||
m_CustomRenderQueue: -1
|
||||
stringTagMap: {}
|
||||
disabledShaderPasses: []
|
||||
m_SavedProperties:
|
||||
serializedVersion: 3
|
||||
m_TexEnvs:
|
||||
- _MainTex:
|
||||
m_Texture: {fileID: 2800000, guid: 7d5844d14c31c4ca88cf5653c09ec1f3, type: 3}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_Ints: []
|
||||
m_Floats:
|
||||
- _ColorMask: 15
|
||||
- _ColorMode: 0
|
||||
- _DstBlend: 1
|
||||
- _SrcBlend: 1
|
||||
- _Stencil: 0
|
||||
- _StencilComp: 8
|
||||
- _StencilOp: 0
|
||||
- _StencilReadMask: 255
|
||||
- _StencilWriteMask: 255
|
||||
- _UseUIAlphaClip: 0
|
||||
m_Colors:
|
||||
- _Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_BuildTextureStacks: []
|
||||
8
Assets/Demo/CustomView/UI-StretchTrait.mat.meta
Normal file
8
Assets/Demo/CustomView/UI-StretchTrait.mat.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bce3318d54bae4f99a2cb35bd8c456b0
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 2100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/Demo/CustomView/UI-StretchTrait.png
Normal file
BIN
Assets/Demo/CustomView/UI-StretchTrait.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 8.5 KiB |
147
Assets/Demo/CustomView/UI-StretchTrait.png.meta
Normal file
147
Assets/Demo/CustomView/UI-StretchTrait.png.meta
Normal file
@@ -0,0 +1,147 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7d5844d14c31c4ca88cf5653c09ec1f3
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 12
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
sRGBTexture: 1
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
vTOnly: 0
|
||||
ignoreMasterTextureLimit: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: 1
|
||||
aniso: 1
|
||||
mipBias: 0
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: 1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 1
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 2
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 0
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
flipbookRows: 1
|
||||
flipbookColumns: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
ignorePngGamma: 0
|
||||
applyGammaDecoding: 1
|
||||
cookieLightType: 1
|
||||
platformSettings:
|
||||
- serializedVersion: 3
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 64
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: Standalone
|
||||
maxTextureSize: 64
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: Android
|
||||
maxTextureSize: 64
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 1
|
||||
- serializedVersion: 3
|
||||
buildTarget: WebGL
|
||||
maxTextureSize: 64
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: 63
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 1
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: Server
|
||||
maxTextureSize: 64
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID: 5e97eb03825dee720800000000000000
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
nameFileIdTable: {}
|
||||
spritePackingTag:
|
||||
pSDRemoveMatte: 0
|
||||
pSDShowRemoveMatteOption: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,3 +1,4 @@
|
||||
using Coffee.UIParticleInternal;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Serialization;
|
||||
|
||||
@@ -46,7 +47,7 @@ namespace Coffee.UIExtensions.Demo
|
||||
|
||||
if (!flag)
|
||||
{
|
||||
foreach (var ps in FindObjectsOfType<ParticleSystem>())
|
||||
foreach (var ps in Misc.FindObjectsOfType<ParticleSystem>())
|
||||
{
|
||||
ps.Play(false);
|
||||
}
|
||||
@@ -75,7 +76,7 @@ namespace Coffee.UIExtensions.Demo
|
||||
|
||||
public void ParticleSystem_SetScale(float scale)
|
||||
{
|
||||
foreach (var ps in FindObjectsOfType<ParticleSystem>())
|
||||
foreach (var ps in Misc.FindObjectsOfType<ParticleSystem>())
|
||||
{
|
||||
ps.transform.localScale = new Vector3(scale, scale, scale);
|
||||
}
|
||||
|
||||
@@ -14,15 +14,16 @@ MonoBehaviour:
|
||||
m_EditorClassIdentifier:
|
||||
m_NanoMonitorEnabled: 1
|
||||
m_BootSceneNameRegex: .*
|
||||
m_DevelopmentBuildOnly: 1
|
||||
m_DevelopmentBuildOnly: 0
|
||||
m_EnabledInEditor: 1
|
||||
m_AlwaysIncludeAssembly: 1
|
||||
m_InstantiateOnLoad: 1
|
||||
m_Prefab: {fileID: 7211429669315726685, guid: b73940fc30a2f4eb9a73783e9c1f8da6,
|
||||
m_Prefab: {fileID: 4567906826058368312, guid: 7cebff2d255b9433cbe23b243c193329,
|
||||
type: 3}
|
||||
m_Opened: 1
|
||||
m_Interval: 0.5
|
||||
m_Anchor: 1
|
||||
m_Anchor: 0
|
||||
m_Width: 750
|
||||
m_HelpUrl: https://github.com/mob-sakai/ParticleEffectForUGUI
|
||||
m_CustomMonitorItems:
|
||||
- m_Format: Screen:{0}x{1}
|
||||
m_Arg0:
|
||||
@@ -31,3 +32,10 @@ MonoBehaviour:
|
||||
m_Path: UnityEngine.Screen, UnityEngine.CoreModule;height
|
||||
m_Arg2:
|
||||
m_Path:
|
||||
- m_Format: UIParticles:{0} Materials:{1}
|
||||
m_Arg0:
|
||||
m_Path: Coffee.UIExtensions.UIParticleUpdater, Coffee.UIParticle;uiParticleCount
|
||||
m_Arg1:
|
||||
m_Path: Coffee.UIParticleInternal.MaterialRepository, Coffee.UIParticle;count
|
||||
m_Arg2:
|
||||
m_Path:
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,20 +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: 94e8c16a26d334eafa227ee444387432, type: 3}
|
||||
m_Name: SimpleSceneNavigator
|
||||
m_EditorClassIdentifier:
|
||||
m_NavigatorEnabled: 1
|
||||
m_EnabledInEditor: 1
|
||||
m_AlwaysIncludeAssembly: 1
|
||||
m_InstantiateOnLoad: 1
|
||||
m_Prefab: {fileID: 7211429669315726685, guid: 46deb9632f6a14713b8460bd01e879c9,
|
||||
type: 3}
|
||||
@@ -1,513 +0,0 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1 &3877588430955763108
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 3877588430955763111}
|
||||
- component: {fileID: 3877588430955763105}
|
||||
- component: {fileID: 3877588430955763110}
|
||||
m_Layer: 5
|
||||
m_Name: Text
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &3877588430955763111
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3877588430955763108}
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 3877588431231610297}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 0, y: 0}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &3877588430955763105
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3877588430955763108}
|
||||
m_CullTransparentMesh: 0
|
||||
--- !u!114 &3877588430955763110
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3877588430955763108}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_Maskable: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_FontData:
|
||||
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
|
||||
m_FontSize: 14
|
||||
m_FontStyle: 0
|
||||
m_BestFit: 0
|
||||
m_MinSize: 10
|
||||
m_MaxSize: 40
|
||||
m_Alignment: 4
|
||||
m_AlignByGeometry: 0
|
||||
m_RichText: 1
|
||||
m_HorizontalOverflow: 1
|
||||
m_VerticalOverflow: 1
|
||||
m_LineSpacing: 1
|
||||
m_Text: '>>'
|
||||
--- !u!1 &3877588431231610301
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 3877588431231610297}
|
||||
- component: {fileID: 3877588431231610302}
|
||||
- component: {fileID: 3877588431231610303}
|
||||
- component: {fileID: 3877588431231610300}
|
||||
m_Layer: 5
|
||||
m_Name: Button - >>
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &3877588431231610297
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3877588431231610301}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children:
|
||||
- {fileID: 3877588430955763111}
|
||||
m_Father: {fileID: 7211429669315725985}
|
||||
m_RootOrder: 1
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 1, y: 1}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 30, y: 30}
|
||||
m_Pivot: {x: 1, y: 1}
|
||||
--- !u!222 &3877588431231610302
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3877588431231610301}
|
||||
m_CullTransparentMesh: 0
|
||||
--- !u!114 &3877588431231610303
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3877588431231610301}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_Maskable: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_Type: 1
|
||||
m_PreserveAspect: 0
|
||||
m_FillCenter: 1
|
||||
m_FillMethod: 4
|
||||
m_FillAmount: 1
|
||||
m_FillClockwise: 1
|
||||
m_FillOrigin: 0
|
||||
m_UseSpriteMesh: 0
|
||||
m_PixelsPerUnitMultiplier: 1
|
||||
--- !u!114 &3877588431231610300
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3877588431231610301}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Navigation:
|
||||
m_Mode: 3
|
||||
m_SelectOnUp: {fileID: 0}
|
||||
m_SelectOnDown: {fileID: 0}
|
||||
m_SelectOnLeft: {fileID: 0}
|
||||
m_SelectOnRight: {fileID: 0}
|
||||
m_Transition: 1
|
||||
m_Colors:
|
||||
m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
|
||||
m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
|
||||
m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
|
||||
m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
|
||||
m_ColorMultiplier: 1
|
||||
m_FadeDuration: 0.1
|
||||
m_SpriteState:
|
||||
m_HighlightedSprite: {fileID: 0}
|
||||
m_PressedSprite: {fileID: 0}
|
||||
m_SelectedSprite: {fileID: 0}
|
||||
m_DisabledSprite: {fileID: 0}
|
||||
m_AnimationTriggers:
|
||||
m_NormalTrigger: Normal
|
||||
m_HighlightedTrigger: Highlighted
|
||||
m_PressedTrigger: Pressed
|
||||
m_SelectedTrigger: Selected
|
||||
m_DisabledTrigger: Disabled
|
||||
m_Interactable: 1
|
||||
m_TargetGraphic: {fileID: 3877588431231610303}
|
||||
m_OnClick:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
--- !u!1 &3877588432219069602
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 3877588432219069614}
|
||||
- component: {fileID: 3877588432219069615}
|
||||
- component: {fileID: 3877588432219069612}
|
||||
- component: {fileID: 3877588432219069613}
|
||||
m_Layer: 5
|
||||
m_Name: Button - <<
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &3877588432219069614
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3877588432219069602}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children:
|
||||
- {fileID: 1738594088889562266}
|
||||
m_Father: {fileID: 7211429669315725985}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 30, y: 30}
|
||||
m_Pivot: {x: 0, y: 1}
|
||||
--- !u!222 &3877588432219069615
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3877588432219069602}
|
||||
m_CullTransparentMesh: 0
|
||||
--- !u!114 &3877588432219069612
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3877588432219069602}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_Maskable: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_Type: 1
|
||||
m_PreserveAspect: 0
|
||||
m_FillCenter: 1
|
||||
m_FillMethod: 4
|
||||
m_FillAmount: 1
|
||||
m_FillClockwise: 1
|
||||
m_FillOrigin: 0
|
||||
m_UseSpriteMesh: 0
|
||||
m_PixelsPerUnitMultiplier: 1
|
||||
--- !u!114 &3877588432219069613
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3877588432219069602}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Navigation:
|
||||
m_Mode: 3
|
||||
m_SelectOnUp: {fileID: 0}
|
||||
m_SelectOnDown: {fileID: 0}
|
||||
m_SelectOnLeft: {fileID: 0}
|
||||
m_SelectOnRight: {fileID: 0}
|
||||
m_Transition: 1
|
||||
m_Colors:
|
||||
m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
|
||||
m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
|
||||
m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
|
||||
m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
|
||||
m_ColorMultiplier: 1
|
||||
m_FadeDuration: 0.1
|
||||
m_SpriteState:
|
||||
m_HighlightedSprite: {fileID: 0}
|
||||
m_PressedSprite: {fileID: 0}
|
||||
m_SelectedSprite: {fileID: 0}
|
||||
m_DisabledSprite: {fileID: 0}
|
||||
m_AnimationTriggers:
|
||||
m_NormalTrigger: Normal
|
||||
m_HighlightedTrigger: Highlighted
|
||||
m_PressedTrigger: Pressed
|
||||
m_SelectedTrigger: Selected
|
||||
m_DisabledTrigger: Disabled
|
||||
m_Interactable: 1
|
||||
m_TargetGraphic: {fileID: 3877588432219069612}
|
||||
m_OnClick:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
--- !u!1 &7211429669315726685
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 7211429669315725985}
|
||||
- component: {fileID: 7211429669315726686}
|
||||
- component: {fileID: 7211429669315726687}
|
||||
- component: {fileID: 7143702096253919615}
|
||||
- component: {fileID: 3330778306119167604}
|
||||
m_Layer: 5
|
||||
m_Name: SimpleSceneNavigator
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &7211429669315725985
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 7211429669315726685}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 0, y: 0, z: 0}
|
||||
m_Children:
|
||||
- {fileID: 3877588432219069614}
|
||||
- {fileID: 3877588431231610297}
|
||||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 0, y: 0}
|
||||
m_Pivot: {x: 0, y: 0}
|
||||
--- !u!223 &7211429669315726686
|
||||
Canvas:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 7211429669315726685}
|
||||
m_Enabled: 1
|
||||
serializedVersion: 3
|
||||
m_RenderMode: 0
|
||||
m_Camera: {fileID: 0}
|
||||
m_PlaneDistance: 100
|
||||
m_PixelPerfect: 0
|
||||
m_ReceivesEvents: 1
|
||||
m_OverrideSorting: 0
|
||||
m_OverridePixelPerfect: 0
|
||||
m_SortingBucketNormalizedSize: 0
|
||||
m_AdditionalShaderChannelsFlag: 0
|
||||
m_SortingLayerID: 0
|
||||
m_SortingOrder: 32000
|
||||
m_TargetDisplay: 0
|
||||
--- !u!114 &7211429669315726687
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 7211429669315726685}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 0cd44c1031e13a943bb63640046fad76, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_UiScaleMode: 1
|
||||
m_ReferencePixelsPerUnit: 100
|
||||
m_ScaleFactor: 1
|
||||
m_ReferenceResolution: {x: 600, y: 40}
|
||||
m_ScreenMatchMode: 0
|
||||
m_MatchWidthOrHeight: 0
|
||||
m_PhysicalUnit: 3
|
||||
m_FallbackScreenDPI: 96
|
||||
m_DefaultSpriteDPI: 96
|
||||
m_DynamicPixelsPerUnit: 1
|
||||
--- !u!114 &7143702096253919615
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 7211429669315726685}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: dc42784cf147c0c48a680349fa168899, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_IgnoreReversedGraphics: 1
|
||||
m_BlockingObjects: 0
|
||||
m_BlockingMask:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
--- !u!114 &3330778306119167604
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 7211429669315726685}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: e7db36469bd2a46658ff432d65cb62ca, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_PrevButton: {fileID: 3877588432219069613}
|
||||
m_NextButton: {fileID: 3877588431231610300}
|
||||
m_PrevName: {fileID: 0}
|
||||
m_NextName: {fileID: 0}
|
||||
--- !u!1 &8570858711609111474
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 1738594088889562266}
|
||||
- component: {fileID: 5485386222362727379}
|
||||
- component: {fileID: 3877588430751452752}
|
||||
m_Layer: 5
|
||||
m_Name: Text
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &1738594088889562266
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 8570858711609111474}
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 3877588432219069614}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 0, y: 0}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &5485386222362727379
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 8570858711609111474}
|
||||
m_CullTransparentMesh: 0
|
||||
--- !u!114 &3877588430751452752
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 8570858711609111474}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_Maskable: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_FontData:
|
||||
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
|
||||
m_FontSize: 14
|
||||
m_FontStyle: 0
|
||||
m_BestFit: 0
|
||||
m_MinSize: 10
|
||||
m_MaxSize: 40
|
||||
m_Alignment: 4
|
||||
m_AlignByGeometry: 0
|
||||
m_RichText: 1
|
||||
m_HorizontalOverflow: 1
|
||||
m_VerticalOverflow: 1
|
||||
m_LineSpacing: 1
|
||||
m_Text: <<
|
||||
@@ -10,6 +10,7 @@ MonoBehaviour:
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: f22a23b9d98e440478697f4adf30e61c, type: 3}
|
||||
m_Name: UIParticle
|
||||
m_Name: UIParticleProjectSettings
|
||||
m_EditorClassIdentifier:
|
||||
m_LinearToGamma: 1
|
||||
m_EnableLinearToGamma: 1
|
||||
m_HideGeneratedObjects: 1
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e8e7744b163af4869b07b8f192c810ed
|
||||
guid: a5b9278dfbd194d04b1c6ae7031928c1
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
||||
@@ -1,16 +1,21 @@
|
||||
using System.Collections;
|
||||
using Coffee.UIParticleInternal;
|
||||
using NUnit.Framework;
|
||||
using UnityEngine;
|
||||
using UnityEngine.TestTools;
|
||||
|
||||
namespace Coffee.UIParticle.Editor.Tests
|
||||
{
|
||||
public class NewTestScript
|
||||
{
|
||||
// A Test behaves as an ordinary method
|
||||
[Test]
|
||||
public void NewTestScriptSimplePasses()
|
||||
[TestCase(-1)]
|
||||
[TestCase(0)]
|
||||
[TestCase(2048)]
|
||||
[TestCase(3000)]
|
||||
public void GetParticleArray(int requiredSize)
|
||||
{
|
||||
// Use the Assert class to test conditions
|
||||
var array = ParticleSystemExtensions.GetParticleArray(requiredSize);
|
||||
Debug.Log($"requiredSize: {requiredSize}, array.Length: {array.Length}");
|
||||
}
|
||||
|
||||
// A UnityTest behaves like a coroutine in Play Mode. In Edit Mode you can use
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"com.unity.ide.rider": "3.0.27",
|
||||
"com.coffee.development": "https://github.com/mob-sakai/Coffee.Internal.git?path=Packages/Development",
|
||||
"com.coffee.minimal-resource": "https://github.com/mob-sakai/Coffee.Internal.git?path=Packages/MinimalResource",
|
||||
"com.coffee.nano-monitor": "https://github.com/mob-sakai/Coffee.Internal.git?path=Packages/NanoMonitor",
|
||||
"com.coffee.simple-scene-navigator": "https://github.com/mob-sakai/Coffee.Internal.git?path=Packages/SceneNavigator",
|
||||
"com.coffee.sub-asset-editor": "https://github.com/mob-sakai/SubAssetEditor.git",
|
||||
"com.unity.ide.rider": "3.0.31",
|
||||
"com.unity.test-framework": "1.1.33",
|
||||
"com.unity.modules.animation": "1.0.0",
|
||||
"com.unity.modules.physics": "1.0.0"
|
||||
|
||||
@@ -5,7 +5,14 @@
|
||||
"depth": 0,
|
||||
"source": "git",
|
||||
"dependencies": {},
|
||||
"hash": "4a57c0a498ba7ce667290ec39510b1474030471a"
|
||||
"hash": "3c280f1a8f4db5038b881ff07f270efd9638fa31"
|
||||
},
|
||||
"com.coffee.minimal-resource": {
|
||||
"version": "https://github.com/mob-sakai/Coffee.Internal.git?path=Packages/MinimalResource",
|
||||
"depth": 0,
|
||||
"source": "git",
|
||||
"dependencies": {},
|
||||
"hash": "3c280f1a8f4db5038b881ff07f270efd9638fa31"
|
||||
},
|
||||
"com.coffee.nano-monitor": {
|
||||
"version": "https://github.com/mob-sakai/Coffee.Internal.git?path=Packages/NanoMonitor",
|
||||
@@ -14,23 +21,7 @@
|
||||
"dependencies": {
|
||||
"com.unity.ugui": "1.0.0"
|
||||
},
|
||||
"hash": "4a57c0a498ba7ce667290ec39510b1474030471a"
|
||||
},
|
||||
"com.coffee.simple-scene-navigator": {
|
||||
"version": "https://github.com/mob-sakai/Coffee.Internal.git?path=Packages/SceneNavigator",
|
||||
"depth": 0,
|
||||
"source": "git",
|
||||
"dependencies": {
|
||||
"com.unity.ugui": "1.0.0"
|
||||
},
|
||||
"hash": "4a57c0a498ba7ce667290ec39510b1474030471a"
|
||||
},
|
||||
"com.coffee.sub-asset-editor": {
|
||||
"version": "https://github.com/mob-sakai/SubAssetEditor.git",
|
||||
"depth": 0,
|
||||
"source": "git",
|
||||
"dependencies": {},
|
||||
"hash": "01464178eec1e4dbe741c11c9baeb94a151c99ee"
|
||||
"hash": "3c280f1a8f4db5038b881ff07f270efd9638fa31"
|
||||
},
|
||||
"com.coffee.ui-particle": {
|
||||
"version": "file:src",
|
||||
@@ -49,7 +40,7 @@
|
||||
"url": "https://packages.unity.com"
|
||||
},
|
||||
"com.unity.ide.rider": {
|
||||
"version": "3.0.27",
|
||||
"version": "3.0.31",
|
||||
"depth": 0,
|
||||
"source": "registry",
|
||||
"dependencies": {
|
||||
|
||||
@@ -1,35 +1,198 @@
|
||||
# [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)
|
||||
## [4.12.1](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.12.0...v4.12.1) (2026-03-24)
|
||||
|
||||
|
||||
### 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)
|
||||
* ignore "EditorOnly" tagged gameObjects on refresh ([031d46a](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/031d46a3216c942d2d1a6ccfadf5f0b9e3ce3006))
|
||||
|
||||
# [4.12.0](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.11.4...v4.12.0) (2026-03-24)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* 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))
|
||||
* explicit null checks ([5384f61](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/5384f61c569e9f78ff9d5b45acfc6f5c2f021a87))
|
||||
|
||||
# [5.0.0-preview.1](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.6.6...v5.0.0-preview.1) (2024-05-23)
|
||||
## [4.11.4](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.11.3...v4.11.4) (2025-12-24)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* add early return for case where subEmitter module is disabled ([d1386a1](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/d1386a12216743a6e09f1b9b87bea1dfcf7702e4))
|
||||
* avoid endless loop ([eb2e862](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/eb2e862e80e549c8cf16ddfed776c101c2413bac)), closes [#392](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/392)
|
||||
|
||||
## [4.11.3](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.11.2...v4.11.3) (2025-10-14)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* fix icon ([a9461ec](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/a9461ecb4d40d7fe878e12465d6e38faae7ae65b))
|
||||
* fix URL link in README ([1c8c65d](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/1c8c65d25e7f6fe7b1d20da4461333df8fc7578e)), closes [#376](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/376)
|
||||
* fix: second and subsequent bursts not displayed when world simulation and non-looping ([df2f3ca](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/df2f3caafbe279f1457d74f8183cb561ac14aa17)), closes [#326](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/326)
|
||||
* UIParticle in canvas with 0f-0.01f alpha value does not start to play until alpha value is greater than 0.01f, causes play calls to be delayed unintentionally if canvas alpha value is set to mentioned value range ([38aec2e](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/38aec2ea1afd77677d629c86665a3342d92e49d9))
|
||||
|
||||
## [4.11.2](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.11.1...v4.11.2) (2025-03-15)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* IL2CPP build fails on older versions of Unity ([0da6525](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/0da652520cd165b43de7404c0b0ab1fbcf9349d1))
|
||||
* NRE on enable ([0cff50e](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/0cff50ef696aa53fb7c46a9a737b7cf3a05b7b9b)), closes [#359](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/359)
|
||||
|
||||
## [4.11.1](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.11.0...v4.11.1) (2025-02-21)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* component icons will no longer be displayed in the scene view ([6dfbdae](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/6dfbdae38d3822ab9c2c6f0e4ca1ca32ee98a239))
|
||||
|
||||
# [4.11.0](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.10.7...v4.11.0) (2025-02-21)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add 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))
|
||||
* add 'TimeScaleMultiplier' option ([925af0b](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/925af0b6046f65f23a778f67cefa8ff9cbedb513))
|
||||
|
||||
## [4.10.7](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.10.6...v4.10.7) (2025-01-14)
|
||||
|
||||
|
||||
### BREAKING CHANGES
|
||||
### Bug Fixes
|
||||
|
||||
* Some members inherited from MaskableGraphic will no longer be available.
|
||||
* editor crashed on exit play mode (editor, windows) ([47ee45c](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/47ee45cbbe651a8f87ca2b8a3948f8b88db8211e)), closes [#351](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/351)
|
||||
|
||||
## [4.10.6](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.10.5...v4.10.6) (2025-01-03)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* sub-emitter particles may not render correctly in certain scenarios ([8276684](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/8276684c3b1646f0490ed64557547ba15281664a)), closes [#348](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/348)
|
||||
* sub-emitter's `inherit velocity` module doubles at runtime ([67de3d1](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/67de3d1bd3e16dc9b564625cb990c53d75769506)), closes [#349](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/349)
|
||||
|
||||
## [4.10.5](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.10.4...v4.10.5) (2024-12-23)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* '3D' scale toggle in the inspector does not keep on reload ([934f4b8](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/934f4b8f1c61f8ff20228d0ebcea9f636a3758ed)), closes [#346](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/346)
|
||||
|
||||
## [4.10.4](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.10.3...v4.10.4) (2024-12-19)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* rendering issues when playing with opening a prefab stage ([95235a9](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/95235a929b82cf681365ed6eba837d857f83e3d2)), closes [#345](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/345)
|
||||
|
||||
## [4.10.3](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.10.2...v4.10.3) (2024-11-20)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* if not configured as a preloaded asset, the project settings asset will be regenerated ([abe0948](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/abe09485f65dd4efd18e74675e752e0213bdf3be)), closes [#342](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/342)
|
||||
|
||||
## [4.10.2](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.10.1...v4.10.2) (2024-11-01)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* trail incorrect offset ([afe00a1](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/afe00a1dde80eb1c0a7bb668b75f4c3733d3fa43)), closes [#335](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/335)
|
||||
|
||||
## [4.10.1](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.10.0...v4.10.1) (2024-09-29)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* mainTex will be ignored ([2ee69d0](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/2ee69d04245fabce185f67dc9bd68c870e556564))
|
||||
|
||||
# [4.10.0](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.9.1...v4.10.0) (2024-09-29)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* component icon is not set ([5ff6ec8](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/5ff6ec815a174de5d3f16d424f1204c60912a8d8))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add project settings ([1ce4e31](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/1ce4e31a9681bf1a201d2723c8d97e07ecc16592))
|
||||
|
||||
## [4.9.1](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.9.0...v4.9.1) (2024-08-07)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* ParticleSystem trails gain offset on parent canvas change ([2a1cd50](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/2a1cd502b452b5b56edf8bcfe91adf99d1bb5147)), closes [#323](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/323)
|
||||
|
||||
# [4.9.0](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.8.1...v4.9.0) (2024-07-18)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* ParticleAttractor supports multiple ParticleSystems ([3834780](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/3834780fdb43443fe6e1ef89df54d26a24d62a91))
|
||||
|
||||
## [4.8.1](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.8.0...v4.8.1) (2024-06-27)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* remove debug code ([669deb4](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/669deb41d4ac589d9db93b29bc8e95383e7f28a5))
|
||||
|
||||
# [4.8.0](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.7.2...v4.8.0) (2024-06-27)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* generated baking-camera object remains in the prefab or scene (again) ([de35cba](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/de35cba34c6312c1405ed522e9927c620c78e72d))
|
||||
* SetParticleSystemInstance/Prefab APIs destroy generated objects ([ae3f3a8](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/ae3f3a8e62cc733420354d237ab765ac777127c8))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add 'custom view' option. ([a703c29](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/a703c2921ca08c2280d0c8fde01e4c0b33b5c69e))
|
||||
* remove overlay window (editor) ([8358170](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/835817049f4fcf00dd2bf98dbada14f041ad3544))
|
||||
* restore `Transform.localScale` when setting `autoScalingMode` to something other than `Transform` (again) ([88a970d](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/88a970d93a2b69cf011d86bd1807569e90538e0e))
|
||||
* the rendering order list in inspector is now more compact ([be90172](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/be901724e064befacf617f4940b0331e1d31e1ca))
|
||||
|
||||
## [4.7.2](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.7.1...v4.7.2) (2024-06-21)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* generated baking-camera object remains in the prefab or scene ([0bb8438](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/0bb843830197d8c1252232928becc211c0ada08d))
|
||||
|
||||
## [4.7.1](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.7.0...v4.7.1) (2024-06-20)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* despite not using the size module, particles become smaller based on their z position ([a8ed6e6](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/a8ed6e68584e1d9e45ed852eefcc03979ea7e0e1)), closes [#316](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/316)
|
||||
|
||||
# [4.7.0](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.6.8...v4.7.0) (2024-06-19)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* `UIParticle.transform.localScale` does not scale particles ([1d40e24](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/1d40e24c742741e97f03c55468ccb1e505341133)), closes [#313](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/313)
|
||||
* UIParticle is scaled by canvas size even when `AutoScalingMode.None` and `ScalingMode.Local` ([54a4b1c](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/54a4b1cdfd06400c7be89c1ee704bb42a659c7c2)), closes [#313](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/313)
|
||||
* UIParticle is scaled incorrectly with nested canvases ([f26920f](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/f26920f9825547222a4afbb31cc5dc5a002c3e9b)), closes [#313](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/313)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* reset previous position on start play for world space simulation ([3880484](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/3880484ce5190c42fc79c81d0b69e3fbeda09dd0)), closes [#303](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/303)
|
||||
* restore `Transform.localScale` when setting `autoScalingMode` to something other than `Transform` ([5505247](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/5505247a94a929ff89635fde512a9b95691e0043))
|
||||
|
||||
## [4.6.8](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.6.7...v4.6.8) (2024-06-14)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 'Resource ID out of range in GetResource' error in overlay rendering mode ([05286ce](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/05286cedfd17b1a0cb90a5e918513644f47cd831)), closes [#308](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/308)
|
||||
|
||||
## [4.6.7](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.6.6...v4.6.7) (2024-05-24)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* the ParticleSystem's localPosition drifts at certain scales due to floating-point precision issues ([e924eb4](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/e924eb45968a112347471cabaeabc274e4c37ce4)), closes [#299](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/299) [#312](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/312)
|
||||
|
||||
## [4.6.6](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.6.5...v4.6.6) (2024-05-23)
|
||||
|
||||
|
||||
@@ -31,35 +31,35 @@ namespace Coffee.UIExtensions
|
||||
}
|
||||
else
|
||||
{
|
||||
result.Aggregate(s_Sb, (a, b) => s_Sb.AppendFormat("{0}, ", b));
|
||||
result.Aggregate(s_Sb, (a, b) =>
|
||||
{
|
||||
s_Sb.Append(b);
|
||||
return s_Sb.Append(", ");
|
||||
});
|
||||
s_Sb.Length -= 2;
|
||||
}
|
||||
|
||||
return s_Sb.ToString();
|
||||
}
|
||||
|
||||
public static void Draw(SerializedProperty sp, Material[] mats)
|
||||
public static void Draw(SerializedProperty sp, List<Material> mats)
|
||||
{
|
||||
bool isClicked;
|
||||
using (new EditorGUILayout.HorizontalScope(GUILayout.ExpandWidth(false)))
|
||||
{
|
||||
var pos = EditorGUILayout.GetControlRect(true);
|
||||
var label = new GUIContent(sp.displayName, sp.tooltip);
|
||||
var rect = EditorGUI.PrefixLabel(pos, label);
|
||||
var text = sp.hasMultipleDifferentValues
|
||||
? "-"
|
||||
: CollectActiveNames(sp, s_ActiveNames);
|
||||
isClicked = GUI.Button(rect, text, EditorStyles.popup);
|
||||
}
|
||||
var pos = EditorGUILayout.GetControlRect(true);
|
||||
var label = new GUIContent(sp.displayName, sp.tooltip);
|
||||
var rect = EditorGUI.PrefixLabel(pos, label);
|
||||
var text = sp.hasMultipleDifferentValues
|
||||
? "-"
|
||||
: CollectActiveNames(sp, s_ActiveNames);
|
||||
|
||||
if (!isClicked) return;
|
||||
if (!GUI.Button(rect, text, EditorStyles.popup)) return;
|
||||
|
||||
var gm = new GenericMenu();
|
||||
gm.AddItem(s_ContentNothing, s_ActiveNames.Count == 0, () =>
|
||||
gm.AddItem(s_ContentNothing, s_ActiveNames.Count == 0, x =>
|
||||
{
|
||||
sp.ClearArray();
|
||||
sp.serializedObject.ApplyModifiedProperties();
|
||||
});
|
||||
var current = (SerializedProperty)x;
|
||||
current.ClearArray();
|
||||
current.serializedObject.ApplyModifiedProperties();
|
||||
}, sp);
|
||||
|
||||
if (!sp.hasMultipleDifferentValues)
|
||||
{
|
||||
@@ -73,17 +73,16 @@ namespace Coffee.UIExtensions
|
||||
}
|
||||
|
||||
s_Names.Clear();
|
||||
for (var j = 0; j < mats.Length; j++)
|
||||
for (var j = 0; j < mats.Count; j++)
|
||||
{
|
||||
var mat = mats[j];
|
||||
if (!mat || !mat.shader) continue;
|
||||
if (mat == null || mat.shader == null) continue;
|
||||
|
||||
for (var i = 0; i < ShaderUtil.GetPropertyCount(mat.shader); i++)
|
||||
{
|
||||
var name = ShaderUtil.GetPropertyName(mat.shader, i);
|
||||
var type = (AnimatableProperty.ShaderPropertyType)ShaderUtil.GetPropertyType(mat.shader, i);
|
||||
if (s_Names.Contains(name)) continue;
|
||||
s_Names.Add(name);
|
||||
if (!s_Names.Add(name)) continue;
|
||||
|
||||
AddMenu(gm, sp, new ShaderProperty(name, type), true);
|
||||
|
||||
|
||||
@@ -2,19 +2,19 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using UnityEditor;
|
||||
using UnityEditor.UI;
|
||||
using UnityEditorInternal;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Profiling;
|
||||
using UnityEngine.UI;
|
||||
|
||||
using Coffee.UIParticleInternal;
|
||||
#if UNITY_2021_2_OR_NEWER
|
||||
using UnityEditor.Overlays;
|
||||
#else
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using Coffee.UIParticleInternal;
|
||||
using Object = UnityEngine.Object;
|
||||
#endif
|
||||
|
||||
#if UNITY_2021_2_OR_NEWER
|
||||
using UnityEditor.SceneManagement;
|
||||
|
||||
@@ -26,20 +26,31 @@ namespace Coffee.UIExtensions
|
||||
{
|
||||
[CustomEditor(typeof(UIParticle))]
|
||||
[CanEditMultipleObjects]
|
||||
internal class UIParticleEditor : Editor
|
||||
internal class UIParticleEditor : GraphicEditor
|
||||
{
|
||||
internal class State : ScriptableSingleton<State>
|
||||
{
|
||||
public bool is3DScaleMode;
|
||||
}
|
||||
|
||||
//################################
|
||||
// Constant or Static Members.
|
||||
//################################
|
||||
private static readonly GUIContent[] s_ContentMaterials = new[]
|
||||
{
|
||||
new GUIContent("Material"),
|
||||
new GUIContent("Trail Material")
|
||||
};
|
||||
|
||||
private static readonly GUIContent s_ContentRenderingOrder = new GUIContent("Rendering Order");
|
||||
private static readonly GUIContent s_ContentRefresh = new GUIContent("Refresh");
|
||||
private static readonly GUIContent s_ContentFix = new GUIContent("Fix");
|
||||
private static readonly GUIContent s_ContentMaterial = new GUIContent("Material");
|
||||
private static readonly GUIContent s_ContentTrailMaterial = new GUIContent("Trail Material");
|
||||
private static readonly GUIContent s_Content3D = new GUIContent("3D");
|
||||
private static readonly GUIContent s_ContentRandom = new GUIContent("Random");
|
||||
private static readonly GUIContent s_ContentScale = new GUIContent("Scale");
|
||||
private static bool s_XYZMode;
|
||||
private static readonly GUIContent s_ContentPrimary = new GUIContent("Primary");
|
||||
private static readonly Regex s_RegexBuiltInGuid = new Regex(@"^0{16}.0{15}$", RegexOptions.Compiled);
|
||||
private static readonly List<Material> s_TempMaterials = new List<Material>();
|
||||
|
||||
private SerializedProperty _maskable;
|
||||
private SerializedProperty _scale3D;
|
||||
@@ -49,8 +60,12 @@ namespace Coffee.UIExtensions
|
||||
private SerializedProperty _groupMaxId;
|
||||
private SerializedProperty _positionMode;
|
||||
private SerializedProperty _autoScalingMode;
|
||||
private SerializedProperty _useCustomView;
|
||||
private SerializedProperty _customViewSize;
|
||||
private SerializedProperty _timeScaleMultiplier;
|
||||
private ReorderableList _ro;
|
||||
private bool _showMax;
|
||||
private bool _is3DScaleMode;
|
||||
|
||||
private static readonly HashSet<Shader> s_Shaders = new HashSet<Shader>();
|
||||
#if UNITY_2018 || UNITY_2019
|
||||
@@ -72,8 +87,10 @@ namespace Coffee.UIExtensions
|
||||
/// <summary>
|
||||
/// This function is called when the object becomes enabled and active.
|
||||
/// </summary>
|
||||
private void OnEnable()
|
||||
protected override void OnEnable()
|
||||
{
|
||||
base.OnEnable();
|
||||
|
||||
_maskable = serializedObject.FindProperty("m_Maskable");
|
||||
_scale3D = serializedObject.FindProperty("m_Scale3D");
|
||||
_animatableProperties = serializedObject.FindProperty("m_AnimatableProperties");
|
||||
@@ -82,31 +99,44 @@ namespace Coffee.UIExtensions
|
||||
_groupMaxId = serializedObject.FindProperty("m_GroupMaxId");
|
||||
_positionMode = serializedObject.FindProperty("m_PositionMode");
|
||||
_autoScalingMode = serializedObject.FindProperty("m_AutoScalingMode");
|
||||
_useCustomView = serializedObject.FindProperty("m_UseCustomView");
|
||||
_customViewSize = serializedObject.FindProperty("m_CustomViewSize");
|
||||
_timeScaleMultiplier = serializedObject.FindProperty("m_TimeScaleMultiplier");
|
||||
|
||||
var sp = serializedObject.FindProperty("m_Particles");
|
||||
_ro = new ReorderableList(sp.serializedObject, sp, true, true, true, true)
|
||||
{
|
||||
elementHeight = EditorGUIUtility.singleLineHeight * 3 + 4,
|
||||
elementHeightCallback = _ => 3 * (EditorGUIUtility.singleLineHeight + 2),
|
||||
elementHeightCallback = index =>
|
||||
{
|
||||
var ps = sp.GetArrayElementAtIndex(index).objectReferenceValue as ParticleSystem;
|
||||
var materialCount = 0;
|
||||
if (ps != null && ps.TryGetComponent<ParticleSystemRenderer>(out var psr))
|
||||
{
|
||||
materialCount = psr.sharedMaterials.Length;
|
||||
}
|
||||
|
||||
return (materialCount + 1) * (EditorGUIUtility.singleLineHeight + 2);
|
||||
},
|
||||
drawElementCallback = (rect, index, _, __) =>
|
||||
{
|
||||
EditorGUI.BeginDisabledGroup(sp.hasMultipleDifferentValues);
|
||||
rect.y += 1;
|
||||
rect.y += 2;
|
||||
rect.height = EditorGUIUtility.singleLineHeight;
|
||||
var p = sp.GetArrayElementAtIndex(index);
|
||||
EditorGUI.ObjectField(rect, p, GUIContent.none);
|
||||
var ps = p.objectReferenceValue as ParticleSystem;
|
||||
if (ps == null || !ps.TryGetComponent<ParticleSystemRenderer>(out var psr)) return;
|
||||
|
||||
rect.x += 15;
|
||||
rect.width -= 15;
|
||||
var ps = p.objectReferenceValue as ParticleSystem;
|
||||
var materials = ps
|
||||
? new SerializedObject(ps.GetComponent<ParticleSystemRenderer>()).FindProperty("m_Materials")
|
||||
: null;
|
||||
rect.y += rect.height + 1;
|
||||
MaterialField(rect, s_ContentMaterial, materials, 0);
|
||||
rect.y += rect.height + 1;
|
||||
MaterialField(rect, s_ContentTrailMaterial, materials, 1);
|
||||
EditorGUI.EndDisabledGroup();
|
||||
if (materials != null && materials.serializedObject.hasModifiedProperties)
|
||||
var materials = new SerializedObject(psr).FindProperty("m_Materials");
|
||||
var count = Mathf.Min(materials.arraySize, 2);
|
||||
for (var i = 0; i < count; i++)
|
||||
{
|
||||
rect.y += rect.height + 2;
|
||||
EditorGUI.PropertyField(rect, materials.GetArrayElementAtIndex(i), s_ContentMaterials[i]);
|
||||
}
|
||||
|
||||
if (materials.serializedObject.hasModifiedProperties)
|
||||
{
|
||||
materials.serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
@@ -140,19 +170,18 @@ namespace Coffee.UIExtensions
|
||||
uip.RefreshParticles(uip.particles);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void MaterialField(Rect rect, GUIContent label, SerializedProperty sp, int index)
|
||||
{
|
||||
if (sp == null || sp.arraySize <= index)
|
||||
// Initialize 3D scale mode.
|
||||
_is3DScaleMode = State.instance.is3DScaleMode;
|
||||
if (!_is3DScaleMode)
|
||||
{
|
||||
EditorGUI.BeginDisabledGroup(true);
|
||||
EditorGUI.ObjectField(rect, label, null, typeof(Material), true);
|
||||
EditorGUI.EndDisabledGroup();
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUI.PropertyField(rect, sp.GetArrayElementAtIndex(index), label);
|
||||
var x = _scale3D.FindPropertyRelative("x");
|
||||
var y = _scale3D.FindPropertyRelative("y");
|
||||
var z = _scale3D.FindPropertyRelative("z");
|
||||
_is3DScaleMode = !Mathf.Approximately(x.floatValue, y.floatValue) ||
|
||||
!Mathf.Approximately(y.floatValue, z.floatValue) ||
|
||||
y.hasMultipleDifferentValues ||
|
||||
z.hasMultipleDifferentValues;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -162,8 +191,9 @@ namespace Coffee.UIExtensions
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
var current = target as UIParticle;
|
||||
if (!current) return;
|
||||
if (current == null) return;
|
||||
|
||||
Profiler.BeginSample("(UIP:E) OnInspectorGUI");
|
||||
serializedObject.Update();
|
||||
|
||||
// Maskable
|
||||
@@ -171,17 +201,16 @@ namespace Coffee.UIExtensions
|
||||
|
||||
// Scale
|
||||
EditorGUI.BeginDisabledGroup(!_meshSharing.hasMultipleDifferentValues && _meshSharing.intValue == 4);
|
||||
s_XYZMode = DrawFloatOrVector3Field(_scale3D, s_XYZMode);
|
||||
if (DrawFloatOrVector3Field(_scale3D, _is3DScaleMode) != _is3DScaleMode)
|
||||
{
|
||||
State.instance.is3DScaleMode = _is3DScaleMode = !_is3DScaleMode;
|
||||
}
|
||||
|
||||
EditorGUI.EndDisabledGroup();
|
||||
|
||||
// AnimatableProperties
|
||||
var mats = current.particles
|
||||
.Where(x => x)
|
||||
.Select(x => x.GetComponent<ParticleSystemRenderer>().sharedMaterial)
|
||||
.Where(x => x)
|
||||
.ToArray();
|
||||
|
||||
AnimatablePropertyEditor.Draw(_animatableProperties, mats);
|
||||
current.GetMaterials(s_TempMaterials);
|
||||
AnimatablePropertyEditor.Draw(_animatableProperties, s_TempMaterials);
|
||||
|
||||
// Mesh sharing
|
||||
EditorGUI.BeginChangeCheck();
|
||||
@@ -189,9 +218,12 @@ namespace Coffee.UIExtensions
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
foreach (var uip in targets.OfType<UIParticle>())
|
||||
foreach (var t in targets)
|
||||
{
|
||||
uip.ResetGroupId();
|
||||
if (t is UIParticle uip)
|
||||
{
|
||||
uip.ResetGroupId();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -199,16 +231,32 @@ namespace Coffee.UIExtensions
|
||||
EditorGUILayout.PropertyField(_positionMode);
|
||||
|
||||
// Auto Scaling
|
||||
DrawAutoScaling(_autoScalingMode, targets.OfType<UIParticle>());
|
||||
EditorGUILayout.PropertyField(_autoScalingMode);
|
||||
|
||||
// Custom View Size
|
||||
EditorGUILayout.PropertyField(_useCustomView);
|
||||
EditorGUI.BeginChangeCheck();
|
||||
EditorGUI.BeginDisabledGroup(!_useCustomView.boolValue);
|
||||
EditorGUI.indentLevel++;
|
||||
EditorGUILayout.PropertyField(_customViewSize);
|
||||
EditorGUI.indentLevel--;
|
||||
EditorGUI.EndDisabledGroup();
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
_customViewSize.floatValue = Mathf.Max(0.1f, _customViewSize.floatValue);
|
||||
}
|
||||
|
||||
// Time Scale Multiplier
|
||||
EditorGUILayout.PropertyField(_timeScaleMultiplier);
|
||||
|
||||
// Target ParticleSystems.
|
||||
EditorGUI.BeginChangeCheck();
|
||||
EditorGUI.BeginDisabledGroup(targets.OfType<UIParticle>().Any(x => !x.canvas));
|
||||
_ro.DoLayoutList();
|
||||
EditorGUI.EndDisabledGroup();
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
EditorApplication.QueuePlayerLoopUpdate();
|
||||
foreach (var uip in targets.OfType<UIParticle>())
|
||||
{
|
||||
uip.RefreshParticles(uip.particles);
|
||||
@@ -216,9 +264,10 @@ namespace Coffee.UIExtensions
|
||||
}
|
||||
|
||||
// Non-UI built-in shader is not supported.
|
||||
foreach (var mat in current.materials)
|
||||
Profiler.BeginSample("(UIP:E) Non-UI built-in shader is not supported.");
|
||||
foreach (var mat in s_TempMaterials)
|
||||
{
|
||||
if (!mat || !mat.shader) continue;
|
||||
if (mat == null || mat.shader == null) continue;
|
||||
var shader = mat.shader;
|
||||
if (IsBuiltInObject(shader) && !shader.name.StartsWith("UI/"))
|
||||
{
|
||||
@@ -229,15 +278,18 @@ namespace Coffee.UIExtensions
|
||||
}
|
||||
}
|
||||
|
||||
Profiler.EndSample();
|
||||
|
||||
// Does the shader support UI masks?
|
||||
Profiler.BeginSample("(UIP:E) Does the shader support UI masks?");
|
||||
if (current.maskable && current.GetComponentInParent<Mask>(false))
|
||||
{
|
||||
foreach (var mat in current.materials)
|
||||
foreach (var mat in s_TempMaterials)
|
||||
{
|
||||
if (!mat || !mat.shader) continue;
|
||||
if (mat == null || mat.shader == null) continue;
|
||||
var shader = mat.shader;
|
||||
if (s_Shaders.Contains(shader)) continue;
|
||||
s_Shaders.Add(shader);
|
||||
if (!s_Shaders.Add(shader)) continue;
|
||||
|
||||
foreach (var propName in s_MaskablePropertyNames)
|
||||
{
|
||||
if (mat.HasProperty(propName)) continue;
|
||||
@@ -251,7 +303,9 @@ namespace Coffee.UIExtensions
|
||||
}
|
||||
}
|
||||
|
||||
s_TempMaterials.Clear();
|
||||
s_Shaders.Clear();
|
||||
Profiler.EndSample();
|
||||
|
||||
// UIParticle for trail should be removed.
|
||||
var label = "This UIParticle component should be removed. The UIParticle for trails is no longer needed.";
|
||||
@@ -290,12 +344,14 @@ namespace Coffee.UIExtensions
|
||||
}
|
||||
}
|
||||
#endif
|
||||
Profiler.EndSample();
|
||||
}
|
||||
|
||||
private bool IsBuiltInObject(Object obj)
|
||||
private static bool IsBuiltInObject(Object obj)
|
||||
{
|
||||
return AssetDatabase.TryGetGUIDAndLocalFileIdentifier(obj, out var guid, out long _)
|
||||
&& Regex.IsMatch(guid, "^0{16}.0{15}$", RegexOptions.Compiled);
|
||||
return AssetDatabase.IsMainAsset(obj)
|
||||
&& AssetDatabase.TryGetGUIDAndLocalFileIdentifier(obj, out var guid, out long _)
|
||||
&& s_RegexBuiltInGuid.IsMatch(guid);
|
||||
}
|
||||
|
||||
#if UNITY_2018 || UNITY_2019
|
||||
@@ -389,7 +445,7 @@ namespace Coffee.UIExtensions
|
||||
{
|
||||
EditorGUI.BeginDisabledGroup(true);
|
||||
var obj = UIParticleUpdater.GetPrimary(spGroupId.intValue);
|
||||
EditorGUILayout.ObjectField("Primary", obj, typeof(UIParticle), false);
|
||||
EditorGUILayout.ObjectField(s_ContentPrimary, obj, typeof(UIParticle), false);
|
||||
EditorGUI.EndDisabledGroup();
|
||||
}
|
||||
|
||||
@@ -399,7 +455,7 @@ namespace Coffee.UIExtensions
|
||||
return showMax;
|
||||
}
|
||||
|
||||
private static void DrawAutoScaling(SerializedProperty prop, IEnumerable<UIParticle> uiParticles)
|
||||
private static void DrawAutoScaling(SerializedProperty prop)
|
||||
{
|
||||
EditorGUILayout.PropertyField(prop);
|
||||
}
|
||||
@@ -408,7 +464,9 @@ namespace Coffee.UIExtensions
|
||||
{
|
||||
if (!p || (ignoreCurrent && target == p)) return;
|
||||
|
||||
var cr = p.canvasRenderer;
|
||||
DestroyImmediate(p);
|
||||
DestroyImmediate(cr);
|
||||
|
||||
#if UNITY_2018_3_OR_NEWER
|
||||
var stage = PrefabStageUtility.GetCurrentPrefabStage();
|
||||
|
||||
|
Before Width: | Height: | Size: 418 B After Width: | Height: | Size: 418 B |
@@ -1,61 +1,85 @@
|
||||
# <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)
|
||||
|
||||
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.
|
||||
# <img alt="UIParticleIcon" src="https://github.com/mob-sakai/ParticleEffectForUGUI/assets/12690315/d76e105e-a840-4f61-a1f6-8cf311c0812d" width="26"/> Particle Effect For UGUI (UI Particle) <!-- omit in toc -->
|
||||
|
||||
[](https://openupm.com/packages/com.coffee.ui-particle/)
|
||||
[](https://github.com/mob-sakai/ParticleEffectForUGUI/releases)
|
||||
[](https://github.com/mob-sakai/ParticleEffectForUGUI/blob/main/LICENSE.txt)
|
||||
[](https://github.com/mob-sakai/ParticleEffectForUGUI/releases)
|
||||
[](https://github.com/mob-sakai/ParticleEffectForUGUI/blob/main/LICENSE.md)
|
||||

|
||||

|
||||

|
||||

|
||||
[](http://makeapullrequest.com)
|
||||
[](https://github.com/mob-sakai/ParticleEffectForUGUI/subscription)
|
||||
[](https://twitter.com/intent/follow?screen_name=mob_sakai)
|
||||
|
||||
<< [📝 Description](#-description) | [🎮 Demo](#-demo) | [⚙ Installation](#-installation) | [🚀 Usage](#-usage) | [🛠 Development Note](#-development-note) | [🤝 Contributing](#-contributing) >>
|
||||
<< [📝 Description](#-description-) | [📌 Key Features](#-key-features) | [🎮 Demo](#-demo) | [⚙ Installation](#-installation) | [🚀 Usage](#-usage) | [🛠 Development Note](#-development-note) | [🤝 Contributing](#-contributing) >>
|
||||
|
||||
<br><br>
|
||||
|
||||
## 📝 Description
|
||||
## 📝 Description <!-- omit in toc -->
|
||||
|
||||

|
||||
|
||||
This package utilizes the new APIs `MeshBake/MashTrailBake` (introduced with Unity 2018.2) to render particles through
|
||||
CanvasRenderer.
|
||||
You can render, mask, and sort your ParticleSystems for UI without the necessity of an additional Camera, RenderTexture,
|
||||
or Canvas.
|
||||
This package uses the new APIs `MeshBake/MeshTrailBake` (introduced in Unity 2018.2) to render particles through `CanvasRenderer`.
|
||||
You can render, mask, and sort your `ParticleSystems` for UI without the need for an additional `Camera`, `RenderTexture`, or `Canvas`.
|
||||
|
||||
### Features
|
||||
- [📌 Key Features](#-key-features)
|
||||
- [🎮 Demo](#-demo)
|
||||
- [⚙ Installation](#-installation)
|
||||
- [Install via OpenUPM](#install-via-openupm)
|
||||
- [Install via UPM (with Package Manager UI)](#install-via-upm-with-package-manager-ui)
|
||||
- [Install via UPM (Manually)](#install-via-upm-manually)
|
||||
- [Install as Embedded Package](#install-as-embedded-package)
|
||||
- [🚀 Usage](#-usage)
|
||||
- [Component: UIParticle](#component-uiparticle)
|
||||
- [Basic Usage](#basic-usage)
|
||||
- [Usage with Your Existing ParticleSystem Prefab](#usage-with-your-existing-particlesystem-prefab)
|
||||
- [Usage with `Mask` or `RectMask2D` Component](#usage-with-mask-or-rectmask2d-component)
|
||||
- [Usage with Script](#usage-with-script)
|
||||
- [Component: UIParticleAttractor](#component-uiparticleattractor)
|
||||
- [Project Settings](#project-settings)
|
||||
- [🛠 Development Note](#-development-note)
|
||||
- [Compares the Baking mesh approach with the conventional approach](#compares-the-baking-mesh-approach-with-the-conventional-approach)
|
||||
- [Performance test results](#performance-test-results)
|
||||
- [🔍 FAQ: Why Are My UIParticles Not Displayed Correctly?](#-faq-why-are-my-uiparticles-not-displayed-correctly)
|
||||
- [Shader Limitation](#shader-limitation)
|
||||
- [Built-in shaders are not supported](#built-in-shaders-are-not-supported)
|
||||
- [(Unity 2018 or 2019) UV.zw components will be discarded](#unity-2018-or-2019-uvzw-components-will-be-discarded)
|
||||
- [(Unity 2018 or 2019) Custom vertex streams](#unity-2018-or-2019-custom-vertex-streams)
|
||||
- [Overheads](#overheads)
|
||||
- [How to Make a Custom Shader to Support `Mask` and `RectMask2D` Component](#how-to-make-a-custom-shader-to-support-mask-and-rectmask2d-component)
|
||||
- [🤝 Contributing](#-contributing)
|
||||
- [Issues](#issues)
|
||||
- [Pull Requests](#pull-requests)
|
||||
- [Support](#support)
|
||||
- [License](#license)
|
||||
- [Author](#author)
|
||||
- [See Also](#see-also)
|
||||
|
||||
* Easy to use: The package is ready to use out of the box.
|
||||
* Sort particle effects and other UI by sibling index.
|
||||
* No extra Camera, RenderTexture, or Canvas required.
|
||||
* Masking options for Mask or RectMask2D.
|
||||
* Support for the Trail module.
|
||||
* Support for CanvasGroup alpha.
|
||||
* No allocations needed to render particles.
|
||||
* Compatibility with overlay, camera space, and world space.
|
||||
* Support for Universal Render Pipeline (URP) and High Definition Render Pipeline (HDRP).
|
||||
* Support for disabling `Enter Play Mode Options > Reload Domain`.
|
||||
* Support for changing material property with AnimationClip (AnimatableProperty).
|
||||
![AnimatableProperty.gif][AnimatableProperty.gif]
|
||||
* [4.0.0+] Support for 8+ materials.
|
||||
* [4.0.0+] Correct world space particle position adjustment when changing window size for standalone platforms (Windows,
|
||||
MacOSX, and Linux).
|
||||
* [4.0.0+] Adaptive scaling for UI.
|
||||
* [4.0.0+] Mesh sharing group to improve performance.
|
||||
![MeshSharing.gif][MeshSharing.gif]
|
||||
* [4.0.0+] Particle attractor component.
|
||||
![ParticleAttractor.gif][ParticleAttractor.gif]
|
||||
* [4.1.0+] Relative/Absolute particle position mode.
|
||||
![AbsolutePosition.gif][AbsolutePosition.gif]
|
||||
<br><br>
|
||||
|
||||
[AnimatableProperty.gif]: https://user-images.githubusercontent.com/12690315/53286323-2d94a980-37b0-11e9-8afb-c4a207805ff2.gif
|
||||
## 📌 Key Features
|
||||
|
||||
[MeshSharing.gif]: https://user-images.githubusercontent.com/12690315/174311048-c882df81-6c34-4eba-b0aa-5645457692f1.gif
|
||||
|
||||
[ParticleAttractor.gif]: https://user-images.githubusercontent.com/12690315/174311027-462929a4-13f0-4ec4-86ea-9c832f2eecf1.gif
|
||||
|
||||
[AbsolutePosition.gif]: https://user-images.githubusercontent.com/12690315/175751579-5a2357e8-2ecf-4afd-83c8-66e9771bde39.gif
|
||||
* **Easy to use:** The package is ready to use out of the box.
|
||||
* **Sortable:** Sort particle effects and other UI elements by sibling index.
|
||||
* **Maskable:** Supports `Mask` or `RectMask2D`.
|
||||
* **No extra components required:** No need for an additional `Camera`, `RenderTexture`, or `Canvas`.
|
||||
* **Trail module support:** Fully supports the Trail module.
|
||||
* **CanvasGroup alpha support:** Integrates with `CanvasGroup` alpha.
|
||||
* **No allocations:** Efficiently renders particles without allocations.
|
||||
* **Any canvas render mode support:** Works with overlay, camera space, and world space.
|
||||
* **Any Render pipeline support:** Compatible with Universal Render Pipeline (URP) and High Definition Render Pipeline (HDRP).
|
||||
* **Disabling domain reload support:** Supports disabling `Enter Play Mode Options > Reload Domain`.
|
||||
* **Animatable material properties:** Supports changing material properties with AnimationClip (AnimatableProperty).
|
||||

|
||||
* **Multiple materials:** Supports 8+ materials.
|
||||
* **Correct positioning:** Adjusts world space particle positions correctly when changing window size for standalone platforms (Windows, MacOSX, and Linux).
|
||||
* **Adaptive scaling:** Provides adaptive scaling for UI (AutoScalingMode).
|
||||
* **Performance optimization:** Mesh sharing group to improve performance.
|
||||
<img alt="MeshSharing.gif" src="https://user-images.githubusercontent.com/12690315/174311048-c882df81-6c34-4eba-b0aa-5645457692f1.gif" width="450"/>
|
||||
* **Particle attractor:** Includes a particle attractor component.
|
||||
<img alt="ParticleAttractor.gif" src="https://user-images.githubusercontent.com/12690315/174311027-462929a4-13f0-4ec4-86ea-9c832f2eecf1.gif" width="450"/>
|
||||
* **Emission position mode:** Supports relative/absolute particle emission position modes.
|
||||
<img alt="AbsolutePosition.gif" src="https://user-images.githubusercontent.com/12690315/175751579-5a2357e8-2ecf-4afd-83c8-66e9771bde39.gif" width="450"/>
|
||||
* **Custom view size:** Fixes min/max particle size mismatch.
|
||||

|
||||
|
||||
<br><br>
|
||||
|
||||
@@ -76,76 +100,87 @@ or Canvas.
|
||||
|
||||
[JMO]: https://assetstore.unity.com/publishers/1669
|
||||
|
||||
|
||||
<br><br>
|
||||
|
||||
## ⚙ Installation
|
||||
|
||||
_This package requires Unity 2018.3 or later._
|
||||
_This package requires **Unity 2018.3 or later**._
|
||||
|
||||
#### Install via OpenUPM
|
||||
|
||||
This package is available on [OpenUPM](https://openupm.com) package registry.
|
||||
This is the preferred method of installation, as you can easily receive updates as they're released.
|
||||
- This package is available on [OpenUPM](https://openupm.com) package registry.
|
||||
- This is the preferred method of installation, as you can easily receive updates as they're released.
|
||||
- If you have [openupm-cli](https://github.com/openupm/openupm-cli) installed, then run the following command in your project's directory:
|
||||
```
|
||||
openupm add com.coffee.ui-particle
|
||||
```
|
||||
- To update the package, use Package Manager UI (`Window > Package Manager`) or run the following command with `@{version}`:
|
||||
```
|
||||
openupm add com.coffee.ui-particle@4.9.0
|
||||
```
|
||||
|
||||
If you have [openupm-cli](https://github.com/openupm/openupm-cli) installed, then run the following command in your
|
||||
project's directory:
|
||||
#### Install via UPM (with Package Manager UI)
|
||||
|
||||
```sh
|
||||
openupm add com.coffee.ui-particle
|
||||
```
|
||||
- Click `Window > Package Manager` to open Package Manager UI.
|
||||
- Click `+ > Add package from git URL...` and input the repository URL: `https://github.com/mob-sakai/ParticleEffectForUGUI.git`
|
||||

|
||||
- To update the package, change suffix `#{version}` to the target version.
|
||||
- e.g. `https://github.com/mob-sakai/ParticleEffectForUGUI.git#4.9.0`
|
||||
|
||||
#### Install via UPM (using Git URL)
|
||||
#### Install via UPM (Manually)
|
||||
|
||||
Navigate to your project's Packages folder and open the `manifest.json` file. Then add this package somewhere in
|
||||
the `dependencies` block:
|
||||
|
||||
```json
|
||||
{
|
||||
"dependencies": {
|
||||
"com.coffee.ui-particle": "https://github.com/mob-sakai/ParticleEffectForUGUI.git",
|
||||
...
|
||||
- Open the `Packages/manifest.json` file in your project. Then add this package somewhere in the `dependencies` block:
|
||||
```json
|
||||
{
|
||||
"dependencies": {
|
||||
"com.coffee.ui-particle": "https://github.com/mob-sakai/ParticleEffectForUGUI.git",
|
||||
...
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
```
|
||||
|
||||
To update the package, change suffix `#{version}` to the target version.
|
||||
- To update the package, change suffix `#{version}` to the target version.
|
||||
- e.g. `"com.coffee.ui-particle": "https://github.com/mob-sakai/ParticleEffectForUGUI.git#4.9.0",`
|
||||
|
||||
* e.g. `"com.coffee.ui-particle": "https://github.com/mob-sakai/ParticleEffectForUGUI.git#4.6.0",`
|
||||
#### Install as Embedded Package
|
||||
|
||||
Or, use [UpmGitExtension](https://github.com/mob-sakai/UpmGitExtension) to install and update the package.
|
||||
|
||||
<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`.
|
||||
-
|
||||
1. Download a source code zip file from [Releases](https://github.com/mob-sakai/ParticleEffectForUGUI/releases) and extract it.
|
||||
2. Place it in your project's `Packages` directory.
|
||||

|
||||
- If you want to fix bugs or add features, install it as an embedded package.
|
||||
- To update the package, you need to re-download it and replace the contents.
|
||||
|
||||
<br><br>
|
||||
|
||||
## 🚀 Usage
|
||||
|
||||
### UIParticle Component
|
||||
### Component: UIParticle
|
||||
|
||||
`UIParticle` controls the ParticleSystems that are attached to its own game objects and child game objects.
|
||||
|
||||

|
||||

|
||||
|
||||
- **Maskable**: Does this graphic allow masking.
|
||||
- **Scale**: Scale the rendering. When the `3D` toggle is enabled, 3D scale (x, y, z) is supported.
|
||||
- **Maskable**: Does this graphic allow maskable.
|
||||
- **Scale**: Scale the rendering particles. When the `3D` toggle is enabled, 3D scale (x, y, z) is supported.
|
||||
- **Animatable Properties**: If you want to update material properties (e.g., `_MainTex_ST`, `_Color`) in AnimationClip,
|
||||
use this to mark the changes.
|
||||
use this to mark as animatable.
|
||||
- **Mesh Sharing**: Particle simulation results are shared within the same group. A large number of the same effects can
|
||||
be displayed with a small load. When the `Random` toggle is enabled, it will be grouped randomly.
|
||||
- **None:** Disable mesh sharing.
|
||||
- **Auto:** Automatically select Primary/Replica.
|
||||
- **Primary:** Provides particle simulation results to the same group.
|
||||
- **Primary Simulator:** Primary, but do not render the particle (simulation only).
|
||||
- **Replica:** Render simulation results provided by the primary.
|
||||
- **Position Mode**: Emission position mode.
|
||||
- **Absolute:** Emit from the world position of the `ParticleSystem`.
|
||||
- **Relative:** Emit from the scaled position of the `ParticleSystem`.
|
||||
- **Auto Scaling**: `Transform.lossyScale` (=world scale) will be set to `(1, 1, 1)` on update. It prevents the
|
||||
root-Canvas scale from affecting the hierarchy-scaled `ParticleSystem`.
|
||||
- **Absolute:** The particles will be emitted from the world position.
|
||||
- **Relative:** The particles will be emitted from the scaled position.
|
||||
- **Auto Scaling Mode**: How to automatically adjust when the Canvas scale is changed by the screen size or reference resolution.
|
||||
- **None:** Do nothing.
|
||||
- **Transform:** Transform.lossyScale (=world scale) will be set to (1, 1, 1).
|
||||
- **UIParticle:** UIParticle.scale will be adjusted.
|
||||
- **Use Custom View:** Use this if the particles are not displayed correctly due to min/max particle size.
|
||||
- **Custom view size:** Change the bake view size.
|
||||
- **Time Scale Multiplier:** Time scale multiplier.
|
||||
- **Rendering Order**: The ParticleSystem list to be rendered. You can change the order and the materials.
|
||||
|
||||
**NOTE:** Press the `Refresh` button to reconstruct the rendering order based on children ParticleSystem's sorting order
|
||||
@@ -153,7 +188,7 @@ and z-position.
|
||||
|
||||
<br><br>
|
||||
|
||||
#### Basic Usage
|
||||
### Basic Usage
|
||||
|
||||
1. Select `GameObject/UI/ParticleSystem` to create UIParticle with a ParticleSystem.
|
||||

|
||||
@@ -162,7 +197,7 @@ and z-position.
|
||||
|
||||
<br>
|
||||
|
||||
#### With Your Existing ParticleSystem Prefab
|
||||
### Usage with Your Existing ParticleSystem Prefab
|
||||
|
||||
1. Select `GameObject/UI/ParticleSystem (Empty)` to create UIParticle.
|
||||

|
||||
@@ -171,19 +206,19 @@ and z-position.
|
||||
|
||||
<br>
|
||||
|
||||
#### With `Mask` or `RectMask2D` Component
|
||||
### Usage with `Mask` or `RectMask2D` Component
|
||||
|
||||
If you want to mask particles, set a stencil-supported shader (such as `UI/UIAdditive`) to the material for
|
||||
ParticleSystem.
|
||||
If you use some custom shaders, see
|
||||
the [How to Make a Custom Shader to Support Mask/RectMask2D Component](#how-to-make-a-custom-shader-to-support-maskrectmask2d-component)
|
||||
the [How to Make a Custom Shader to Support Mask/RectMask2D Component](#how-to-make-a-custom-shader-to-support-mask-and-rectmask2d-component)
|
||||
section.
|
||||
|
||||

|
||||
|
||||
<br><br>
|
||||
|
||||
### Script usage
|
||||
### Usage with Script
|
||||
|
||||
```cs
|
||||
// Instantiate ParticleSystem prefab with UIParticle on runtime.
|
||||
@@ -202,14 +237,14 @@ uiParticle.Stop();
|
||||
|
||||
<br><br>
|
||||
|
||||
### UIParticleAttractor component
|
||||
### Component: UIParticleAttractor
|
||||
|
||||
`UIParticleAttractor` attracts particles generated by the specified ParticleSystem.
|
||||
|
||||

|
||||

|
||||

|
||||
|
||||
- **Particle System**: Attracts particles generated by the specified particle system.
|
||||
- **Particle Systems**: Attracts particles generated by the specified ParticleSystems.
|
||||
- **Destination Radius**: Once the particle is within the radius, the particle lifetime will become 0, and `OnAttracted`
|
||||
will be called.
|
||||
- **Delay Rate**: Delay to start attracting. It is a percentage of the particle's start lifetime.
|
||||
@@ -223,6 +258,14 @@ uiParticle.Stop();
|
||||
|
||||
<br><br>
|
||||
|
||||
### Project Settings
|
||||
|
||||

|
||||
|
||||
- Click `Edit > Project Settings` to open the Project Settings window and then select `UI > UI Particle` category.
|
||||
|
||||
<br><br>
|
||||
|
||||
## 🛠 Development Note
|
||||
|
||||
### Compares the Baking mesh approach with the conventional approach
|
||||
@@ -354,7 +397,7 @@ When improving performance, keep the following in mind:
|
||||
- Consider a single material, atlasing the sprites, and using `Sprite` mode in the `Texture Sheet Animation` module
|
||||
in the ParticleSystem.
|
||||
|
||||
### How to Make a Custom Shader to Support Mask/RectMask2D Component
|
||||
### How to Make a Custom Shader to Support `Mask` and `RectMask2D` Component
|
||||
|
||||
<details>
|
||||
<summary>Shader tips</summary>
|
||||
|
||||
BIN
Packages/src/Runtime/Coffee.UIParticle.R.dll
Normal file
BIN
Packages/src/Runtime/Coffee.UIParticle.R.dll
Normal file
Binary file not shown.
33
Packages/src/Runtime/Coffee.UIParticle.R.dll.meta
Normal file
33
Packages/src/Runtime/Coffee.UIParticle.R.dll.meta
Normal file
@@ -0,0 +1,33 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4d73b3825bf044d418ae21bb331d3902
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 1
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
Windows Store Apps: WindowsStoreApps
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -18,10 +18,10 @@ namespace Coffee.UIParticleInternal
|
||||
public static T[] GetComponentsInChildren<T>(this Component self, int depth)
|
||||
where T : Component
|
||||
{
|
||||
var results = ListPool<T>.Rent();
|
||||
var results = InternalListPool<T>.Rent();
|
||||
self.GetComponentsInChildren_Internal(results, depth);
|
||||
var array = results.ToArray();
|
||||
ListPool<T>.Return(ref results);
|
||||
InternalListPool<T>.Return(ref results);
|
||||
return array;
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace Coffee.UIParticleInternal
|
||||
private static void GetComponentsInChildren_Internal<T>(this Component self, List<T> results, int depth)
|
||||
where T : Component
|
||||
{
|
||||
if (!self || results == null || depth < 0) return;
|
||||
if (self == null || results == null || depth < 0) return;
|
||||
|
||||
var tr = self.transform;
|
||||
if (tr.TryGetComponent<T>(out var t))
|
||||
@@ -50,7 +50,7 @@ namespace Coffee.UIParticleInternal
|
||||
var childCount = tr.childCount;
|
||||
for (var i = 0; i < childCount; i++)
|
||||
{
|
||||
tr.GetChild(i).GetComponentsInChildren(results, depth - 1);
|
||||
tr.GetChild(i).GetComponentsInChildren_Internal(results, depth - 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ namespace Coffee.UIParticleInternal
|
||||
/// </summary>
|
||||
public static T GetOrAddComponent<T>(this Component self) where T : Component
|
||||
{
|
||||
if (!self) return null;
|
||||
if (self == null) return null;
|
||||
return self.TryGetComponent<T>(out var component)
|
||||
? component
|
||||
: self.gameObject.AddComponent<T>();
|
||||
@@ -134,10 +134,39 @@ namespace Coffee.UIParticleInternal
|
||||
Profiler.EndSample();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add a component of a specific type to the children of a GameObject.
|
||||
/// </summary>
|
||||
public static void AddComponentOnChildren<T>(this Component self, bool includeSelf)
|
||||
where T : Component
|
||||
{
|
||||
if (self == null) return;
|
||||
|
||||
Profiler.BeginSample("(COF)[ComponentExt] AddComponentOnChildren > Self");
|
||||
if (includeSelf && !self.TryGetComponent<T>(out _))
|
||||
{
|
||||
self.gameObject.AddComponent<T>();
|
||||
}
|
||||
|
||||
Profiler.EndSample();
|
||||
|
||||
Profiler.BeginSample("(COF)[ComponentExt] AddComponentOnChildren > Child");
|
||||
var childCount = self.transform.childCount;
|
||||
for (var i = 0; i < childCount; i++)
|
||||
{
|
||||
var child = self.transform.GetChild(i);
|
||||
if (child.TryGetComponent<T>(out _)) continue;
|
||||
|
||||
child.gameObject.AddComponent<T>();
|
||||
}
|
||||
|
||||
Profiler.EndSample();
|
||||
}
|
||||
|
||||
#if !UNITY_2021_2_OR_NEWER && !UNITY_2020_3_45 && !UNITY_2020_3_46 && !UNITY_2020_3_47 && !UNITY_2020_3_48
|
||||
public static T GetComponentInParent<T>(this Component self, bool includeInactive) where T : Component
|
||||
{
|
||||
if (!self) return null;
|
||||
if (self == null) return null;
|
||||
if (!includeInactive) return self.GetComponentInParent<T>();
|
||||
|
||||
var current = self.transform;
|
||||
@@ -155,9 +184,9 @@ namespace Coffee.UIParticleInternal
|
||||
/// <summary>
|
||||
/// Verify whether it can be converted to the specified component.
|
||||
/// </summary>
|
||||
internal static bool CanConvertTo<T>(this Object context) where T : MonoBehaviour
|
||||
internal static bool CanConvertTo<T>(this Object context) where T : MonoBehaviour
|
||||
{
|
||||
return context && context.GetType() != typeof(T);
|
||||
return context != null && context.GetType() != typeof(T);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -175,7 +204,7 @@ namespace Coffee.UIParticleInternal
|
||||
target.enabled = false;
|
||||
|
||||
// Find MonoScript of the specified component.
|
||||
foreach (var script in Resources.FindObjectsOfTypeAll<MonoScript>())
|
||||
foreach (var script in MonoImporter.GetAllRuntimeMonoScripts())
|
||||
{
|
||||
if (script.GetClass() != typeof(T))
|
||||
{
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Coffee.UIParticleInternal
|
||||
{
|
||||
/// <summary>
|
||||
/// Extension methods for Component class.
|
||||
/// </summary>
|
||||
internal static class ListExtensions
|
||||
{
|
||||
public static void RemoveAtFast<T>(this List<T> self, int index)
|
||||
{
|
||||
if (self == null) return;
|
||||
|
||||
var lastIndex = self.Count - 1;
|
||||
self[index] = self[lastIndex];
|
||||
self.RemoveAt(lastIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 833553390099d40c9b212823f0852c46
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,48 +0,0 @@
|
||||
using System.Diagnostics;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Coffee.UIParticleInternal
|
||||
{
|
||||
internal static class Misc
|
||||
{
|
||||
public static void Destroy(Object obj)
|
||||
{
|
||||
if (!obj) return;
|
||||
#if UNITY_EDITOR
|
||||
if (!Application.isPlaying)
|
||||
{
|
||||
Object.DestroyImmediate(obj);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
Object.Destroy(obj);
|
||||
}
|
||||
}
|
||||
|
||||
public static void DestroyImmediate(Object obj)
|
||||
{
|
||||
if (!obj) return;
|
||||
#if UNITY_EDITOR
|
||||
if (Application.isEditor)
|
||||
{
|
||||
Object.DestroyImmediate(obj);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
Object.Destroy(obj);
|
||||
}
|
||||
}
|
||||
|
||||
[Conditional("UNITY_EDITOR")]
|
||||
public static void SetDirty(Object obj)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (!obj) return;
|
||||
EditorUtility.SetDirty(obj);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,23 +17,25 @@ namespace Coffee.UIParticleInternal
|
||||
Type.GetType("UnityEditor.Experimental.U2D.SpriteEditorExtension, UnityEditor")
|
||||
?? Type.GetType("UnityEditor.U2D.SpriteEditorExtension, UnityEditor");
|
||||
|
||||
private static readonly MethodInfo s_GetActiveAtlasTextureMethod = s_SpriteEditorExtensionType
|
||||
.GetMethod("GetActiveAtlasTexture", BindingFlags.Static | BindingFlags.NonPublic);
|
||||
private static readonly Func<Sprite, Texture2D> s_GetActiveAtlasTextureMethod =
|
||||
(Func<Sprite, Texture2D>)Delegate.CreateDelegate(typeof(Func<Sprite, Texture2D>),
|
||||
s_SpriteEditorExtensionType
|
||||
.GetMethod("GetActiveAtlasTexture", BindingFlags.Static | BindingFlags.NonPublic));
|
||||
|
||||
private static readonly MethodInfo s_GetActiveAtlasMethod = s_SpriteEditorExtensionType
|
||||
.GetMethod("GetActiveAtlas", BindingFlags.Static | BindingFlags.NonPublic);
|
||||
private static readonly Func<Sprite, SpriteAtlas> s_GetActiveAtlasMethod =
|
||||
(Func<Sprite, SpriteAtlas>)Delegate.CreateDelegate(typeof(Func<Sprite, SpriteAtlas>),
|
||||
s_SpriteEditorExtensionType
|
||||
.GetMethod("GetActiveAtlas", BindingFlags.Static | BindingFlags.NonPublic));
|
||||
|
||||
/// <summary>
|
||||
/// Get the actual texture of a sprite in play mode or edit mode.
|
||||
/// </summary>
|
||||
public static Texture2D GetActualTexture(this Sprite self)
|
||||
{
|
||||
if (!self) return null;
|
||||
if (self == null) return null;
|
||||
|
||||
if (Application.isPlaying) return self.texture;
|
||||
|
||||
var ret = s_GetActiveAtlasTextureMethod.Invoke(null, new object[] { self }) as Texture2D;
|
||||
return ret ? ret : self.texture;
|
||||
var ret = s_GetActiveAtlasTextureMethod(self);
|
||||
return ret != null ? ret : self.texture;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -41,9 +43,9 @@ namespace Coffee.UIParticleInternal
|
||||
/// </summary>
|
||||
public static SpriteAtlas GetActiveAtlas(this Sprite self)
|
||||
{
|
||||
if (!self) return null;
|
||||
if (self == null) return null;
|
||||
|
||||
return s_GetActiveAtlasMethod.Invoke(null, new object[] { self }) as SpriteAtlas;
|
||||
return s_GetActiveAtlasMethod(self);
|
||||
}
|
||||
#else
|
||||
/// <summary>
|
||||
@@ -51,7 +53,7 @@ namespace Coffee.UIParticleInternal
|
||||
/// </summary>
|
||||
internal static Texture2D GetActualTexture(this Sprite self)
|
||||
{
|
||||
return self ? self.texture : null;
|
||||
return self != null ? self.texture : null;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
using Object = UnityEngine.Object;
|
||||
#if UNITY_EDITOR
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEditor.Build;
|
||||
using UnityEditor.Build.Reporting;
|
||||
@@ -13,41 +13,51 @@ namespace Coffee.UIParticleInternal
|
||||
{
|
||||
public abstract class PreloadedProjectSettings : ScriptableObject
|
||||
#if UNITY_EDITOR
|
||||
, IPreprocessBuildWithReport
|
||||
{
|
||||
int IOrderedCallback.callbackOrder => 0;
|
||||
|
||||
void IPreprocessBuildWithReport.OnPreprocessBuild(BuildReport report)
|
||||
private class Postprocessor : AssetPostprocessor
|
||||
{
|
||||
Initialize();
|
||||
private static void OnPostprocessAllAssets(string[] _, string[] __, string[] ___, string[] ____)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
}
|
||||
|
||||
private class PreprocessBuildWithReport : IPreprocessBuildWithReport
|
||||
{
|
||||
int IOrderedCallback.callbackOrder => 0;
|
||||
|
||||
void IPreprocessBuildWithReport.OnPreprocessBuild(BuildReport report)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
}
|
||||
|
||||
[InitializeOnLoadMethod]
|
||||
[InitializeOnEnterPlayMode]
|
||||
private static void Initialize()
|
||||
{
|
||||
const BindingFlags flags = BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy;
|
||||
foreach (var t in TypeCache.GetTypesDerivedFrom(typeof(PreloadedProjectSettings<>)))
|
||||
{
|
||||
var defaultSettings = GetDefaultSettings(t);
|
||||
if (!defaultSettings)
|
||||
if (defaultSettings == null)
|
||||
{
|
||||
defaultSettings = t.GetProperty("instance", flags)
|
||||
?.GetValue(null, null) as PreloadedProjectSettings;
|
||||
// When create a new instance, automatically set it as default settings.
|
||||
defaultSettings = CreateInstance(t) as PreloadedProjectSettings;
|
||||
SetDefaultSettings(defaultSettings);
|
||||
}
|
||||
else if (GetPreloadedSettings(t).Length != 1)
|
||||
{
|
||||
SetDefaultSettings(defaultSettings);
|
||||
}
|
||||
}
|
||||
|
||||
EditorApplication.QueuePlayerLoopUpdate();
|
||||
if (defaultSettings != null)
|
||||
{
|
||||
defaultSettings.OnInitialize();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected static string GetDefaultName(Type type, bool nicify)
|
||||
{
|
||||
var typeName = type.Name.Replace("ProjectSettings", "");
|
||||
var typeName = type.Name;
|
||||
return nicify
|
||||
? ObjectNames.NicifyVariableName(typeName)
|
||||
: typeName;
|
||||
@@ -56,7 +66,7 @@ namespace Coffee.UIParticleInternal
|
||||
private static Object[] GetPreloadedSettings(Type type)
|
||||
{
|
||||
return PlayerSettings.GetPreloadedAssets()
|
||||
.Where(x => x && x.GetType() == type)
|
||||
.Where(x => x != null && x.GetType() == type)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
@@ -66,11 +76,13 @@ namespace Coffee.UIParticleInternal
|
||||
?? AssetDatabase.FindAssets($"t:{nameof(PreloadedProjectSettings)}")
|
||||
.Select(AssetDatabase.GUIDToAssetPath)
|
||||
.Select(AssetDatabase.LoadAssetAtPath<PreloadedProjectSettings>)
|
||||
.FirstOrDefault(x => x && x.GetType() == type);
|
||||
.FirstOrDefault(x => x != null && x.GetType() == type);
|
||||
}
|
||||
|
||||
protected static void SetDefaultSettings(PreloadedProjectSettings asset)
|
||||
{
|
||||
if (asset == null) return;
|
||||
|
||||
var type = asset.GetType();
|
||||
if (string.IsNullOrEmpty(AssetDatabase.GetAssetPath(asset)))
|
||||
{
|
||||
@@ -81,13 +93,17 @@ namespace Coffee.UIParticleInternal
|
||||
|
||||
var assetPath = $"Assets/ProjectSettings/{GetDefaultName(type, false)}.asset";
|
||||
assetPath = AssetDatabase.GenerateUniqueAssetPath(assetPath);
|
||||
AssetDatabase.CreateAsset(asset, assetPath);
|
||||
if (!File.Exists(assetPath))
|
||||
{
|
||||
AssetDatabase.CreateAsset(asset, assetPath);
|
||||
asset.OnCreateAsset();
|
||||
}
|
||||
}
|
||||
|
||||
var preloadedAssets = PlayerSettings.GetPreloadedAssets();
|
||||
var projectSettings = GetPreloadedSettings(type);
|
||||
PlayerSettings.SetPreloadedAssets(preloadedAssets
|
||||
.Where(x => x)
|
||||
.Where(x => x != null)
|
||||
.Except(projectSettings.Except(new[] { asset }))
|
||||
.Append(asset)
|
||||
.Distinct()
|
||||
@@ -95,13 +111,20 @@ namespace Coffee.UIParticleInternal
|
||||
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
|
||||
protected virtual void OnCreateAsset()
|
||||
{
|
||||
}
|
||||
|
||||
protected virtual void OnInitialize()
|
||||
{
|
||||
}
|
||||
}
|
||||
#else
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
public abstract class PreloadedProjectSettings<T> : PreloadedProjectSettings
|
||||
where T : PreloadedProjectSettings<T>
|
||||
{
|
||||
@@ -110,17 +133,19 @@ namespace Coffee.UIParticleInternal
|
||||
#if UNITY_EDITOR
|
||||
private string _jsonText;
|
||||
|
||||
public static bool hasInstance => s_Instance != null;
|
||||
|
||||
public static T instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (s_Instance) return s_Instance;
|
||||
if (s_Instance != null) return s_Instance;
|
||||
|
||||
s_Instance = GetDefaultSettings(typeof(T)) as T;
|
||||
if (s_Instance) return s_Instance;
|
||||
if (s_Instance != null) return s_Instance;
|
||||
|
||||
s_Instance = CreateInstance<T>();
|
||||
if (!s_Instance)
|
||||
if (s_Instance == null)
|
||||
{
|
||||
s_Instance = null;
|
||||
return s_Instance;
|
||||
@@ -149,7 +174,7 @@ namespace Coffee.UIParticleInternal
|
||||
}
|
||||
}
|
||||
#else
|
||||
public static T instance => s_Instance ? s_Instance : s_Instance = CreateInstance<T>();
|
||||
public static T instance => s_Instance != null ? s_Instance : s_Instance = CreateInstance<T>();
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
@@ -158,7 +183,7 @@ namespace Coffee.UIParticleInternal
|
||||
protected virtual void OnEnable()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
var isDefaultSettings = !s_Instance || s_Instance == this || GetDefaultSettings(typeof(T)) == this;
|
||||
var isDefaultSettings = s_Instance == null || s_Instance == this || GetDefaultSettings(typeof(T)) == this;
|
||||
if (!isDefaultSettings)
|
||||
{
|
||||
DestroyImmediate(this, true);
|
||||
@@ -168,7 +193,7 @@ namespace Coffee.UIParticleInternal
|
||||
EditorApplication.playModeStateChanged += OnPlayModeStateChanged;
|
||||
#endif
|
||||
|
||||
if (s_Instance) return;
|
||||
if (s_Instance != null) return;
|
||||
s_Instance = this as T;
|
||||
}
|
||||
|
||||
@@ -197,7 +222,7 @@ namespace Coffee.UIParticleInternal
|
||||
|
||||
public override void OnGUI(string searchContext)
|
||||
{
|
||||
if (!_target)
|
||||
if (_target == null)
|
||||
{
|
||||
if (_editor)
|
||||
{
|
||||
|
||||
@@ -10,8 +10,9 @@ namespace Coffee.UIParticleInternal
|
||||
/// </summary>
|
||||
internal class FastActionBase<T>
|
||||
{
|
||||
private static readonly ObjectPool<LinkedListNode<T>> s_NodePool =
|
||||
new ObjectPool<LinkedListNode<T>>(() => new LinkedListNode<T>(default), _ => true, x => x.Value = default);
|
||||
private static readonly InternalObjectPool<LinkedListNode<T>> s_NodePool =
|
||||
new InternalObjectPool<LinkedListNode<T>>(() => new LinkedListNode<T>(default), _ => true,
|
||||
x => x.Value = default);
|
||||
|
||||
private readonly LinkedList<T> _delegates = new LinkedList<T>();
|
||||
|
||||
@@ -20,6 +21,7 @@ namespace Coffee.UIParticleInternal
|
||||
/// </summary>
|
||||
public void Add(T rhs)
|
||||
{
|
||||
if (rhs == null) return;
|
||||
Profiler.BeginSample("(COF)[FastAction] Add Action");
|
||||
var node = s_NodePool.Rent();
|
||||
node.Value = rhs;
|
||||
@@ -32,6 +34,7 @@ namespace Coffee.UIParticleInternal
|
||||
/// </summary>
|
||||
public void Remove(T rhs)
|
||||
{
|
||||
if (rhs == null) return;
|
||||
Profiler.BeginSample("(COF)[FastAction] Remove Action");
|
||||
var node = _delegates.Find(rhs);
|
||||
if (node != null)
|
||||
@@ -63,6 +66,11 @@ namespace Coffee.UIParticleInternal
|
||||
node = node.Next;
|
||||
}
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
_delegates.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -46,7 +46,6 @@ namespace Coffee.UIParticleInternal
|
||||
GetFrameCache<T>().Set((key1.GetHashCode(), key2.GetHashCode()), result);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Sets a value in the frame cache with a specified key.
|
||||
/// </summary>
|
||||
|
||||
@@ -5,7 +5,6 @@ using Object = UnityEngine.Object;
|
||||
#if ENABLE_COFFEE_LOGGER
|
||||
using System.Reflection;
|
||||
using System.Collections.Generic;
|
||||
|
||||
#else
|
||||
using Conditional = System.Diagnostics.ConditionalAttribute;
|
||||
#endif
|
||||
@@ -43,44 +42,40 @@ namespace Coffee.UIParticleInternal
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#if !ENABLE_COFFEE_LOGGER
|
||||
[Conditional(k_DisableSymbol)]
|
||||
#endif
|
||||
public static void LogIf(bool enable, object tag, object message, Object context = null)
|
||||
{
|
||||
if (!enable) return;
|
||||
Log_Internal(LogType.Log, tag, message, context ? context : tag as Object);
|
||||
Log_Internal(LogType.Log, tag, message, context != null ? context : tag as Object);
|
||||
}
|
||||
|
||||
|
||||
#if !ENABLE_COFFEE_LOGGER
|
||||
[Conditional(k_DisableSymbol)]
|
||||
#endif
|
||||
public static void Log(object tag, object message, Object context = null)
|
||||
{
|
||||
Log_Internal(LogType.Log, tag, message, context ? context : tag as Object);
|
||||
Log_Internal(LogType.Log, tag, message, context != null ? context : tag as Object);
|
||||
}
|
||||
|
||||
|
||||
#if !ENABLE_COFFEE_LOGGER
|
||||
[Conditional(k_DisableSymbol)]
|
||||
#endif
|
||||
public static void LogWarning(object tag, object message, Object context = null)
|
||||
{
|
||||
Log_Internal(LogType.Warning, tag, message, context ? context : tag as Object);
|
||||
Log_Internal(LogType.Warning, tag, message, context != null ? context : tag as Object);
|
||||
}
|
||||
|
||||
public static void LogError(object tag, object message, Object context = null)
|
||||
{
|
||||
#if ENABLE_COFFEE_LOGGER
|
||||
Log_Internal(LogType.Error, tag, message, context ? context : tag as Object);
|
||||
Log_Internal(LogType.Error, tag, message, context != null ? context : tag as Object);
|
||||
#else
|
||||
Debug.LogError($"{tag}: {message}", context);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#if !ENABLE_COFFEE_LOGGER
|
||||
[Conditional(k_DisableSymbol)]
|
||||
#endif
|
||||
@@ -124,7 +119,6 @@ namespace Coffee.UIParticleInternal
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#if !ENABLE_COFFEE_LOGGER
|
||||
[Conditional(k_DisableSymbol)]
|
||||
#endif
|
||||
@@ -141,6 +135,9 @@ namespace Coffee.UIParticleInternal
|
||||
|
||||
switch (tag)
|
||||
{
|
||||
case string name:
|
||||
sb.Append(name);
|
||||
break;
|
||||
case Type type:
|
||||
AppendType(sb, type);
|
||||
break;
|
||||
@@ -167,7 +164,6 @@ namespace Coffee.UIParticleInternal
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#if !ENABLE_COFFEE_LOGGER
|
||||
[Conditional(k_DisableSymbol)]
|
||||
#endif
|
||||
@@ -206,7 +202,6 @@ namespace Coffee.UIParticleInternal
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#if !ENABLE_COFFEE_LOGGER
|
||||
[Conditional(k_DisableSymbol)]
|
||||
#endif
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace Coffee.UIParticleInternal
|
||||
|
||||
#if UNITY_EDITOR
|
||||
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
|
||||
private static void Clear()
|
||||
public static void Clear()
|
||||
{
|
||||
s_Repository.Clear();
|
||||
}
|
||||
@@ -55,7 +55,6 @@ namespace Coffee.UIParticleInternal
|
||||
Profiler.EndSample();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Adds or retrieves a cached material based on the hash.
|
||||
/// </summary>
|
||||
|
||||
132
Packages/src/Runtime/Internal/Utilities/Misc.cs
Normal file
132
Packages/src/Runtime/Internal/Utilities/Misc.cs
Normal file
@@ -0,0 +1,132 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using Object = UnityEngine.Object;
|
||||
#if UNITY_EDITOR
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
#if UNITY_2021_2_OR_NEWER
|
||||
using UnityEditor.SceneManagement;
|
||||
#else
|
||||
using UnityEditor.Experimental.SceneManagement;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace Coffee.UIParticleInternal
|
||||
{
|
||||
internal static class Misc
|
||||
{
|
||||
public static T[] FindObjectsOfType<T>() where T : Object
|
||||
{
|
||||
#if UNITY_2023_1_OR_NEWER
|
||||
return Object.FindObjectsByType<T>(FindObjectsInactive.Include, FindObjectsSortMode.None);
|
||||
#else
|
||||
return Object.FindObjectsOfType<T>();
|
||||
#endif
|
||||
}
|
||||
|
||||
public static void Destroy(Object obj)
|
||||
{
|
||||
if (obj == null) return;
|
||||
#if UNITY_EDITOR
|
||||
if (!Application.isPlaying)
|
||||
{
|
||||
Object.DestroyImmediate(obj);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
Object.Destroy(obj);
|
||||
}
|
||||
}
|
||||
|
||||
public static void DestroyImmediate(Object obj)
|
||||
{
|
||||
if (obj == null) return;
|
||||
#if UNITY_EDITOR
|
||||
if (Application.isEditor)
|
||||
{
|
||||
Object.DestroyImmediate(obj);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
Object.Destroy(obj);
|
||||
}
|
||||
}
|
||||
|
||||
[Conditional("UNITY_EDITOR")]
|
||||
public static void SetDirty(Object obj)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (obj == null) return;
|
||||
EditorUtility.SetDirty(obj);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
public static T[] GetAllComponentsInPrefabStage<T>() where T : Component
|
||||
{
|
||||
var prefabStage = PrefabStageUtility.GetCurrentPrefabStage();
|
||||
if (prefabStage == null) return Array.Empty<T>();
|
||||
|
||||
return prefabStage.prefabContentsRoot.GetComponentsInChildren<T>(true);
|
||||
}
|
||||
|
||||
public static bool isBatchOrBuilding => Application.isBatchMode || BuildPipeline.isBuildingPlayer;
|
||||
#endif
|
||||
|
||||
[Conditional("UNITY_EDITOR")]
|
||||
public static void QueuePlayerLoopUpdate()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (!EditorApplication.isPlaying)
|
||||
{
|
||||
EditorApplication.QueuePlayerLoopUpdate();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#if !UNITY_2021_2_OR_NEWER
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
[Conditional("UNITY_EDITOR")]
|
||||
internal class IconAttribute : Attribute
|
||||
{
|
||||
private readonly string _path;
|
||||
|
||||
public IconAttribute(string path)
|
||||
{
|
||||
_path = path;
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
private static Action<Object, Texture2D> s_SetIconForObject = typeof(EditorGUIUtility)
|
||||
.GetMethod("SetIconForObject", BindingFlags.Static | BindingFlags.NonPublic)
|
||||
.CreateDelegate(typeof(Action<Object, Texture2D>), null) as Action<Object, Texture2D>;
|
||||
|
||||
[InitializeOnLoadMethod]
|
||||
private static void InitializeOnLoadMethod()
|
||||
{
|
||||
if (Misc.isBatchOrBuilding) return;
|
||||
|
||||
var types = TypeCache.GetTypesWithAttribute<IconAttribute>();
|
||||
var scripts = MonoImporter.GetAllRuntimeMonoScripts();
|
||||
foreach (var type in types)
|
||||
{
|
||||
var script = scripts.FirstOrDefault(x => x.GetClass() == type);
|
||||
if (script == null) continue;
|
||||
|
||||
var path = type.GetCustomAttribute<IconAttribute>()?._path;
|
||||
var icon = AssetDatabase.LoadAssetAtPath<Texture2D>(path);
|
||||
if (icon == null) continue;
|
||||
|
||||
s_SetIconForObject(script, icon);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 39ed6a6b0a72e482488bd298b2ae762e
|
||||
guid: 182319ecc315e4858b119764af0fbcb0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
@@ -6,15 +6,58 @@ namespace Coffee.UIParticleInternal
|
||||
/// <summary>
|
||||
/// Object pool.
|
||||
/// </summary>
|
||||
internal class ObjectPool<T>
|
||||
internal class InternalObjectPool<T> where T : class
|
||||
{
|
||||
#if UNITY_2021_1_OR_NEWER
|
||||
private readonly Predicate<T> _onValid; // Delegate for checking if instances are valid
|
||||
private readonly UnityEngine.Pool.ObjectPool<T> _pool;
|
||||
|
||||
public InternalObjectPool(Func<T> onCreate, Predicate<T> onValid, Action<T> onReturn)
|
||||
{
|
||||
_pool = new UnityEngine.Pool.ObjectPool<T>(onCreate, null, onReturn);
|
||||
_onValid = onValid;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Rent an instance from the pool.
|
||||
/// When you no longer need it, return it with <see cref="Return" />.
|
||||
/// </summary>
|
||||
public T Rent()
|
||||
{
|
||||
while (0 < _pool.CountInactive)
|
||||
{
|
||||
var instance = _pool.Get();
|
||||
if (_onValid(instance))
|
||||
{
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
|
||||
// If there are no instances in the pool, create a new one.
|
||||
Logging.Log(this, $"A new instance is created (pooled: {_pool.CountInactive}, created: {_pool.CountAll}).");
|
||||
return _pool.Get();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return an instance to the pool and assign null.
|
||||
/// Be sure to return the instance obtained with <see cref="Rent" /> with this method.
|
||||
/// </summary>
|
||||
public void Return(ref T instance)
|
||||
{
|
||||
if (instance == null) return; // Ignore if already pooled or null.
|
||||
|
||||
_pool.Release(instance);
|
||||
Logging.Log(this, $"An instance is released (pooled: {_pool.CountInactive}, created: {_pool.CountAll}).");
|
||||
instance = default; // Set the reference to null.
|
||||
}
|
||||
#else
|
||||
private readonly Func<T> _onCreate; // Delegate for creating instances
|
||||
private readonly Action<T> _onReturn; // Delegate for returning instances to the pool
|
||||
private readonly Predicate<T> _onValid; // Delegate for checking if instances are valid
|
||||
private readonly Stack<T> _pool = new Stack<T>(32); // Object pool
|
||||
private int _count; // Total count of created instances
|
||||
|
||||
public ObjectPool(Func<T> onCreate, Predicate<T> onValid, Action<T> onReturn)
|
||||
public InternalObjectPool(Func<T> onCreate, Predicate<T> onValid, Action<T> onReturn)
|
||||
{
|
||||
_onCreate = onCreate;
|
||||
_onValid = onValid;
|
||||
@@ -54,15 +97,40 @@ namespace Coffee.UIParticleInternal
|
||||
Logging.Log(this, $"An instance is released (pooled: {_pool.Count}, created: {_count}).");
|
||||
instance = default; // Set the reference to null.
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Object pool for <see cref="List{T}" />.
|
||||
/// </summary>
|
||||
internal static class ListPool<T>
|
||||
internal static class InternalListPool<T>
|
||||
{
|
||||
private static readonly ObjectPool<List<T>> s_ListPool =
|
||||
new ObjectPool<List<T>>(() => new List<T>(), _ => true, x => x.Clear());
|
||||
#if UNITY_2021_1_OR_NEWER
|
||||
/// <summary>
|
||||
/// Rent an instance from the pool.
|
||||
/// When you no longer need it, return it with <see cref="Return" />.
|
||||
/// </summary>
|
||||
public static List<T> Rent()
|
||||
{
|
||||
return UnityEngine.Pool.ListPool<T>.Get();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return an instance to the pool and assign null.
|
||||
/// Be sure to return the instance obtained with <see cref="Rent" /> with this method.
|
||||
/// </summary>
|
||||
public static void Return(ref List<T> toRelease)
|
||||
{
|
||||
if (toRelease != null)
|
||||
{
|
||||
UnityEngine.Pool.ListPool<T>.Release(toRelease);
|
||||
}
|
||||
|
||||
toRelease = null;
|
||||
}
|
||||
#else
|
||||
private static readonly InternalObjectPool<List<T>> s_ListPool =
|
||||
new InternalObjectPool<List<T>>(() => new List<T>(), _ => true, x => x.Clear());
|
||||
|
||||
/// <summary>
|
||||
/// Rent an instance from the pool.
|
||||
@@ -81,5 +149,6 @@ namespace Coffee.UIParticleInternal
|
||||
{
|
||||
s_ListPool.Return(ref toRelease);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,10 +8,11 @@ namespace Coffee.UIParticleInternal
|
||||
{
|
||||
internal class ObjectRepository<T> where T : Object
|
||||
{
|
||||
private readonly List<Entry> _cache = new List<Entry>();
|
||||
private readonly Dictionary<Hash128, Entry> _cache = new Dictionary<Hash128, Entry>(8);
|
||||
private readonly Dictionary<int, Hash128> _objectKey = new Dictionary<int, Hash128>(8);
|
||||
private readonly string _name;
|
||||
private readonly Action<T> _onRelease;
|
||||
private readonly Stack<Entry> _pool = new Stack<Entry>();
|
||||
private readonly Stack<Entry> _pool = new Stack<Entry>(8);
|
||||
|
||||
public ObjectRepository(Action<T> onRelease = null)
|
||||
{
|
||||
@@ -36,40 +37,33 @@ namespace Coffee.UIParticleInternal
|
||||
{
|
||||
_onRelease = onRelease;
|
||||
}
|
||||
|
||||
for (var i = 0; i < 8; i++)
|
||||
{
|
||||
_pool.Push(new Entry());
|
||||
}
|
||||
}
|
||||
|
||||
public int count => _cache.Count;
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
for (var i = 0; i < _cache.Count; i++)
|
||||
foreach (var kv in _cache)
|
||||
{
|
||||
var entry = _cache[i];
|
||||
var entry = kv.Value;
|
||||
if (entry == null) continue;
|
||||
|
||||
entry.Release(_onRelease);
|
||||
_pool.Push(entry);
|
||||
}
|
||||
|
||||
_cache.Clear();
|
||||
_objectKey.Clear();
|
||||
}
|
||||
|
||||
public bool Valid(Hash128 hash, T obj)
|
||||
{
|
||||
// Find existing entry.
|
||||
Profiler.BeginSample("(COF)[ObjectRepository] Valid > Find existing entry");
|
||||
for (var i = 0; i < _cache.Count; ++i)
|
||||
{
|
||||
var entry = _cache[i];
|
||||
if (entry.hash != hash) continue;
|
||||
Profiler.EndSample();
|
||||
|
||||
// Existing entry found.
|
||||
return entry.storedObject == obj;
|
||||
}
|
||||
|
||||
Profiler.EndSample();
|
||||
|
||||
return false;
|
||||
return _cache.TryGetValue(hash, out var entry) && entry.storedObject == obj;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -77,41 +71,8 @@ namespace Coffee.UIParticleInternal
|
||||
/// </summary>
|
||||
public void Get(Hash128 hash, ref T obj, Func<T> onCreate)
|
||||
{
|
||||
// Find existing entry.
|
||||
Profiler.BeginSample("(COF)[ObjectRepository] Get > Find existing entry");
|
||||
for (var i = 0; i < _cache.Count; ++i)
|
||||
{
|
||||
var entry = _cache[i];
|
||||
if (entry.hash != hash) continue;
|
||||
|
||||
// Existing entry found.
|
||||
if (entry.storedObject != obj)
|
||||
{
|
||||
// if the object is different, release the old one.
|
||||
Release(ref obj);
|
||||
++entry.reference;
|
||||
obj = entry.storedObject;
|
||||
Logging.Log(_name, $"Get(#{count}): {entry}");
|
||||
}
|
||||
|
||||
Profiler.EndSample();
|
||||
return;
|
||||
}
|
||||
|
||||
Profiler.EndSample();
|
||||
|
||||
// Create new entry.
|
||||
Profiler.BeginSample("(COF)[ObjectRepository] Get > Create new entry");
|
||||
var newEntry = 0 < _pool.Count ? _pool.Pop() : new Entry();
|
||||
newEntry.storedObject = onCreate();
|
||||
newEntry.hash = hash;
|
||||
newEntry.reference = 1;
|
||||
_cache.Add(newEntry);
|
||||
Logging.Log(_name, $"Get(#{count}): {newEntry}");
|
||||
|
||||
Release(ref obj);
|
||||
obj = newEntry.storedObject;
|
||||
Profiler.EndSample();
|
||||
if (GetFromCache(hash, ref obj)) return;
|
||||
Add(hash, ref obj, onCreate());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -119,40 +80,60 @@ namespace Coffee.UIParticleInternal
|
||||
/// </summary>
|
||||
public void Get<TS>(Hash128 hash, ref T obj, Func<TS, T> onCreate, TS source)
|
||||
{
|
||||
// Find existing entry.
|
||||
Profiler.BeginSample("(COF)[ObjectRepository] Get > Find existing entry");
|
||||
for (var i = 0; i < _cache.Count; ++i)
|
||||
{
|
||||
var entry = _cache[i];
|
||||
if (entry.hash != hash) continue;
|
||||
if (GetFromCache(hash, ref obj)) return;
|
||||
Add(hash, ref obj, onCreate(source));
|
||||
}
|
||||
|
||||
private bool GetFromCache(Hash128 hash, ref T obj)
|
||||
{
|
||||
// Find existing entry.
|
||||
Profiler.BeginSample("(COF)[ObjectRepository] GetFromCache");
|
||||
if (_cache.TryGetValue(hash, out var entry))
|
||||
{
|
||||
if (entry.storedObject == null)
|
||||
{
|
||||
Release(ref entry.storedObject);
|
||||
Profiler.EndSample();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Existing entry found.
|
||||
if (entry.storedObject != obj)
|
||||
{
|
||||
// if the object is different, release the old one.
|
||||
Release(ref obj);
|
||||
++entry.reference;
|
||||
obj = entry.storedObject;
|
||||
Logging.Log(_name, $"Get(#{count}): {entry}");
|
||||
Logging.Log(_name, $"Get(total#{count}): {entry}");
|
||||
}
|
||||
|
||||
Profiler.EndSample();
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
Profiler.EndSample();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create new entry.
|
||||
Profiler.BeginSample("(COF)[ObjectRepository] Get > Create new entry");
|
||||
private void Add(Hash128 hash, ref T obj, T newObject)
|
||||
{
|
||||
if (newObject == null)
|
||||
{
|
||||
Release(ref obj);
|
||||
obj = newObject;
|
||||
return;
|
||||
}
|
||||
|
||||
// Create and add a new entry.
|
||||
Profiler.BeginSample("(COF)[ObjectRepository] Add");
|
||||
var newEntry = 0 < _pool.Count ? _pool.Pop() : new Entry();
|
||||
newEntry.storedObject = onCreate(source);
|
||||
newEntry.storedObject = newObject;
|
||||
newEntry.hash = hash;
|
||||
newEntry.reference = 1;
|
||||
_cache.Add(newEntry);
|
||||
Logging.Log(_name, $"Get(#{count}): {newEntry}");
|
||||
|
||||
_cache[hash] = newEntry;
|
||||
_objectKey[newObject.GetInstanceID()] = hash;
|
||||
Logging.Log(_name, $"<color=#03c700>Add</color>(total#{count}): {newEntry}");
|
||||
Release(ref obj);
|
||||
obj = newEntry.storedObject;
|
||||
obj = newObject;
|
||||
Profiler.EndSample();
|
||||
}
|
||||
|
||||
@@ -163,35 +144,45 @@ namespace Coffee.UIParticleInternal
|
||||
{
|
||||
if (ReferenceEquals(obj, null)) return;
|
||||
|
||||
// Find and release the entry.
|
||||
Profiler.BeginSample("(COF)[ObjectRepository] Release");
|
||||
for (var i = 0; i < _cache.Count; i++)
|
||||
var id = obj.GetInstanceID();
|
||||
if (_objectKey.TryGetValue(id, out var hash)
|
||||
&& _cache.TryGetValue(hash, out var entry))
|
||||
{
|
||||
var entry = _cache[i];
|
||||
|
||||
if (entry.storedObject != obj)
|
||||
entry.reference--;
|
||||
if (entry.reference <= 0 || entry.storedObject == null)
|
||||
{
|
||||
continue;
|
||||
Remove(entry);
|
||||
}
|
||||
|
||||
if (--entry.reference <= 0)
|
||||
else
|
||||
{
|
||||
Profiler.BeginSample("(COF)[ObjectRepository] Release > RemoveAt");
|
||||
_cache.RemoveAtFast(i);
|
||||
Logging.Log(_name, $"Release(#{_cache.Count}): {entry}");
|
||||
entry.Release(_onRelease);
|
||||
_pool.Push(entry);
|
||||
Profiler.EndSample();
|
||||
break;
|
||||
Logging.Log(_name, $"Release(total#{_cache.Count}): {entry}");
|
||||
}
|
||||
|
||||
Logging.Log(_name, $"Release(#{count}): {entry}");
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
Logging.Log(_name, $"Release(total#{_cache.Count}): <color=red>Already released: {obj}</color>");
|
||||
}
|
||||
|
||||
obj = null;
|
||||
Profiler.EndSample();
|
||||
}
|
||||
|
||||
private void Remove(Entry entry)
|
||||
{
|
||||
if (ReferenceEquals(entry, null)) return;
|
||||
|
||||
Profiler.BeginSample("(COF)[ObjectRepository] Remove");
|
||||
_cache.Remove(entry.hash);
|
||||
_objectKey.Remove(entry.storedObject.GetInstanceID());
|
||||
_pool.Push(entry);
|
||||
entry.reference = 0;
|
||||
Logging.Log(_name, $"<color=#f29e03>Remove</color>(total#{_cache.Count}): {entry}");
|
||||
entry.Release(_onRelease);
|
||||
Profiler.EndSample();
|
||||
}
|
||||
|
||||
private class Entry
|
||||
{
|
||||
public Hash128 hash;
|
||||
@@ -201,7 +192,7 @@ namespace Coffee.UIParticleInternal
|
||||
public void Release(Action<T> onRelease)
|
||||
{
|
||||
reference = 0;
|
||||
if (storedObject)
|
||||
if (storedObject != null)
|
||||
{
|
||||
onRelease?.Invoke(storedObject);
|
||||
}
|
||||
@@ -211,7 +202,7 @@ namespace Coffee.UIParticleInternal
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"h{(uint)hash.GetHashCode()} (#{reference}), {storedObject}";
|
||||
return $"h{(uint)hash.GetHashCode()} (refs#{reference}), {storedObject}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,8 @@ namespace Coffee.UIParticleInternal
|
||||
private static readonly FastAction s_AfterCanvasRebuildAction = new FastAction();
|
||||
private static readonly FastAction s_LateAfterCanvasRebuildAction = new FastAction();
|
||||
private static readonly FastAction s_BeforeCanvasRebuildAction = new FastAction();
|
||||
private static readonly FastAction s_OnScreenSizeChangedAction = new FastAction();
|
||||
private static Vector2Int s_LastScreenSize;
|
||||
|
||||
static UIExtraCallbacks()
|
||||
{
|
||||
@@ -48,6 +50,15 @@ namespace Coffee.UIParticleInternal
|
||||
remove => s_AfterCanvasRebuildAction.Remove(value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Event that occurs when the screen size changes.
|
||||
/// </summary>
|
||||
public static event Action onScreenSizeChanged
|
||||
{
|
||||
add => s_OnScreenSizeChangedAction.Add(value);
|
||||
remove => s_OnScreenSizeChangedAction.Remove(value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the UIExtraCallbacks to ensure proper event handling.
|
||||
/// </summary>
|
||||
@@ -64,11 +75,12 @@ namespace Coffee.UIParticleInternal
|
||||
|
||||
#if UNITY_EDITOR
|
||||
[InitializeOnLoadMethod]
|
||||
#else
|
||||
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
|
||||
#endif
|
||||
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
|
||||
private static void InitializeOnLoad()
|
||||
{
|
||||
Canvas.willRenderCanvases -= OnAfterCanvasRebuild;
|
||||
s_IsInitializedAfterCanvasRebuild = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -76,6 +88,17 @@ namespace Coffee.UIParticleInternal
|
||||
/// </summary>
|
||||
private static void OnBeforeCanvasRebuild()
|
||||
{
|
||||
var screenSize = new Vector2Int(Screen.width, Screen.height);
|
||||
if (s_LastScreenSize != screenSize)
|
||||
{
|
||||
if (s_LastScreenSize != default)
|
||||
{
|
||||
s_OnScreenSizeChangedAction.Invoke();
|
||||
}
|
||||
|
||||
s_LastScreenSize = screenSize;
|
||||
}
|
||||
|
||||
s_BeforeCanvasRebuildAction.Invoke();
|
||||
InitializeAfterCanvasRebuild();
|
||||
}
|
||||
|
||||
@@ -3,22 +3,26 @@ using System.Collections.Generic;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Coffee.UIParticleInternal;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.Rendering;
|
||||
using UnityEngine.Serialization;
|
||||
using UnityEngine.UI;
|
||||
using Random = UnityEngine.Random;
|
||||
|
||||
[assembly: InternalsVisibleTo("Coffee.UIParticle.Editor")]
|
||||
[assembly: InternalsVisibleTo("Coffee.UIParticle.Editor.Tests")]
|
||||
[assembly: InternalsVisibleTo("Coffee.UIParticle.PerformanceDemo")]
|
||||
[assembly: InternalsVisibleTo("Coffee.UIParticle.Demo")]
|
||||
|
||||
namespace Coffee.UIExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Render maskable and sortable particle effect ,without Camera, RenderTexture or Canvas.
|
||||
/// </summary>
|
||||
[Icon("Packages/com.coffee.ui-particle/Editor/UIParticleIcon.png")]
|
||||
[ExecuteAlways]
|
||||
[RequireComponent(typeof(RectTransform))]
|
||||
[RequireComponent(typeof(CanvasRenderer))]
|
||||
public class UIParticle : UIBehaviour, ISerializationCallbackReceiver
|
||||
public class UIParticle : MaskableGraphic, ISerializationCallbackReceiver
|
||||
{
|
||||
public enum AutoScalingMode
|
||||
{
|
||||
@@ -58,12 +62,12 @@ namespace Coffee.UIExtensions
|
||||
[Obsolete]
|
||||
internal bool m_AbsoluteMode;
|
||||
|
||||
[Tooltip("Particle effect scale")]
|
||||
[Tooltip("Scale the rendering particles. When the `3D` toggle is enabled, 3D scale (x, y, z) is supported.")]
|
||||
[SerializeField]
|
||||
private Vector3 m_Scale3D = new Vector3(1, 1, 1);
|
||||
private Vector3 m_Scale3D = new Vector3(10, 10, 10);
|
||||
|
||||
[Tooltip("Animatable material properties.\n" +
|
||||
"If you want to change the material properties of the ParticleSystem in Animation, enable it.")]
|
||||
[Tooltip("If you want to update material properties (e.g. _MainTex_ST, _Color) in AnimationClip, " +
|
||||
"use this to mark as animatable.")]
|
||||
[SerializeField]
|
||||
internal AnimatableProperty[] m_AnimatableProperties = new AnimatableProperty[0];
|
||||
|
||||
@@ -71,12 +75,13 @@ namespace Coffee.UIExtensions
|
||||
[SerializeField]
|
||||
private List<ParticleSystem> m_Particles = new List<ParticleSystem>();
|
||||
|
||||
[Tooltip("Mesh sharing.\n" +
|
||||
"None: disable mesh sharing.\n" +
|
||||
"Auto: automatically select Primary/Replica.\n" +
|
||||
"Primary: provides particle simulation results to the same group.\n" +
|
||||
[Tooltip("Particle simulation results are shared within the same group. " +
|
||||
"A large number of the same effects can be displayed with a small load.\n" +
|
||||
"None: Disable mesh sharing.\n" +
|
||||
"Auto: Automatically select Primary/Replica.\n" +
|
||||
"Primary: Provides particle simulation results to the same group.\n" +
|
||||
"Primary Simulator: Primary, but do not render the particle (simulation only).\n" +
|
||||
"Replica: render simulation results provided by the primary.")]
|
||||
"Replica: Render simulation results provided by the primary.")]
|
||||
[SerializeField]
|
||||
private MeshSharing m_MeshSharing = MeshSharing.None;
|
||||
|
||||
@@ -88,67 +93,57 @@ namespace Coffee.UIExtensions
|
||||
[SerializeField]
|
||||
private int m_GroupMaxId;
|
||||
|
||||
[Tooltip("Relative: The particles will be emitted from the scaled position of ParticleSystem.\n" +
|
||||
"Absolute: The particles will be emitted from the world position of ParticleSystem.")]
|
||||
[Tooltip("Emission position mode.\n" +
|
||||
"Relative: The particles will be emitted from the scaled position.\n" +
|
||||
"Absolute: The particles will be emitted from the world position.")]
|
||||
[SerializeField]
|
||||
private PositionMode m_PositionMode = PositionMode.Relative;
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("Prevent the root-Canvas scale from affecting the hierarchy-scaled ParticleSystem.")]
|
||||
[Obsolete]
|
||||
internal bool m_AutoScaling;
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("Transform: Transform.lossyScale (=world scale) will be set to (1, 1, 1)." +
|
||||
"UIParticle: UIParticle.scale will be adjusted.")]
|
||||
[Tooltip(
|
||||
"How to automatically adjust when the Canvas scale is changed by the screen size or reference resolution.\n" +
|
||||
"None: Do nothing.\n" +
|
||||
"Transform: Transform.lossyScale (=world scale) will be set to (1, 1, 1).\n" +
|
||||
"UIParticle: UIParticle.scale will be adjusted.")]
|
||||
private AutoScalingMode m_AutoScalingMode = AutoScalingMode.Transform;
|
||||
|
||||
[SerializeField]
|
||||
private bool m_Maskable = true;
|
||||
[Tooltip("Use a custom view.\n" +
|
||||
"Use this if the particles are not displayed correctly due to min/max particle size.")]
|
||||
private bool m_UseCustomView;
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("Custom view size.\n" +
|
||||
"Change the bake view size.")]
|
||||
private float m_CustomViewSize = 10;
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("Time scale multiplier.")]
|
||||
private float m_TimeScaleMultiplier = 1;
|
||||
|
||||
private readonly List<UIParticleRenderer> _renderers = new List<UIParticleRenderer>();
|
||||
private Canvas _canvas;
|
||||
private int _groupId;
|
||||
private Camera _bakeCamera;
|
||||
private DrivenRectTransformTracker _tracker;
|
||||
private Vector3 _storedScale;
|
||||
private int _groupId;
|
||||
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;
|
||||
}
|
||||
}
|
||||
private Vector3 _storedScale;
|
||||
private DrivenRectTransformTracker _tracker;
|
||||
|
||||
/// <summary>
|
||||
/// Does this graphic allow masking.
|
||||
/// Should this graphic be considered a target for ray-casting?
|
||||
/// </summary>
|
||||
public bool maskable
|
||||
public override bool raycastTarget
|
||||
{
|
||||
get => m_Maskable;
|
||||
set
|
||||
{
|
||||
if (value == m_Maskable) return;
|
||||
m_Maskable = value;
|
||||
UpdateRendererMaterial();
|
||||
}
|
||||
get => false;
|
||||
set { }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Mesh sharing.
|
||||
/// Particle simulation results are shared within the same group.
|
||||
/// A large number of the same effects can be displayed with a small load.
|
||||
/// None: disable mesh sharing.
|
||||
/// Auto: automatically select Primary/Replica.
|
||||
/// Primary: provides particle simulation results to the same group.
|
||||
@@ -191,9 +186,9 @@ namespace Coffee.UIExtensions
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Particle position mode.
|
||||
/// Relative: The particles will be emitted from the scaled position of the ParticleSystem.
|
||||
/// Absolute: The particles will be emitted from the world position of the ParticleSystem.
|
||||
/// Emission position mode.
|
||||
/// Relative: The particles will be emitted from the scaled position.
|
||||
/// Absolute: The particles will be emitted from the world position.
|
||||
/// </summary>
|
||||
public PositionMode positionMode
|
||||
{
|
||||
@@ -206,6 +201,7 @@ namespace Coffee.UIExtensions
|
||||
/// Relative: The particles will be emitted from the scaled position of the ParticleSystem.
|
||||
/// Absolute: The particles will be emitted from the world position of the ParticleSystem.
|
||||
/// </summary>
|
||||
[Obsolete("The absoluteMode is now obsolete. Please use the autoScalingMode instead.", false)]
|
||||
public bool absoluteMode
|
||||
{
|
||||
get => m_PositionMode == PositionMode.Absolute;
|
||||
@@ -223,8 +219,12 @@ namespace Coffee.UIExtensions
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Auto scaling mode.
|
||||
/// How to automatically adjust when the Canvas scale is changed by the screen size or reference resolution.
|
||||
/// <para/>
|
||||
/// None: Do nothing.
|
||||
/// <para/>
|
||||
/// Transform: Transform.lossyScale (=world scale) will be set to (1, 1, 1).
|
||||
/// <para/>
|
||||
/// UIParticle: UIParticle.scale will be adjusted.
|
||||
/// </summary>
|
||||
public AutoScalingMode autoScalingMode
|
||||
@@ -243,6 +243,35 @@ namespace Coffee.UIExtensions
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use a custom view.
|
||||
/// Use this if the particles are not displayed correctly due to min/max particle size.
|
||||
/// </summary>
|
||||
public bool useCustomView
|
||||
{
|
||||
get => m_UseCustomView;
|
||||
set => m_UseCustomView = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Custom view size.
|
||||
/// Change the bake view size.
|
||||
/// </summary>
|
||||
public float customViewSize
|
||||
{
|
||||
get => m_CustomViewSize;
|
||||
set => m_CustomViewSize = Mathf.Max(0.1f, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Time scale multiplier.
|
||||
/// </summary>
|
||||
public float timeScaleMultiplier
|
||||
{
|
||||
get => m_TimeScaleMultiplier;
|
||||
set => m_TimeScaleMultiplier = value;
|
||||
}
|
||||
|
||||
internal bool useMeshSharing => m_MeshSharing != MeshSharing.None;
|
||||
|
||||
internal bool isPrimary =>
|
||||
@@ -288,22 +317,6 @@ namespace Coffee.UIExtensions
|
||||
|
||||
public List<ParticleSystem> particles => m_Particles;
|
||||
|
||||
/// <summary>
|
||||
/// Get all base materials to render.
|
||||
/// </summary>
|
||||
public IEnumerable<Material> materials
|
||||
{
|
||||
get
|
||||
{
|
||||
for (var i = 0; i < _renderers.Count; i++)
|
||||
{
|
||||
var r = _renderers[i];
|
||||
if (!r || !r.material) continue;
|
||||
yield return r.material;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Paused.
|
||||
/// </summary>
|
||||
@@ -311,15 +324,15 @@ namespace Coffee.UIExtensions
|
||||
|
||||
public Vector3 parentScale { get; private set; }
|
||||
|
||||
private Vector3 canvasScale { get; set; }
|
||||
public Vector3 canvasScale { get; private set; }
|
||||
|
||||
protected override void OnEnable()
|
||||
{
|
||||
_isScaleStored = false;
|
||||
ResetGroupId();
|
||||
UIParticleUpdater.Register(this);
|
||||
RegisterDirtyMaterialCallback(UpdateRendererMaterial);
|
||||
|
||||
//
|
||||
if (0 < particles.Count)
|
||||
{
|
||||
RefreshParticles(particles);
|
||||
@@ -329,7 +342,7 @@ namespace Coffee.UIExtensions
|
||||
RefreshParticles();
|
||||
}
|
||||
|
||||
UpdateRendererMaterial();
|
||||
base.OnEnable();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -346,15 +359,9 @@ namespace Coffee.UIExtensions
|
||||
_isScaleStored = false;
|
||||
UIParticleUpdater.Unregister(this);
|
||||
_renderers.ForEach(r => r.Reset());
|
||||
_canvas = null;
|
||||
}
|
||||
UnregisterDirtyMaterialCallback(UpdateRendererMaterial);
|
||||
|
||||
/// <summary>
|
||||
/// Called when the state of the parent Canvas is changed.
|
||||
/// </summary>
|
||||
protected override void OnCanvasHierarchyChanged()
|
||||
{
|
||||
_canvas = null;
|
||||
base.OnDisable();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -364,14 +371,6 @@ namespace Coffee.UIExtensions
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function is called when a direct or indirect parent of the transform of the GameObject has changed.
|
||||
/// </summary>
|
||||
protected override void OnTransformParentChanged()
|
||||
{
|
||||
_canvas = null;
|
||||
}
|
||||
|
||||
void ISerializationCallbackReceiver.OnBeforeSerialize()
|
||||
{
|
||||
}
|
||||
@@ -462,6 +461,21 @@ namespace Coffee.UIExtensions
|
||||
isPaused = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get all base materials to render.
|
||||
/// </summary>
|
||||
public void GetMaterials(List<Material> result)
|
||||
{
|
||||
if (result == null) return;
|
||||
|
||||
for (var i = 0; i < _renderers.Count; i++)
|
||||
{
|
||||
var r = _renderers[i];
|
||||
if (r == null || r.material == null) continue;
|
||||
result.Add(r.material);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Refresh UIParticle using the ParticleSystem instance.
|
||||
/// </summary>
|
||||
@@ -475,12 +489,15 @@ namespace Coffee.UIExtensions
|
||||
/// </summary>
|
||||
public void SetParticleSystemInstance(GameObject instance, bool destroyOldParticles)
|
||||
{
|
||||
if (!instance) return;
|
||||
if (instance == null) return;
|
||||
|
||||
var childCount = transform.childCount;
|
||||
for (var i = 0; i < childCount; i++)
|
||||
{
|
||||
var go = transform.GetChild(i).gameObject;
|
||||
if (go.TryGetComponent<Camera>(out var cam) && cam == _bakeCamera) continue;
|
||||
if (go.TryGetComponent<UIParticleRenderer>(out var _)) continue;
|
||||
|
||||
go.SetActive(false);
|
||||
if (destroyOldParticles)
|
||||
{
|
||||
@@ -501,7 +518,7 @@ namespace Coffee.UIExtensions
|
||||
/// </summary>
|
||||
public void SetParticleSystemPrefab(GameObject prefab)
|
||||
{
|
||||
if (!prefab) return;
|
||||
if (prefab == null) return;
|
||||
|
||||
SetParticleSystemInstance(Instantiate(prefab.gameObject), true);
|
||||
}
|
||||
@@ -521,12 +538,14 @@ namespace Coffee.UIExtensions
|
||||
/// </summary>
|
||||
private void RefreshParticles(GameObject root)
|
||||
{
|
||||
if (!root) return;
|
||||
if (root == null) return;
|
||||
root.GetComponentsInChildren(true, particles);
|
||||
for (var i = particles.Count - 1; 0 <= i; i--)
|
||||
{
|
||||
var ps = particles[i];
|
||||
if (!ps || ps.GetComponentInParent<UIParticle>(true) != this)
|
||||
if (!ps
|
||||
|| ps.gameObject.CompareTag("EditorOnly") // Ignore "EditorOnly" tagged ParticleSystems.
|
||||
|| ps.GetComponentInParent<UIParticle>(true) != this) // Ignore ParticleSystems that are not under this UIParticle.
|
||||
{
|
||||
particles.RemoveAt(i);
|
||||
}
|
||||
@@ -574,13 +593,15 @@ namespace Coffee.UIExtensions
|
||||
for (var i = 0; i < particleSystems.Count; i++)
|
||||
{
|
||||
var ps = particleSystems[i];
|
||||
if (!ps) continue;
|
||||
GetRenderer(j++).Set(this, ps, false);
|
||||
if (ps == null) continue;
|
||||
|
||||
var mainEmitter = ps.GetMainEmitter(particleSystems);
|
||||
GetRenderer(j++).Set(this, ps, false, mainEmitter);
|
||||
|
||||
// If the trail is enabled, set it additionally.
|
||||
if (ps.trails.enabled)
|
||||
{
|
||||
GetRenderer(j++).Set(this, ps, true);
|
||||
GetRenderer(j++).Set(this, ps, true, mainEmitter);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -602,8 +623,12 @@ namespace Coffee.UIExtensions
|
||||
}
|
||||
|
||||
var currentScale = transform.localScale;
|
||||
_storedScale = currentScale;
|
||||
_isScaleStored = true;
|
||||
if (!_isScaleStored)
|
||||
{
|
||||
_storedScale = currentScale.IsVisible() ? currentScale : Vector3.one;
|
||||
_isScaleStored = true;
|
||||
}
|
||||
|
||||
_tracker.Add(this, rectTransform, DrivenTransformProperties.Scale);
|
||||
var newScale = parentScale.Inverse();
|
||||
if (currentScale != newScale)
|
||||
@@ -619,7 +644,7 @@ namespace Coffee.UIExtensions
|
||||
for (var i = 0; i < _renderers.Count; i++)
|
||||
{
|
||||
var r = _renderers[i];
|
||||
if (r) continue;
|
||||
if (r != null) continue;
|
||||
|
||||
RefreshParticles(particles);
|
||||
break;
|
||||
@@ -629,7 +654,7 @@ namespace Coffee.UIExtensions
|
||||
for (var i = 0; i < _renderers.Count; i++)
|
||||
{
|
||||
var r = _renderers[i];
|
||||
if (!r) continue;
|
||||
if (r == null) continue;
|
||||
|
||||
r.UpdateMesh(bakeCamera);
|
||||
}
|
||||
@@ -642,12 +667,23 @@ namespace Coffee.UIExtensions
|
||||
: Random.Range(m_GroupId, m_GroupMaxId + 1);
|
||||
}
|
||||
|
||||
protected override void UpdateMaterial()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Call to update the geometry of the Graphic onto the CanvasRenderer.
|
||||
/// </summary>
|
||||
protected override void UpdateGeometry()
|
||||
{
|
||||
}
|
||||
|
||||
private void UpdateRendererMaterial()
|
||||
{
|
||||
for (var i = 0; i < _renderers.Count; i++)
|
||||
{
|
||||
var r = _renderers[i];
|
||||
if (!r) continue;
|
||||
if (r == null) continue;
|
||||
r.maskable = maskable;
|
||||
r.SetMaterialDirty();
|
||||
}
|
||||
@@ -660,7 +696,7 @@ namespace Coffee.UIExtensions
|
||||
_renderers.Add(UIParticleRenderer.AddRenderer(this, index));
|
||||
}
|
||||
|
||||
if (!_renderers[index])
|
||||
if (_renderers[index] == null)
|
||||
{
|
||||
_renderers[index] = UIParticleRenderer.AddRenderer(this, index);
|
||||
}
|
||||
@@ -670,8 +706,17 @@ namespace Coffee.UIExtensions
|
||||
|
||||
private Camera GetBakeCamera()
|
||||
{
|
||||
if (!canvas) return Camera.main;
|
||||
if (_bakeCamera) return _bakeCamera;
|
||||
if (canvas == null) return Camera.main;
|
||||
if (!useCustomView && canvas.renderMode != RenderMode.ScreenSpaceOverlay && canvas.rootCanvas.worldCamera)
|
||||
{
|
||||
return canvas.rootCanvas.worldCamera;
|
||||
}
|
||||
|
||||
if (_bakeCamera != null)
|
||||
{
|
||||
_bakeCamera.orthographicSize = useCustomView ? customViewSize : 10;
|
||||
return _bakeCamera;
|
||||
}
|
||||
|
||||
// Find existing baking camera.
|
||||
var childCount = transform.childCount;
|
||||
@@ -686,13 +731,9 @@ namespace Coffee.UIExtensions
|
||||
}
|
||||
|
||||
// Create baking camera.
|
||||
if (!_bakeCamera)
|
||||
if (_bakeCamera == null)
|
||||
{
|
||||
var go = new GameObject("[generated] UIParticle BakingCamera")
|
||||
{
|
||||
// hideFlags = HideFlags.HideAndDontSave
|
||||
hideFlags = HideFlags.DontSave
|
||||
};
|
||||
var go = new GameObject("[generated] UIParticle BakingCamera");
|
||||
go.SetActive(false);
|
||||
go.transform.SetParent(transform, false);
|
||||
_bakeCamera = go.AddComponent<Camera>();
|
||||
@@ -700,7 +741,7 @@ namespace Coffee.UIExtensions
|
||||
|
||||
// Setup baking camera.
|
||||
_bakeCamera.enabled = false;
|
||||
_bakeCamera.orthographicSize = 1000;
|
||||
_bakeCamera.orthographicSize = useCustomView ? customViewSize : 10;
|
||||
_bakeCamera.transform.SetPositionAndRotation(new Vector3(0, 0, -1000), Quaternion.identity);
|
||||
_bakeCamera.orthographic = true;
|
||||
_bakeCamera.farClipPlane = 2000f;
|
||||
@@ -711,6 +752,9 @@ namespace Coffee.UIExtensions
|
||||
_bakeCamera.renderingPath = RenderingPath.Forward;
|
||||
_bakeCamera.useOcclusionCulling = false;
|
||||
|
||||
_bakeCamera.gameObject.SetActive(false);
|
||||
_bakeCamera.gameObject.hideFlags = UIParticleProjectSettings.globalHideFlags;
|
||||
|
||||
return _bakeCamera;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 2800000, guid: 5f0675613942149309588d556e33d990, type: 3}
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Coffee.UIParticleInternal;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
@@ -6,7 +7,7 @@ using UnityEngine.Events;
|
||||
namespace Coffee.UIExtensions
|
||||
{
|
||||
[ExecuteAlways]
|
||||
public class UIParticleAttractor : MonoBehaviour
|
||||
public class UIParticleAttractor : MonoBehaviour, ISerializationCallbackReceiver
|
||||
{
|
||||
public enum Movement
|
||||
{
|
||||
@@ -22,8 +23,12 @@ namespace Coffee.UIExtensions
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
private ParticleSystem m_ParticleSystem;
|
||||
|
||||
[SerializeField]
|
||||
private List<ParticleSystem> m_ParticleSystems = new List<ParticleSystem>();
|
||||
|
||||
[Range(0.1f, 10f)]
|
||||
[SerializeField]
|
||||
private float m_DestinationRadius = 1;
|
||||
@@ -45,7 +50,7 @@ namespace Coffee.UIExtensions
|
||||
[SerializeField]
|
||||
private UnityEvent m_OnAttracted;
|
||||
|
||||
private UIParticle _uiParticle;
|
||||
private List<UIParticle> _uiParticles = new List<UIParticle>();
|
||||
|
||||
public float destinationRadius
|
||||
{
|
||||
@@ -84,25 +89,46 @@ namespace Coffee.UIExtensions
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The target ParticleSystem to attract.
|
||||
/// The target ParticleSystems to attract. Use <see cref="AddParticleSystem"/> and
|
||||
/// <see cref="RemoveParticleSystem"/> to modify the list.
|
||||
/// </summary>
|
||||
#if UNITY_EDITOR
|
||||
public new ParticleSystem particleSystem
|
||||
#else
|
||||
public ParticleSystem particleSystem
|
||||
#endif
|
||||
public IReadOnlyList<ParticleSystem> particleSystems => m_ParticleSystems;
|
||||
|
||||
public void AddParticleSystem(ParticleSystem ps)
|
||||
{
|
||||
get => m_ParticleSystem;
|
||||
set
|
||||
if (m_ParticleSystems == null)
|
||||
{
|
||||
m_ParticleSystem = value;
|
||||
ApplyParticleSystem();
|
||||
m_ParticleSystems = new List<ParticleSystem>();
|
||||
}
|
||||
|
||||
var i = m_ParticleSystems.IndexOf(ps);
|
||||
if (0 <= i) return; // Already added: skip
|
||||
|
||||
m_ParticleSystems.Add(ps);
|
||||
_uiParticles.Clear();
|
||||
}
|
||||
|
||||
public void RemoveParticleSystem(ParticleSystem ps)
|
||||
{
|
||||
if (m_ParticleSystems == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var i = m_ParticleSystems.IndexOf(ps);
|
||||
if (i < 0) return; // Not found. skip
|
||||
|
||||
m_ParticleSystems.RemoveAt(i);
|
||||
_uiParticles.Clear();
|
||||
}
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
UpgradeIfNeeded();
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
ApplyParticleSystem();
|
||||
UIParticleUpdater.Register(this);
|
||||
}
|
||||
|
||||
@@ -113,85 +139,96 @@ namespace Coffee.UIExtensions
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
_uiParticle = null;
|
||||
m_ParticleSystem = null;
|
||||
_uiParticles = null;
|
||||
m_ParticleSystems = null;
|
||||
}
|
||||
|
||||
internal void Attract()
|
||||
{
|
||||
if (m_ParticleSystem == null) return;
|
||||
// Collect UIParticle if needed (same size as m_ParticleSystems)
|
||||
CollectUIParticlesIfNeeded();
|
||||
|
||||
var count = m_ParticleSystem.particleCount;
|
||||
if (count == 0) return;
|
||||
|
||||
var particles = ParticleSystemExtensions.GetParticleArray(count);
|
||||
m_ParticleSystem.GetParticles(particles, count);
|
||||
|
||||
var dstPos = GetDestinationPosition();
|
||||
for (var i = 0; i < count; i++)
|
||||
for (var particleIndex = 0; particleIndex < m_ParticleSystems.Count; particleIndex++)
|
||||
{
|
||||
// Attracted
|
||||
var p = particles[i];
|
||||
if (0f < p.remainingLifetime && Vector3.Distance(p.position, dstPos) < m_DestinationRadius)
|
||||
{
|
||||
p.remainingLifetime = 0f;
|
||||
particles[i] = p;
|
||||
var particleSystem = m_ParticleSystems[particleIndex];
|
||||
|
||||
if (m_OnAttracted != null)
|
||||
// Skip: The ParticleSystem is not active
|
||||
if (particleSystem == null || !particleSystem.gameObject.activeInHierarchy) continue;
|
||||
|
||||
// Skip: No active particles
|
||||
var count = particleSystem.particleCount;
|
||||
if (count == 0) continue;
|
||||
|
||||
var particles = ParticleSystemExtensions.GetParticleArray(count);
|
||||
particleSystem.GetParticles(particles, count);
|
||||
|
||||
var uiParticle = _uiParticles[particleIndex];
|
||||
var dstPos = GetDestinationPosition(uiParticle, particleSystem);
|
||||
for (var i = 0; i < count; i++)
|
||||
{
|
||||
// Attracted
|
||||
var p = particles[i];
|
||||
if (0f < p.remainingLifetime && Vector3.Distance(p.position, dstPos) < m_DestinationRadius)
|
||||
{
|
||||
try
|
||||
p.remainingLifetime = 0f;
|
||||
particles[i] = p;
|
||||
|
||||
if (m_OnAttracted != null)
|
||||
{
|
||||
m_OnAttracted.Invoke();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogException(e);
|
||||
try
|
||||
{
|
||||
m_OnAttracted.Invoke();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogException(e);
|
||||
}
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
continue;
|
||||
// Calc attracting time
|
||||
var delayTime = p.startLifetime * m_DelayRate;
|
||||
var duration = p.startLifetime - delayTime;
|
||||
var time = Mathf.Max(0, p.startLifetime - p.remainingLifetime - delayTime);
|
||||
|
||||
// Delay
|
||||
if (time <= 0) continue;
|
||||
|
||||
// Attract
|
||||
p.position = GetAttractedPosition(p.position, dstPos, duration, time);
|
||||
p.velocity *= 0.5f;
|
||||
particles[i] = p;
|
||||
}
|
||||
|
||||
// Calc attracting time
|
||||
var delayTime = p.startLifetime * m_DelayRate;
|
||||
var duration = p.startLifetime - delayTime;
|
||||
var time = Mathf.Max(0, p.startLifetime - p.remainingLifetime - delayTime);
|
||||
|
||||
// Delay
|
||||
if (time <= 0) continue;
|
||||
|
||||
// Attract
|
||||
p.position = GetAttractedPosition(p.position, dstPos, duration, time);
|
||||
p.velocity *= 0.5f;
|
||||
particles[i] = p;
|
||||
particleSystem.SetParticles(particles, count);
|
||||
}
|
||||
|
||||
m_ParticleSystem.SetParticles(particles, count);
|
||||
}
|
||||
|
||||
private Vector3 GetDestinationPosition()
|
||||
private Vector3 GetDestinationPosition(UIParticle uiParticle, ParticleSystem particleSystem)
|
||||
{
|
||||
var isUI = _uiParticle && _uiParticle.enabled;
|
||||
var psPos = m_ParticleSystem.transform.position;
|
||||
var isUI = uiParticle != null && uiParticle.enabled;
|
||||
var psPos = particleSystem.transform.position;
|
||||
var attractorPos = transform.position;
|
||||
var dstPos = attractorPos;
|
||||
var isLocalSpace = m_ParticleSystem.IsLocalSpace();
|
||||
var isLocalSpace = particleSystem.IsLocalSpace();
|
||||
|
||||
if (isLocalSpace)
|
||||
{
|
||||
dstPos = m_ParticleSystem.transform.InverseTransformPoint(dstPos);
|
||||
dstPos = particleSystem.transform.InverseTransformPoint(dstPos);
|
||||
}
|
||||
|
||||
if (isUI)
|
||||
{
|
||||
var inverseScale = _uiParticle.parentScale.Inverse();
|
||||
var scale3d = _uiParticle.scale3DForCalc;
|
||||
var inverseScale = uiParticle.parentScale.Inverse();
|
||||
var scale3d = uiParticle.scale3DForCalc;
|
||||
dstPos = dstPos.GetScaled(inverseScale, scale3d.Inverse());
|
||||
|
||||
// Relative mode
|
||||
if (_uiParticle.positionMode == UIParticle.PositionMode.Relative)
|
||||
if (uiParticle.positionMode == UIParticle.PositionMode.Relative)
|
||||
{
|
||||
var diff = _uiParticle.transform.position - psPos;
|
||||
var diff = uiParticle.transform.position - psPos;
|
||||
diff.Scale(scale3d - inverseScale);
|
||||
diff.Scale(scale3d.Inverse());
|
||||
dstPos += diff;
|
||||
@@ -237,25 +274,59 @@ namespace Coffee.UIExtensions
|
||||
return Vector3.MoveTowards(current, target, speed);
|
||||
}
|
||||
|
||||
private void ApplyParticleSystem()
|
||||
private void CollectUIParticlesIfNeeded()
|
||||
{
|
||||
_uiParticle = null;
|
||||
if (m_ParticleSystem == null)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (Application.isPlaying)
|
||||
#endif
|
||||
{
|
||||
Debug.LogError("No particle system attached to particle attractor script", this);
|
||||
}
|
||||
if (m_ParticleSystems.Count == 0 || _uiParticles.Count != 0) return;
|
||||
|
||||
return;
|
||||
// Expand capacity
|
||||
if (_uiParticles.Capacity < m_ParticleSystems.Capacity)
|
||||
{
|
||||
_uiParticles.Capacity = m_ParticleSystems.Capacity;
|
||||
}
|
||||
|
||||
_uiParticle = m_ParticleSystem.GetComponentInParent<UIParticle>(true);
|
||||
if (_uiParticle && !_uiParticle.particles.Contains(m_ParticleSystem))
|
||||
// Find UIParticle that controls the ParticleSystem
|
||||
for (var i = 0; i < m_ParticleSystems.Count; i++)
|
||||
{
|
||||
_uiParticle = null;
|
||||
var ps = m_ParticleSystems[i];
|
||||
if (ps == null)
|
||||
{
|
||||
_uiParticles.Add(null);
|
||||
continue;
|
||||
}
|
||||
|
||||
var uiParticle = ps.GetComponentInParent<UIParticle>(true);
|
||||
_uiParticles.Add(uiParticle.particles.Contains(ps) ? uiParticle : null);
|
||||
}
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
private void OnValidate()
|
||||
{
|
||||
_uiParticles.Clear();
|
||||
}
|
||||
#endif
|
||||
|
||||
void ISerializationCallbackReceiver.OnBeforeSerialize()
|
||||
{
|
||||
UpgradeIfNeeded();
|
||||
}
|
||||
|
||||
void ISerializationCallbackReceiver.OnAfterDeserialize()
|
||||
{
|
||||
}
|
||||
|
||||
private void UpgradeIfNeeded()
|
||||
{
|
||||
// Multiple ParticleSystems support: from 'm_ParticleSystem' to 'm_ParticleSystems'
|
||||
if (m_ParticleSystem != null)
|
||||
{
|
||||
if (!m_ParticleSystems.Contains(m_ParticleSystem))
|
||||
{
|
||||
m_ParticleSystems.Add(m_ParticleSystem);
|
||||
}
|
||||
|
||||
m_ParticleSystem = null;
|
||||
Debug.Log($"Upgraded!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
icon: {fileID: 2800000, guid: 5f0675613942149309588d556e33d990, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
||||
@@ -17,6 +17,18 @@ namespace Coffee.UIExtensions
|
||||
set => instance.m_EnableLinearToGamma = value;
|
||||
}
|
||||
|
||||
|
||||
[Header("Editor")]
|
||||
[Tooltip("Hide the automatically generated objects.\n" +
|
||||
" - UIParticleRenderer\n" +
|
||||
" - UIParticle BakingCamera")]
|
||||
[SerializeField]
|
||||
private bool m_HideGeneratedObjects = true;
|
||||
|
||||
public static HideFlags globalHideFlags => instance.m_HideGeneratedObjects
|
||||
? HideFlags.DontSave | HideFlags.NotEditable | HideFlags.HideInHierarchy | HideFlags.HideInInspector
|
||||
: HideFlags.DontSave | HideFlags.NotEditable;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
[SettingsProvider]
|
||||
private static SettingsProvider CreateSettingsProvider()
|
||||
|
||||
@@ -5,7 +5,7 @@ MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
icon: {fileID: 2800000, guid: 5f0675613942149309588d556e33d990, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
#elif UNITY_2022_3_OR_NEWER
|
||||
#define PS_BAKE_API_V2
|
||||
#endif
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Coffee.UIParticleInternal;
|
||||
@@ -16,6 +15,7 @@ using UnityEngine.UI;
|
||||
|
||||
namespace Coffee.UIExtensions
|
||||
{
|
||||
[Icon("Packages/com.coffee.ui-particle/Editor/UIParticleIcon.png")]
|
||||
[ExecuteAlways]
|
||||
[RequireComponent(typeof(RectTransform))]
|
||||
[RequireComponent(typeof(CanvasRenderer))]
|
||||
@@ -25,10 +25,10 @@ namespace Coffee.UIExtensions
|
||||
private static readonly CombineInstance[] s_CombineInstances = { new CombineInstance() };
|
||||
private static readonly List<Material> s_Materials = new List<Material>(2);
|
||||
private static MaterialPropertyBlock s_Mpb;
|
||||
private static readonly List<UIParticleRenderer> s_Renderers = new List<UIParticleRenderer>(8);
|
||||
private static readonly Vector3[] s_Corners = new Vector3[4];
|
||||
private bool _delay;
|
||||
private int _index;
|
||||
private bool _isPrevStored;
|
||||
private bool _isTrail;
|
||||
private Bounds _lastBounds;
|
||||
private Material _materialForRendering;
|
||||
@@ -38,10 +38,10 @@ namespace Coffee.UIExtensions
|
||||
private float _prevCanvasScale;
|
||||
private Vector3 _prevPsPos;
|
||||
private Vector3 _prevScale;
|
||||
private bool _isPrevStored;
|
||||
private Vector2Int _prevScreenSize;
|
||||
private bool _preWarm;
|
||||
private ParticleSystemRenderer _renderer;
|
||||
private ParticleSystem _mainEmitter;
|
||||
|
||||
public override Texture mainTexture => _isTrail ? null : _particleSystem.GetTextureForSprite();
|
||||
|
||||
@@ -55,7 +55,7 @@ namespace Coffee.UIExtensions
|
||||
s_Corners[1] = transform.TransformPoint(_lastBounds.min.x, _lastBounds.max.y, 0);
|
||||
s_Corners[2] = transform.TransformPoint(_lastBounds.max.x, _lastBounds.max.y, 0);
|
||||
s_Corners[3] = transform.TransformPoint(_lastBounds.max.x, _lastBounds.min.y, 0);
|
||||
if (canvas)
|
||||
if (canvas != null)
|
||||
{
|
||||
var worldToLocalMatrix = canvas.rootCanvas.transform.worldToLocalMatrix;
|
||||
for (var i = 0; i < 4; ++i)
|
||||
@@ -95,7 +95,7 @@ namespace Coffee.UIExtensions
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!_materialForRendering)
|
||||
if (_materialForRendering == null)
|
||||
{
|
||||
_materialForRendering = base.materialForRendering;
|
||||
}
|
||||
@@ -106,7 +106,7 @@ namespace Coffee.UIExtensions
|
||||
|
||||
public void Reset(int index = -1)
|
||||
{
|
||||
if (_renderer)
|
||||
if (_renderer != null)
|
||||
{
|
||||
_renderer.enabled = true;
|
||||
}
|
||||
@@ -114,13 +114,14 @@ namespace Coffee.UIExtensions
|
||||
_parent = null;
|
||||
_particleSystem = null;
|
||||
_renderer = null;
|
||||
_mainEmitter = null;
|
||||
if (0 <= index)
|
||||
{
|
||||
_index = index;
|
||||
}
|
||||
|
||||
//_emitter = null;
|
||||
if (this && isActiveAndEnabled)
|
||||
if (isActiveAndEnabled)
|
||||
{
|
||||
material = null;
|
||||
canvasRenderer.Clear();
|
||||
@@ -138,7 +139,8 @@ namespace Coffee.UIExtensions
|
||||
{
|
||||
base.OnEnable();
|
||||
|
||||
if (!s_CombineInstances[0].mesh)
|
||||
hideFlags = UIParticleProjectSettings.globalHideFlags;
|
||||
if (s_CombineInstances[0].mesh == null)
|
||||
{
|
||||
s_CombineInstances[0].mesh = new Mesh
|
||||
{
|
||||
@@ -162,7 +164,7 @@ namespace Coffee.UIExtensions
|
||||
// Create renderer object.
|
||||
var go = new GameObject("[generated] UIParticleRenderer", typeof(UIParticleRenderer))
|
||||
{
|
||||
hideFlags = HideFlags.HideAndDontSave,
|
||||
hideFlags = UIParticleProjectSettings.globalHideFlags,
|
||||
layer = parent.gameObject.layer
|
||||
};
|
||||
|
||||
@@ -202,7 +204,6 @@ namespace Coffee.UIExtensions
|
||||
return modifiedMaterial;
|
||||
}
|
||||
|
||||
//
|
||||
var hash = new Hash128(
|
||||
modifiedMaterial ? (uint)modifiedMaterial.GetInstanceID() : 0,
|
||||
texture ? (uint)texture.GetInstanceID() : 0,
|
||||
@@ -225,7 +226,7 @@ namespace Coffee.UIExtensions
|
||||
return _modifiedMaterial;
|
||||
}
|
||||
|
||||
public void Set(UIParticle parent, ParticleSystem ps, bool isTrail)
|
||||
public void Set(UIParticle parent, ParticleSystem ps, bool isTrail, ParticleSystem mainEmitter)
|
||||
{
|
||||
_parent = parent;
|
||||
maskable = parent.maskable;
|
||||
@@ -248,10 +249,7 @@ namespace Coffee.UIExtensions
|
||||
|
||||
ps.TryGetComponent(out _renderer);
|
||||
_renderer.enabled = false;
|
||||
|
||||
//_emitter = emitter;
|
||||
_isTrail = isTrail;
|
||||
|
||||
_renderer.GetSharedMaterials(s_Materials);
|
||||
material = s_Materials[isTrail ? 1 : 0];
|
||||
s_Materials.Clear();
|
||||
@@ -268,6 +266,7 @@ namespace Coffee.UIExtensions
|
||||
_prevScreenSize = new Vector2Int(Screen.width, Screen.height);
|
||||
_prevCanvasScale = canvas ? canvas.scaleFactor : 1f;
|
||||
_delay = true;
|
||||
_mainEmitter = mainEmitter;
|
||||
|
||||
canvasRenderer.SetTexture(null);
|
||||
|
||||
@@ -284,10 +283,6 @@ namespace Coffee.UIExtensions
|
||||
|| !transform.lossyScale.GetScaled(_parent.scale3DForCalc).IsVisible() // Scale is not visible.
|
||||
|| (!_particleSystem.IsAlive() && !_particleSystem.isPlaying) // No particle.
|
||||
|| (_isTrail && !_particleSystem.trails.enabled) // Trail, but it is not enabled.
|
||||
#if UNITY_2018_3_OR_NEWER
|
||||
|| canvasRenderer.GetInheritedAlpha() <
|
||||
0.01f // #102: Do not bake particle system to mesh when the alpha is zero.
|
||||
#endif
|
||||
)
|
||||
{
|
||||
Profiler.BeginSample("[UIParticleRenderer] Clear Mesh");
|
||||
@@ -299,13 +294,31 @@ namespace Coffee.UIExtensions
|
||||
return;
|
||||
}
|
||||
|
||||
// Reset custom data.
|
||||
// var customData = _particleSystem.customData;
|
||||
// if (!customData.enabled || customData.GetMode(ParticleSystemCustomData.Custom1) == ParticleSystemCustomDataMode.Disabled)
|
||||
// {
|
||||
// customData.SetVector(ParticleSystemCustomData.Custom1, 0, 0);
|
||||
// customData.SetVector(ParticleSystemCustomData.Custom1, 1, 0);
|
||||
// customData.SetVector(ParticleSystemCustomData.Custom1, 2, 0);
|
||||
// customData.SetVector(ParticleSystemCustomData.Custom1, 3, 0);
|
||||
// }
|
||||
//
|
||||
// if (!customData.enabled || customData.GetMode(ParticleSystemCustomData.Custom2) == ParticleSystemCustomDataMode.Disabled)
|
||||
// {
|
||||
// customData.SetVector(ParticleSystemCustomData.Custom2, 0, 0);
|
||||
// customData.SetVector(ParticleSystemCustomData.Custom2, 1, 0);
|
||||
// customData.SetVector(ParticleSystemCustomData.Custom2, 2, 0);
|
||||
// customData.SetVector(ParticleSystemCustomData.Custom2, 3, 0);
|
||||
// }
|
||||
|
||||
var main = _particleSystem.main;
|
||||
var scale = GetWorldScale();
|
||||
var psPos = _particleSystem.transform.position;
|
||||
|
||||
// Simulate particles.
|
||||
Profiler.BeginSample("[UIParticle] Bake Mesh > Simulate Particles");
|
||||
if (!_isTrail && _parent.canSimulate)
|
||||
if (!_isTrail && _parent.canSimulate && !_mainEmitter)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (!Application.isPlaying)
|
||||
@@ -316,6 +329,13 @@ namespace Coffee.UIExtensions
|
||||
#endif
|
||||
{
|
||||
ResolveResolutionChange(psPos, scale);
|
||||
|
||||
// fix: second and subsequent bursts not displayed when world simulation and non-looping. (#326)
|
||||
if (!_particleSystem.IsLocalSpace() && !main.loop && _particleSystem.time == 0)
|
||||
{
|
||||
_delay = true;
|
||||
}
|
||||
|
||||
Simulate(scale, _parent.isPaused || _delay);
|
||||
|
||||
if (_delay && !_parent.isPaused)
|
||||
@@ -423,17 +443,16 @@ namespace Coffee.UIExtensions
|
||||
workerMesh.LinearToGamma();
|
||||
}
|
||||
|
||||
var components = ListPool<Component>.Rent();
|
||||
var components = InternalListPool<Component>.Rent();
|
||||
GetComponents(typeof(IMeshModifier), components);
|
||||
|
||||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
for (var i = 0; i < components.Count; i++)
|
||||
{
|
||||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
((IMeshModifier)components[i]).ModifyMesh(workerMesh);
|
||||
}
|
||||
#pragma warning restore CS0618 // Type or member is obsolete
|
||||
}
|
||||
|
||||
ListPool<Component>.Return(ref components);
|
||||
InternalListPool<Component>.Return(ref components);
|
||||
}
|
||||
|
||||
Profiler.EndSample();
|
||||
@@ -445,22 +464,25 @@ namespace Coffee.UIExtensions
|
||||
|
||||
// Get grouped renderers.
|
||||
Profiler.BeginSample("[UIParticleRenderer] Set Mesh");
|
||||
s_Renderers.Clear();
|
||||
var renderers = InternalListPool<UIParticleRenderer>.Rent();
|
||||
if (_parent.useMeshSharing)
|
||||
{
|
||||
UIParticleUpdater.GetGroupedRenderers(_parent.groupId, _index, s_Renderers);
|
||||
UIParticleUpdater.GetGroupedRenderers(_parent.groupId, _index, renderers);
|
||||
}
|
||||
|
||||
for (var i = 0; i < s_Renderers.Count; i++)
|
||||
for (var i = 0; i < renderers.Count; i++)
|
||||
{
|
||||
if (s_Renderers[i] == this) continue;
|
||||
var r = renderers[i];
|
||||
if (r == this) continue;
|
||||
|
||||
s_Renderers[i].canvasRenderer.SetMesh(workerMesh);
|
||||
s_Renderers[i]._lastBounds = _lastBounds;
|
||||
s_Renderers[i].canvasRenderer.materialCount = 1;
|
||||
s_Renderers[i].canvasRenderer.SetMaterial(materialForRendering, 0);
|
||||
r.canvasRenderer.SetMesh(workerMesh);
|
||||
r._lastBounds = _lastBounds;
|
||||
r.canvasRenderer.materialCount = 1;
|
||||
r.canvasRenderer.SetMaterial(materialForRendering, 0);
|
||||
}
|
||||
|
||||
InternalListPool<UIParticleRenderer>.Return(ref renderers);
|
||||
|
||||
if (_parent.canRender)
|
||||
{
|
||||
canvasRenderer.SetMesh(workerMesh);
|
||||
@@ -471,8 +493,6 @@ namespace Coffee.UIExtensions
|
||||
}
|
||||
|
||||
Profiler.EndSample();
|
||||
|
||||
s_Renderers.Clear();
|
||||
}
|
||||
|
||||
public override void SetMaterialDirty()
|
||||
@@ -544,6 +564,30 @@ namespace Coffee.UIExtensions
|
||||
return Matrix4x4.Translate(psPos)
|
||||
* Matrix4x4.Scale(scale);
|
||||
case ParticleSystemSimulationSpace.World:
|
||||
if (_isTrail)
|
||||
{
|
||||
return Matrix4x4.Translate(psPos)
|
||||
* Matrix4x4.Scale(scale)
|
||||
* Matrix4x4.Translate(-psPos);
|
||||
}
|
||||
|
||||
if (_mainEmitter)
|
||||
{
|
||||
if (_mainEmitter.IsLocalSpace())
|
||||
{
|
||||
return Matrix4x4.Translate(psPos)
|
||||
* Matrix4x4.Scale(scale)
|
||||
* Matrix4x4.Translate(-psPos);
|
||||
}
|
||||
else
|
||||
{
|
||||
psPos = _particleSystem.transform.position - _mainEmitter.transform.position;
|
||||
return Matrix4x4.Translate(psPos)
|
||||
* Matrix4x4.Scale(scale)
|
||||
* Matrix4x4.Translate(-psPos);
|
||||
}
|
||||
}
|
||||
|
||||
return Matrix4x4.Scale(scale);
|
||||
case ParticleSystemSimulationSpace.Custom:
|
||||
return Matrix4x4.Translate(_particleSystem.main.customSimulationSpace.position.GetScaled(scale))
|
||||
@@ -606,6 +650,7 @@ namespace Coffee.UIExtensions
|
||||
: main.useUnscaledTime
|
||||
? Time.unscaledDeltaTime
|
||||
: Time.deltaTime;
|
||||
deltaTime *= _parent.timeScaleMultiplier;
|
||||
|
||||
// Pre-warm:
|
||||
if (0 < deltaTime && _preWarm)
|
||||
@@ -686,7 +731,7 @@ namespace Coffee.UIExtensions
|
||||
if (s_Mpb.isEmpty) return;
|
||||
|
||||
// #41: Copy the value from MaterialPropertyBlock to CanvasRenderer
|
||||
if (!materialForRendering) return;
|
||||
if (materialForRendering == null) return;
|
||||
|
||||
for (var i = 0; i < _parent.m_AnimatableProperties.Length; i++)
|
||||
{
|
||||
|
||||
@@ -16,37 +16,50 @@ namespace Coffee.UIExtensions
|
||||
|
||||
public static void Register(UIParticle particle)
|
||||
{
|
||||
if (!particle) return;
|
||||
if (particle == null) return;
|
||||
s_ActiveParticles.Add(particle);
|
||||
}
|
||||
|
||||
public static void Unregister(UIParticle particle)
|
||||
{
|
||||
if (!particle) return;
|
||||
if (particle == null) return;
|
||||
s_ActiveParticles.Remove(particle);
|
||||
}
|
||||
|
||||
public static void Register(UIParticleAttractor attractor)
|
||||
{
|
||||
if (!attractor) return;
|
||||
if (attractor == null) return;
|
||||
s_ActiveAttractors.Add(attractor);
|
||||
}
|
||||
|
||||
public static void Unregister(UIParticleAttractor attractor)
|
||||
{
|
||||
if (!attractor) return;
|
||||
if (attractor == null) return;
|
||||
s_ActiveAttractors.Remove(attractor);
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
[InitializeOnLoadMethod]
|
||||
private static void InitializeOnLoad()
|
||||
{
|
||||
UIExtraCallbacks.onAfterCanvasRebuild += Refresh;
|
||||
|
||||
EditorApplication.playModeStateChanged += state =>
|
||||
{
|
||||
UIExtraCallbacks.onAfterCanvasRebuild -= Refresh;
|
||||
if (state == PlayModeStateChange.EnteredEditMode || state == PlayModeStateChange.EnteredPlayMode)
|
||||
{
|
||||
UIExtraCallbacks.onAfterCanvasRebuild += Refresh;
|
||||
}
|
||||
};
|
||||
}
|
||||
#else
|
||||
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
|
||||
#endif
|
||||
private static void InitializeOnLoad()
|
||||
{
|
||||
UIExtraCallbacks.onAfterCanvasRebuild += Refresh;
|
||||
}
|
||||
#endif
|
||||
|
||||
private static void Refresh()
|
||||
{
|
||||
@@ -58,7 +71,7 @@ namespace Coffee.UIExtensions
|
||||
for (var i = 0; i < s_ActiveParticles.Count; i++)
|
||||
{
|
||||
var uip = s_ActiveParticles[i];
|
||||
if (!uip || !uip.canvas || !uip.isPrimary || !s_UpdatedGroupIds.Add(uip.groupId)) continue;
|
||||
if (uip == null || uip.canvas == null || !uip.isPrimary || !s_UpdatedGroupIds.Add(uip.groupId)) continue;
|
||||
|
||||
uip.UpdateTransformScale();
|
||||
uip.UpdateRenderers();
|
||||
@@ -68,7 +81,7 @@ namespace Coffee.UIExtensions
|
||||
for (var i = 0; i < s_ActiveParticles.Count; i++)
|
||||
{
|
||||
var uip = s_ActiveParticles[i];
|
||||
if (!uip || !uip.canvas) continue;
|
||||
if (uip == null || uip.canvas == null) continue;
|
||||
|
||||
uip.UpdateTransformScale();
|
||||
|
||||
@@ -112,7 +125,7 @@ namespace Coffee.UIExtensions
|
||||
var uip = s_ActiveParticles[i];
|
||||
if (!uip.useMeshSharing || uip.groupId != groupId) continue;
|
||||
if (uip.isPrimary) return uip;
|
||||
if (!primary && uip.canSimulate) primary = uip;
|
||||
if (primary == null && uip.canSimulate) primary = uip;
|
||||
}
|
||||
|
||||
return primary;
|
||||
|
||||
@@ -13,11 +13,7 @@ namespace Coffee.UIParticleInternal
|
||||
{
|
||||
if (s_TmpParticles.Length < size)
|
||||
{
|
||||
while (s_TmpParticles.Length < size)
|
||||
{
|
||||
size = Mathf.NextPowerOfTwo(size);
|
||||
}
|
||||
|
||||
size = Mathf.NextPowerOfTwo(size);
|
||||
s_TmpParticles = new ParticleSystem.Particle[size];
|
||||
}
|
||||
|
||||
@@ -88,11 +84,11 @@ namespace Coffee.UIParticleInternal
|
||||
var bRenderer = b.GetComponent<ParticleSystemRenderer>();
|
||||
|
||||
// Render queue: ascending
|
||||
var aMat = aRenderer.sharedMaterial ? aRenderer.sharedMaterial : aRenderer.trailMaterial;
|
||||
var bMat = bRenderer.sharedMaterial ? bRenderer.sharedMaterial : bRenderer.trailMaterial;
|
||||
if (!aMat && !bMat) return 0;
|
||||
if (!aMat) return -1;
|
||||
if (!bMat) return 1;
|
||||
var aMat = aRenderer.sharedMaterial != null ? aRenderer.sharedMaterial : aRenderer.trailMaterial;
|
||||
var bMat = bRenderer.sharedMaterial != null ? bRenderer.sharedMaterial : bRenderer.trailMaterial;
|
||||
if (aMat == null && bMat == null) return 0;
|
||||
if (aMat == null) return -1;
|
||||
if (bMat == null) return 1;
|
||||
|
||||
if (sortByMaterial)
|
||||
{
|
||||
@@ -146,7 +142,7 @@ namespace Coffee.UIParticleInternal
|
||||
|
||||
public static Texture2D GetTextureForSprite(this ParticleSystem self)
|
||||
{
|
||||
if (!self) return null;
|
||||
if (self == null) return null;
|
||||
|
||||
// Get sprite's texture.
|
||||
var tsaModule = self.textureSheetAnimation;
|
||||
@@ -155,7 +151,7 @@ namespace Coffee.UIParticleInternal
|
||||
for (var i = 0; i < tsaModule.spriteCount; i++)
|
||||
{
|
||||
var sprite = tsaModule.GetSprite(i);
|
||||
if (!sprite) continue;
|
||||
if (sprite == null) continue;
|
||||
|
||||
return sprite.GetActualTexture();
|
||||
}
|
||||
@@ -167,9 +163,38 @@ namespace Coffee.UIParticleInternal
|
||||
{
|
||||
foreach (var p in self)
|
||||
{
|
||||
if (!p) continue;
|
||||
if (p == null) continue;
|
||||
action.Invoke(p);
|
||||
}
|
||||
}
|
||||
|
||||
public static ParticleSystem GetMainEmitter(this ParticleSystem self, List<ParticleSystem> list)
|
||||
{
|
||||
if (self == null || list == null || list.Count == 0) return null;
|
||||
|
||||
for (var i = 0; i < list.Count; i++)
|
||||
{
|
||||
var parent = list[i];
|
||||
if (parent != self && IsSubEmitterOf(self, parent)) return parent;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static bool IsSubEmitterOf(this ParticleSystem self, ParticleSystem parent)
|
||||
{
|
||||
if (self == null || parent == null) return false;
|
||||
|
||||
var subEmitters = parent.subEmitters;
|
||||
if (!subEmitters.enabled) return false; // No sub emitters.
|
||||
|
||||
var count = subEmitters.subEmittersCount;
|
||||
for (var i = 0; i < count; i++)
|
||||
{
|
||||
if (subEmitters.GetSubEmitterSystem(i) == self) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace Coffee.UIExtensions.Demo
|
||||
|
||||
private void Start()
|
||||
{
|
||||
if (!m_Origin) return;
|
||||
if (m_Origin == null) return;
|
||||
m_Origin.SetActive(false);
|
||||
|
||||
var parent = m_Origin.transform.parent;
|
||||
|
||||
@@ -42,7 +42,7 @@ public class UIElementDragger : MonoBehaviour, IBeginDragHandler, IDragHandler,
|
||||
break;
|
||||
case Target.Custom:
|
||||
_rectTransform.localPosition += delta;
|
||||
if (m_CustomTarget)
|
||||
if (m_CustomTarget != null)
|
||||
{
|
||||
if (m_UseCanvasScale)
|
||||
{
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using Coffee.UIParticleInternal;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Serialization;
|
||||
using UnityEngine.UI;
|
||||
@@ -51,7 +52,7 @@ namespace Coffee.UIExtensions.Demo
|
||||
|
||||
public void EnableAnimations(bool flag)
|
||||
{
|
||||
foreach (var animator in FindObjectsOfType<Animator>())
|
||||
foreach (var animator in Misc.FindObjectsOfType<Animator>())
|
||||
{
|
||||
animator.enabled = flag;
|
||||
}
|
||||
@@ -79,7 +80,7 @@ namespace Coffee.UIExtensions.Demo
|
||||
|
||||
public void UIParticle_Scale(float scale)
|
||||
{
|
||||
foreach (var uip in FindObjectsOfType<UIParticle>())
|
||||
foreach (var uip in Misc.FindObjectsOfType<UIParticle>())
|
||||
{
|
||||
uip.scale = scale;
|
||||
}
|
||||
@@ -87,7 +88,7 @@ namespace Coffee.UIExtensions.Demo
|
||||
|
||||
public void ParticleSystem_WorldSpaseSimulation(bool flag)
|
||||
{
|
||||
foreach (var p in FindObjectsOfType<ParticleSystem>())
|
||||
foreach (var p in Misc.FindObjectsOfType<ParticleSystem>())
|
||||
{
|
||||
var main = p.main;
|
||||
main.simulationSpace = flag
|
||||
@@ -123,7 +124,7 @@ namespace Coffee.UIExtensions.Demo
|
||||
|
||||
public void ParticleSystem_SetScale(float scale)
|
||||
{
|
||||
foreach (var ps in FindObjectsOfType<ParticleSystem>())
|
||||
foreach (var ps in Misc.FindObjectsOfType<ParticleSystem>())
|
||||
{
|
||||
ps.transform.localScale = new Vector3(scale, scale, scale);
|
||||
}
|
||||
|
||||
@@ -42,12 +42,12 @@ TextureImporter:
|
||||
compressionQuality: 50
|
||||
spriteMode: 1
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
spriteMeshType: 0
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
spriteGenerateFallbackPhysicsShape: 0
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
|
||||
@@ -27,7 +27,7 @@ TextureImporter:
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
textureFormat: 4
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
@@ -42,12 +42,12 @@ TextureImporter:
|
||||
compressionQuality: 50
|
||||
spriteMode: 1
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
spriteMeshType: 0
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
spriteGenerateFallbackPhysicsShape: 0
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
|
||||
@@ -42,12 +42,12 @@ TextureImporter:
|
||||
compressionQuality: 50
|
||||
spriteMode: 1
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
spriteMeshType: 0
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
spriteGenerateFallbackPhysicsShape: 0
|
||||
alphaUsage: 0
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
|
||||
@@ -27,7 +27,7 @@ TextureImporter:
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: -1
|
||||
textureFormat: 4
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
@@ -42,12 +42,12 @@ TextureImporter:
|
||||
compressionQuality: 50
|
||||
spriteMode: 1
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
spriteMeshType: 0
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
spriteGenerateFallbackPhysicsShape: 0
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
|
||||
@@ -40,7 +40,10 @@
|
||||
Lighting Off
|
||||
ZWrite Off
|
||||
ZTest [unity_GUIZTestMode]
|
||||
Fog { Mode Off }
|
||||
Fog
|
||||
{
|
||||
Mode Off
|
||||
}
|
||||
Blend One One
|
||||
|
||||
ColorMask [_ColorMask]
|
||||
@@ -61,21 +64,21 @@
|
||||
|
||||
struct appdata_t
|
||||
{
|
||||
float4 vertex : POSITION;
|
||||
float4 color : COLOR;
|
||||
float4 vertex : POSITION;
|
||||
float4 color : COLOR;
|
||||
float2 texcoord : TEXCOORD0;
|
||||
UNITY_VERTEX_INPUT_INSTANCE_ID
|
||||
};
|
||||
|
||||
struct v2f
|
||||
{
|
||||
float4 vertex : SV_POSITION;
|
||||
fixed4 color : COLOR;
|
||||
float2 texcoord : TEXCOORD0;
|
||||
float4 worldPosition : TEXCOORD1;
|
||||
float4 vertex : SV_POSITION;
|
||||
fixed4 color : COLOR;
|
||||
float2 texcoord : TEXCOORD0;
|
||||
float4 worldPosition : TEXCOORD1;
|
||||
UNITY_VERTEX_OUTPUT_STEREO
|
||||
};
|
||||
|
||||
|
||||
fixed4 _Color;
|
||||
sampler2D _MainTex;
|
||||
float4 _MainTex_ST;
|
||||
@@ -114,4 +117,4 @@
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
"name": "com.coffee.ui-particle",
|
||||
"displayName": "UI Particle",
|
||||
"description": "This package provides a component to render particle effects for uGUI.\nThe particle rendering is maskable and sortable, without the need for an extra Camera, RenderTexture, or Canvas.",
|
||||
"version": "5.0.0-preview.2",
|
||||
"version": "4.12.1",
|
||||
"unity": "2018.2",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
|
||||
11
ProjectSettings/MinimalResourceSettings.json
Normal file
11
ProjectSettings/MinimalResourceSettings.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"MonoBehaviour": {
|
||||
"m_Enabled": true,
|
||||
"m_EditorHideFlags": 0,
|
||||
"m_Name": "",
|
||||
"m_EditorClassIdentifier": "",
|
||||
"m_OutputDllPaths": [
|
||||
"Packages/com.coffee.ui-particle/Runtime/Coffee.UIParticle.R.dll"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -124,7 +124,7 @@ PlayerSettings:
|
||||
bundleVersion: 1.0
|
||||
preloadedAssets:
|
||||
- {fileID: 11400000, guid: 86087a0847f384b538391745dad4565c, type: 2}
|
||||
- {fileID: 11400000, guid: be3e05903ef7041d39b3ef8ecdd47f08, type: 2}
|
||||
- {fileID: 11400000, guid: 4b9df7b8a4193489299b8f477348ae0c, type: 2}
|
||||
metroInputSource: 0
|
||||
wsaTransparentSwapchain: 0
|
||||
m_HolographicPauseOnTrackingLoss: 1
|
||||
@@ -520,7 +520,7 @@ PlayerSettings:
|
||||
webGLTemplate: APPLICATION:Default
|
||||
webGLAnalyzeBuildSize: 0
|
||||
webGLUseEmbeddedResources: 0
|
||||
webGLCompressionFormat: 1
|
||||
webGLCompressionFormat: 2
|
||||
webGLLinkerTarget: 0
|
||||
webGLThreadsSupport: 0
|
||||
scriptingDefineSymbols:
|
||||
|
||||
Reference in New Issue
Block a user