Compare commits
44 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
19989cf18c | ||
|
|
30b00762f6 | ||
|
|
154a04c022 | ||
|
|
3eab0979b9 | ||
|
|
01e08eefbd | ||
|
|
a8af984d6f | ||
|
|
1b5c359058 | ||
|
|
ea043524c0 | ||
|
|
c37c014864 | ||
|
|
dc81428921 | ||
|
|
e82c833d04 | ||
|
|
2ec3748336 | ||
|
|
2eff411bd9 | ||
|
|
46c300b347 | ||
|
|
e1863f25d3 | ||
|
|
89289c052f | ||
|
|
84ac11e6b7 | ||
|
|
cc2be37b9e | ||
|
|
ad20d128a2 | ||
|
|
fcae60bf29 | ||
|
|
7fd4a8e343 | ||
|
|
2052dda953 | ||
|
|
e88bc54c2c | ||
|
|
1627de10eb | ||
|
|
88890ff159 | ||
|
|
25582dc51f | ||
|
|
76c6dcfd76 | ||
|
|
772bf50d16 | ||
|
|
93d3919b6f | ||
|
|
0c1022c622 | ||
|
|
c61d22d221 | ||
|
|
cbe3105b0f | ||
|
|
7c4242150b | ||
|
|
c6b25c73bf | ||
|
|
2f4a963a56 | ||
|
|
4c5b1287a4 | ||
|
|
15e31abc3c | ||
|
|
8a78ec13ad | ||
|
|
f53a7faed3 | ||
|
|
0af2042132 | ||
|
|
9a0187a72a | ||
|
|
e4f5fde11c | ||
|
|
974aff72d7 | ||
|
|
2aa8d41950 |
@@ -1 +0,0 @@
|
||||
s/Coffee.Internal/Coffee.UIParticleInternal/g
|
||||
208
.editorconfig
Normal file
@@ -0,0 +1,208 @@
|
||||
root = true
|
||||
|
||||
[*.json]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*.asmdef]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
# C# files
|
||||
[*.cs]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
csharp_style_implicit_object_creation_when_type_is_apparent = false
|
||||
resharper_object_creation_when_type_evident = explicitly_typed
|
||||
|
||||
# Keep
|
||||
csharp_keep_existing_attribute_arrangement = true
|
||||
csharp_keep_existing_embedded_arrangement = true
|
||||
csharp_keep_user_linebreaks = true
|
||||
csharp_keep_existing_linebreaks = true
|
||||
csharp_place_simple_embedded_statement_on_same_line = false
|
||||
csharp_place_simple_blocks_on_single_line = false
|
||||
csharp_keep_existing_initializer_arrangement = true
|
||||
csharp_keep_existing_arrangement = true
|
||||
|
||||
# Standard properties
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
|
||||
# Brace preferences
|
||||
csharp_brace_style = next_line
|
||||
csharp_braces_for_ifelse = required_for_multiline_statement
|
||||
csharp_braces_for_for = required
|
||||
csharp_braces_for_foreach = required
|
||||
csharp_braces_for_while = required
|
||||
csharp_braces_for_dowhile = required
|
||||
csharp_braces_for_using = required
|
||||
csharp_case_block_braces = next_line
|
||||
csharp_initializer_braces = next_line
|
||||
|
||||
# New line preferences
|
||||
csharp_new_line_before_open_brace = all
|
||||
csharp_new_line_before_else = true
|
||||
csharp_new_line_before_catch = true
|
||||
csharp_new_line_before_finally = true
|
||||
csharp_new_line_before_members_in_object_initializers = true
|
||||
csharp_new_line_before_members_in_anonymous_types = true
|
||||
csharp_new_line_between_query_expression_clauses = true
|
||||
|
||||
# Indentation preferences
|
||||
csharp_indent_block_contents = true
|
||||
csharp_indent_braces = false
|
||||
csharp_indent_case_contents = true
|
||||
csharp_indent_case_contents_when_block = false
|
||||
csharp_indent_switch_labels = true
|
||||
csharp_indent_labels = one_less_than_current
|
||||
|
||||
# Modifier preferences
|
||||
csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:suggestion
|
||||
|
||||
# avoid this. unless absolutely necessary
|
||||
dotnet_style_qualification_for_field = false:suggestion
|
||||
dotnet_style_qualification_for_property = false:suggestion
|
||||
dotnet_style_qualification_for_method = false:suggestion
|
||||
dotnet_style_qualification_for_event = false:suggestion
|
||||
|
||||
# Types: use keywords instead of BCL types, and permit var only when the type is clear
|
||||
csharp_style_var_for_built_in_types = true:suggestion
|
||||
csharp_style_var_when_type_is_apparent = true:none
|
||||
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
|
||||
|
||||
# Arguments
|
||||
csharp_arguments_literal = named:suggestion
|
||||
csharp_arguments_string_literal = named:suggestion
|
||||
|
||||
# Naming: public and protected fields -> camelCase
|
||||
dotnet_naming_rule.protected_public_fields.severity = suggestion
|
||||
dotnet_naming_rule.protected_public_fields.symbols = protected_public_fields
|
||||
dotnet_naming_rule.protected_public_fields.style = camel_case
|
||||
dotnet_naming_symbols.protected_public_fields.applicable_kinds = field, event
|
||||
dotnet_naming_symbols.protected_public_fields.applicable_accessibilities = public, protected
|
||||
dotnet_naming_style.camel_case.capitalization = camel_case
|
||||
|
||||
# Naming: properties -> camelCase
|
||||
dotnet_naming_rule.properties.severity = suggestion
|
||||
dotnet_naming_rule.properties.symbols = properties
|
||||
dotnet_naming_rule.properties.style = camel_case
|
||||
dotnet_naming_symbols.properties.applicable_kinds = property
|
||||
|
||||
# Naming: constant fields -> k_PascalCase
|
||||
dotnet_naming_rule.constant_fields.severity = suggestion
|
||||
dotnet_naming_rule.constant_fields.symbols = constant_fields
|
||||
dotnet_naming_rule.constant_fields.style = k_pascal_case
|
||||
dotnet_naming_symbols.constant_fields.applicable_kinds = field
|
||||
dotnet_naming_symbols.constant_fields.required_modifiers = const
|
||||
dotnet_naming_style.k_pascal_case.required_prefix = k_
|
||||
dotnet_naming_style.k_pascal_case.capitalization = pascal_case
|
||||
|
||||
# Naming: static fields -> s_PascalCase
|
||||
dotnet_naming_rule.static_fields_should_have_prefix.severity = suggestion
|
||||
dotnet_naming_rule.static_fields_should_have_prefix.symbols = static_fields
|
||||
dotnet_naming_rule.static_fields_should_have_prefix.style = s_pascal_case
|
||||
dotnet_naming_symbols.static_fields.applicable_kinds = field, property
|
||||
dotnet_naming_symbols.static_fields.required_modifiers = static
|
||||
dotnet_naming_symbols.static_fields.applicable_accessibilities = private, internal, private_protected
|
||||
dotnet_naming_style.s_pascal_case.required_prefix = s_
|
||||
dotnet_naming_style.s_pascal_case.capitalization = pascal_case
|
||||
|
||||
# Naming: internal and private fields -> _camelCase
|
||||
dotnet_naming_rule.private_internal_fields.severity = suggestion
|
||||
dotnet_naming_rule.private_internal_fields.symbols = private_internal_fields
|
||||
dotnet_naming_rule.private_internal_fields.style = _camel_case
|
||||
dotnet_naming_symbols.private_internal_fields.applicable_kinds = field
|
||||
dotnet_naming_symbols.private_internal_fields.applicable_accessibilities = private, internal
|
||||
dotnet_naming_style._camel_case.required_prefix = _
|
||||
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_prefer_static_local_function = true:suggestion
|
||||
csharp_prefer_simple_using_statement = false:none
|
||||
csharp_style_prefer_switch_expression = true:suggestion
|
||||
dotnet_style_readonly_field = true:suggestion
|
||||
|
||||
# Expression-level preferences
|
||||
dotnet_style_object_initializer = true:suggestion
|
||||
dotnet_style_collection_initializer = true:suggestion
|
||||
dotnet_style_explicit_tuple_names = true:suggestion
|
||||
dotnet_style_coalesce_expression = true:suggestion
|
||||
dotnet_style_null_propagation = true:suggestion
|
||||
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
|
||||
dotnet_style_prefer_inferred_tuple_names = true:suggestion
|
||||
dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
|
||||
dotnet_style_prefer_auto_properties = true:suggestion
|
||||
dotnet_style_prefer_conditional_expression_over_assignment = true:silent
|
||||
dotnet_style_prefer_conditional_expression_over_return = true:silent
|
||||
csharp_prefer_simple_default_expression = true:suggestion
|
||||
|
||||
# Expression-bodied members
|
||||
csharp_style_expression_bodied_accessors = when_on_single_line:suggestion
|
||||
csharp_style_expression_bodied_methods = false:suggestion
|
||||
csharp_style_expression_bodied_constructors = false:suggestion
|
||||
csharp_style_expression_bodied_operators = false:suggestion
|
||||
csharp_style_expression_bodied_properties = when_on_single_line:suggestion
|
||||
csharp_style_expression_bodied_indexers = false:suggestion
|
||||
csharp_style_expression_bodied_lambdas = when_on_single_line:silent
|
||||
csharp_style_expression_bodied_local_functions = false:suggestion
|
||||
|
||||
# Pattern matching
|
||||
csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
|
||||
csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
|
||||
csharp_style_inlined_variable_declaration = true:suggestion
|
||||
|
||||
# Null checking preferences
|
||||
csharp_style_throw_expression = true:suggestion
|
||||
csharp_style_conditional_delegate_call = true:suggestion
|
||||
|
||||
# Other features
|
||||
csharp_style_prefer_index_operator = false:none
|
||||
csharp_style_prefer_range_operator = false:none
|
||||
csharp_style_pattern_local_over_anonymous_function = false:none
|
||||
|
||||
# Space preferences
|
||||
csharp_space_after_cast = false
|
||||
csharp_space_after_colon_in_inheritance_clause = true
|
||||
csharp_space_after_comma = true
|
||||
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_before_colon_in_inheritance_clause = true
|
||||
csharp_space_before_comma = false
|
||||
csharp_space_before_dot = false
|
||||
csharp_space_before_open_square_brackets = false
|
||||
csharp_space_before_semicolon_in_for_statement = false
|
||||
csharp_space_between_empty_square_brackets = false
|
||||
csharp_space_between_method_call_empty_parameter_list_parentheses = false
|
||||
csharp_space_between_method_call_name_and_opening_parenthesis = false
|
||||
csharp_space_between_method_call_parameter_list_parentheses = false
|
||||
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
|
||||
csharp_space_between_method_declaration_name_and_open_parenthesis = false
|
||||
csharp_space_between_method_declaration_parameter_list_parentheses = false
|
||||
csharp_space_between_parentheses = false
|
||||
csharp_space_between_square_brackets = false
|
||||
|
||||
# ReSharper inspection severities
|
||||
resharper_check_namespace_highlighting = none
|
||||
resharper_for_can_be_converted_to_foreach_highlighting = none
|
||||
resharper_xmldoc_indent_text = ZeroIndent
|
||||
103
.github/workflows/release.yml
vendored
Normal file
@@ -0,0 +1,103 @@
|
||||
name: 🔖 Release
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- release
|
||||
- release-preview
|
||||
- release-v4
|
||||
tags-ignore:
|
||||
- "**"
|
||||
|
||||
jobs:
|
||||
release:
|
||||
name: 🔖 Release (${{ github.ref_name }})
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
issues: write
|
||||
outputs:
|
||||
channel: ${{ steps.release.outputs.new_release_channel }}
|
||||
released: ${{ steps.release.outputs.new_release_published }}
|
||||
tag: ${{ steps.release.outputs.new_release_git_tag }}
|
||||
version: ${{ steps.release.outputs.new_release_version }}
|
||||
merge_to: ${{ steps.summary.outputs.merge_to }}
|
||||
split_to: ${{ steps.summary.outputs.split_to }}
|
||||
steps:
|
||||
- name: 🚚 Checkout (${{ github.ref_name }})
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: 🔖 Run semantic release
|
||||
uses: cycjimmy/semantic-release-action@v4
|
||||
id: release
|
||||
with:
|
||||
working_directory: Packages/src
|
||||
extra_plugins: |
|
||||
@semantic-release/changelog
|
||||
@semantic-release/git
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
|
||||
- id: summary
|
||||
run: |
|
||||
echo "🔖 New release published: '${{ steps.release.outputs.new_release_published }}'" | tee -a $GITHUB_STEP_SUMMARY
|
||||
echo "🔖 New release version: '${{ steps.release.outputs.new_release_version }}'" | tee -a $GITHUB_STEP_SUMMARY
|
||||
echo "🔖 New release channel: '${{ steps.release.outputs.new_release_channel }}'" | tee -a $GITHUB_STEP_SUMMARY
|
||||
echo "🔖 New release git tag: '${{ steps.release.outputs.new_release_git_tag }}'" | tee -a $GITHUB_STEP_SUMMARY
|
||||
|
||||
if [ '${{ steps.release.outputs.new_release_published }}' = 'false' ]; then
|
||||
echo "No new release published." | tee -a $GITHUB_STEP_SUMMARY
|
||||
elif [ '${{ github.ref_name }}' = 'release' ]; then
|
||||
echo "merge_to=develop" | tee -a $GITHUB_OUTPUT
|
||||
echo "split_to=main" | tee -a $GITHUB_OUTPUT
|
||||
elif [ '${{ github.ref_name }}' = 'release-preview' ]; then
|
||||
echo "merge_to=develop-preview" | tee -a $GITHUB_OUTPUT
|
||||
echo "split_to=preview" | tee -a $GITHUB_OUTPUT
|
||||
elif [ '${{ github.ref_name }}' = 'release-4.x' ]; then
|
||||
echo "merge_to=develop-4.x" | tee -a $GITHUB_OUTPUT
|
||||
echo "split_to=4.x" | tee -a $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
merge-to:
|
||||
if: needs.release.outputs.merge_to != ''
|
||||
needs: release
|
||||
name: 🔀 Merge to ${{ needs.release.outputs.merge_to }}
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- name: 🚚 Checkout (${{ needs.release.outputs.merge_to }})
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ needs.release.outputs.merge_to }}
|
||||
fetch-depth: 0
|
||||
- name: 🔀 Merge '${{ needs.release.outputs.tag }}' into '${{ needs.release.outputs.merge_to }}'
|
||||
run: |
|
||||
git config --local user.email "github-actions[bot]@users.noreply.github.com"
|
||||
git config --local user.name "github-actions[bot]"
|
||||
|
||||
git merge ${{ needs.release.outputs.tag }}
|
||||
git push origin ${{ needs.release.outputs.merge_to }}
|
||||
|
||||
split-to:
|
||||
if: needs.release.outputs.split_to != ''
|
||||
needs: release
|
||||
name: 🔀 Split package to ${{ needs.release.outputs.split_to }}
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- name: 🚚 Checkout (${{ needs.release.outputs.tag }})
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ needs.release.outputs.tag }}
|
||||
fetch-depth: 0
|
||||
- name: 🔀 Split subtree 'Packages/src' to '${{ needs.release.outputs.split_to }}'
|
||||
run: |
|
||||
split_to=${{ needs.release.outputs.split_to }}
|
||||
git branch $split_to origin/$split_to
|
||||
git subtree split --prefix=Packages/src --branch $split_to
|
||||
git tag ${{ needs.release.outputs.version }} $split_to
|
||||
git push origin ${{ needs.release.outputs.version }} $split_to:$split_to
|
||||
95
.github/workflows/test.yml
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
# Required secrets
|
||||
# UNITY_LICENSE: The contents of Unity license file
|
||||
# UNITY_EMAIL: Unity user email to login
|
||||
# UNITY_PASSWORD: Unity user password to login
|
||||
name: 🧪 Test
|
||||
|
||||
env:
|
||||
# MINIMUM_VERSION: The minimum version of Unity.
|
||||
MINIMUM_VERSION: 2019.4
|
||||
# EXCLUDE_FILTER: The excluded versions of Unity.
|
||||
EXCLUDE_FILTER: '(2020.2.0)'
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- develop
|
||||
- develop-preview
|
||||
- develop-4.x
|
||||
tags:
|
||||
- "!*"
|
||||
paths-ignore:
|
||||
- "*.md"
|
||||
pull_request:
|
||||
types:
|
||||
- opened
|
||||
- synchronize
|
||||
|
||||
jobs:
|
||||
setup:
|
||||
name: ⚙️ Setup
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
unityVersions: ${{ steps.setup.outputs.unityVersions }}
|
||||
steps:
|
||||
- name: ⚙️ Find target Unity versions
|
||||
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=[]
|
||||
|
||||
VERSIONS=`echo "[${LATEST_VERSIONS}, ${ADDITIONAL_VERSIONS}]" \
|
||||
| jq -c '[ flatten | sort | unique | .[] | select( test("${{ env.EXCLUDE_FILTER }}") | not ) ]'`
|
||||
echo "unityVersions=${VERSIONS}" | tee $GITHUB_OUTPUT
|
||||
|
||||
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
|
||||
matrix:
|
||||
unityVersion: ${{ fromJson(needs.setup.outputs.unityVersions) }}
|
||||
steps:
|
||||
- name: 🚚 Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: 📥 Cache library
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: Library
|
||||
key: Library-${{ matrix.unityVersion }}-${{ github.sha }}
|
||||
restore-keys: |
|
||||
Library-${{ matrix.unityVersion }}-
|
||||
Library-
|
||||
|
||||
- name: 🛠️ Build Unity Project
|
||||
uses: game-ci/unity-builder@v4
|
||||
timeout-minutes: 45
|
||||
with:
|
||||
customImage: ghcr.io/mob-sakai/unity3d:${{ matrix.unityVersion }}
|
||||
targetPlatform: StandaloneLinux64
|
||||
allowDirtyBuild: true
|
||||
customParameters: -nographics
|
||||
|
||||
- name: 🧪 Run tests
|
||||
uses: game-ci/unity-test-runner@v4
|
||||
timeout-minutes: 45
|
||||
with:
|
||||
customImage: ghcr.io/mob-sakai/unity3d:${{ matrix.unityVersion }}
|
||||
# unityVersion: ${{ matrix.unityVersion }}
|
||||
customParameters: -nographics
|
||||
checkName: ${{ matrix.unityVersion }} Test Results
|
||||
githubToken: ${{ github.token }}
|
||||
coverageOptions: "dontClear;generateHtmlReport;generateBadgeReport;pathFilters:+**/Packages/src/**;assemblyFilters:+<packages>,-*.Editor,-*.Test"
|
||||
30
.gitignore
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
# Windows
|
||||
Thumbs.db
|
||||
Desktop.ini
|
||||
/*.csproj
|
||||
/*.sln
|
||||
|
||||
# macOS
|
||||
.DS_Store
|
||||
|
||||
# Vim
|
||||
*.swp
|
||||
|
||||
# Unity
|
||||
/Logs
|
||||
/Library
|
||||
/Temp
|
||||
Assets/Plugins.meta
|
||||
Assets/JMO Assets.meta
|
||||
Assets/JMO Assets
|
||||
Assets/EffectExamples/
|
||||
Assets/EffectExamples.meta
|
||||
Assets/Plugins/
|
||||
|
||||
# VS
|
||||
.vs/
|
||||
.vscode/
|
||||
.idea/
|
||||
obj/
|
||||
bin/
|
||||
UserSettings/
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 53aa3f36032944b3fb1455e774c52396
|
||||
guid: 7c9f7735cc2f24a7ca1c23043e63a6be
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8cf8018dee45a4c42a19eec890eaa5b1
|
||||
guid: 15e5409f0334e479e91e672ae14567d3
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
5622
Assets/Demo/Cartoon FX & War FX Demo/CFX Free Demo.unity
Normal file
@@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 064daa6b97d6846ec9334e98d642f081
|
||||
DefaultImporter:
|
||||
userData:
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "Coffee.CFX_Demo_With_UIParticle",
|
||||
"references": [
|
||||
"Coffee.UIParticle"
|
||||
],
|
||||
"optionalUnityReferences": [],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": []
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 67b89587ad4f645e18aa12053a6cc9b7
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
116
Assets/Demo/Cartoon FX & War FX Demo/CFX_Demo_With_UIParticle.cs
Normal file
@@ -0,0 +1,116 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
using UnityEngine.UI;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace Coffee.UIExtensions.Demo
|
||||
{
|
||||
public class CFX_Demo_With_UIParticle : MonoBehaviour
|
||||
{
|
||||
private MonoBehaviour _demo;
|
||||
private string _demoType;
|
||||
private Toggle _spawnOnUI;
|
||||
private UIParticle _uiParticle;
|
||||
|
||||
// Start is called before the first frame update
|
||||
private void Start()
|
||||
{
|
||||
_uiParticle = GetComponentInChildren<UIParticle>();
|
||||
_spawnOnUI = GetComponentInChildren<Toggle>();
|
||||
_demo = FindObjectOfType("CFX_Demo_New") as MonoBehaviour
|
||||
?? FindObjectOfType("WFX_Demo_New") as MonoBehaviour
|
||||
?? FindObjectOfType("CFXR_Demo") as MonoBehaviour;
|
||||
_demoType = _demo?.GetType().Name;
|
||||
|
||||
SetCanvasWidth(800);
|
||||
SetCanvasRenderOverlay(true);
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
private void Update()
|
||||
{
|
||||
if (!_spawnOnUI.isOn || !_demo || !Input.GetMouseButtonDown(0)) return;
|
||||
|
||||
if (_demoType == "CFX_Demo_New" || _demoType == "WFX_Demo_New")
|
||||
{
|
||||
SpawnParticleCFX();
|
||||
}
|
||||
else if (_demoType == "CFXR_Demo")
|
||||
{
|
||||
SpawnParticleCFXR();
|
||||
}
|
||||
}
|
||||
|
||||
private void SpawnParticleCFXR()
|
||||
{
|
||||
var particle = _demo.GetType()
|
||||
.GetField("currentEffect", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public)
|
||||
?.GetValue(_demo) as GameObject;
|
||||
if (!particle) return;
|
||||
|
||||
var instance = Instantiate(particle);
|
||||
foreach (var c in instance.GetComponentsInChildren<MonoBehaviour>())
|
||||
{
|
||||
if (c.GetType().Name == "CFXR_Effect")
|
||||
{
|
||||
c.enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
_uiParticle.SetParticleSystemInstance(instance, true);
|
||||
}
|
||||
|
||||
private void SpawnParticleCFX()
|
||||
{
|
||||
var particle = _demo.GetType()
|
||||
.GetMethod("spawnParticle", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public)
|
||||
?.Invoke(_demo, Array.Empty<object>()) as GameObject;
|
||||
if (!particle) return;
|
||||
|
||||
particle.transform.localScale = Vector3.one;
|
||||
_uiParticle.SetParticleSystemInstance(particle, true);
|
||||
}
|
||||
|
||||
private static Object FindObjectOfType(string typeName)
|
||||
{
|
||||
var type = AppDomain.CurrentDomain.GetAssemblies()
|
||||
.SelectMany(x => x.GetTypes())
|
||||
.FirstOrDefault(x => x.Name == typeName);
|
||||
|
||||
return type == null ? null : FindObjectOfType(type);
|
||||
}
|
||||
|
||||
public void SetCanvasWidth(int width)
|
||||
{
|
||||
var scaler = GetComponentInParent<CanvasScaler>();
|
||||
scaler.screenMatchMode = CanvasScaler.ScreenMatchMode.MatchWidthOrHeight;
|
||||
scaler.matchWidthOrHeight = 0;
|
||||
var resolution = scaler.referenceResolution;
|
||||
resolution.x = width;
|
||||
scaler.referenceResolution = resolution;
|
||||
}
|
||||
|
||||
public void SetCanvasRenderOverlay(bool enable)
|
||||
{
|
||||
var canvas = GetComponentInParent<Canvas>();
|
||||
if (enable)
|
||||
{
|
||||
canvas.renderMode = RenderMode.ScreenSpaceOverlay;
|
||||
}
|
||||
else
|
||||
{
|
||||
canvas.worldCamera = Camera.main;
|
||||
canvas.renderMode = RenderMode.ScreenSpaceCamera;
|
||||
canvas.planeDistance = 5;
|
||||
}
|
||||
}
|
||||
|
||||
public void LoadScene(string scene)
|
||||
{
|
||||
SceneManager.LoadScene(scene);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8455ee485a5ee4cacbdf558f66af65fb
|
||||
guid: a845100b226da488ab9037ad254b5860
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
4044
Assets/Demo/Cartoon FX & War FX Demo/ParticleEffectForUGUI.prefab
Normal file
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3432d66abba624d4fad1150154199656
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
4
Assets/Demo/Cartoon FX & War FX Demo/README.md
Normal file
@@ -0,0 +1,4 @@
|
||||
Cartoon FX & War FX Demo
|
||||
===
|
||||
|
||||
Please import assets "Cartoon FX Free" and/or "War FX Free" from Unity asset store.
|
||||
7
Assets/Demo/Cartoon FX & War FX Demo/README.md.meta
Normal file
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8f3407e8e4c3c4cf0a8717c25bc1c790
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1b2877595f27c4a70a426991d515434f
|
||||
guid: ca0fd7c7ead2c49b1ae139b7963de126
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 66c42f0f30de84ca4bd8305a1188af85
|
||||
guid: 839afb79f79094e6c942050ec5413ebf
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
@@ -0,0 +1,88 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 6
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: UIParticle_PerformanceDemo_Fire
|
||||
m_Shader: {fileID: 4800000, guid: ecfa8f5732b504ef98fba10aa18d0326, type: 3}
|
||||
m_ShaderKeywords:
|
||||
m_LightmapFlags: 4
|
||||
m_EnableInstancingVariants: 0
|
||||
m_DoubleSidedGI: 0
|
||||
m_CustomRenderQueue: -1
|
||||
stringTagMap: {}
|
||||
disabledShaderPasses: []
|
||||
m_SavedProperties:
|
||||
serializedVersion: 3
|
||||
m_TexEnvs:
|
||||
- _BumpMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailAlbedoMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailMask:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailNormalMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _EmissionMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MainTex:
|
||||
m_Texture: {fileID: 2800000, guid: 294c5667b05cc4edcac3885a5899cc65, type: 3}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MetallicGlossMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _OcclusionMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _ParallaxMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_Floats:
|
||||
- _BumpScale: 1
|
||||
- _ColorMask: 15
|
||||
- _Cutoff: 0.5
|
||||
- _DetailNormalMapScale: 1
|
||||
- _DstBlend: 0
|
||||
- _GlossMapScale: 1
|
||||
- _Glossiness: 0.5
|
||||
- _GlossyReflections: 1
|
||||
- _Glow: 1
|
||||
- _InvFade: 1
|
||||
- _Metallic: 0
|
||||
- _Mode: 0
|
||||
- _OcclusionStrength: 1
|
||||
- _Parallax: 0.02
|
||||
- _SmoothnessTextureChannel: 0
|
||||
- _SpecularHighlights: 1
|
||||
- _SrcBlend: 1
|
||||
- _Stencil: 0
|
||||
- _StencilComp: 8
|
||||
- _StencilOp: 0
|
||||
- _StencilReadMask: 255
|
||||
- _StencilWriteMask: 255
|
||||
- _UVSec: 0
|
||||
- _UseUIAlphaClip: 0
|
||||
- _ZWrite: 1
|
||||
m_Colors:
|
||||
- _ClipRect: {r: -32767, g: -32767, b: 32767, a: 32767}
|
||||
- _Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
|
||||
- _TintColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3dc66b79cada243e59bcaf09f804373d
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 2100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
Before Width: | Height: | Size: 585 KiB After Width: | Height: | Size: 585 KiB |
@@ -0,0 +1,121 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 294c5667b05cc4edcac3885a5899cc65
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
externalObjects: {}
|
||||
serializedVersion: 9
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 1
|
||||
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
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: 2
|
||||
aniso: 16
|
||||
mipBias: -100
|
||||
wrapU: -1
|
||||
wrapV: -1
|
||||
wrapW: -1
|
||||
nPOTScale: 1
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
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: 0
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 0
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 2
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 4096
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 2
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- serializedVersion: 2
|
||||
buildTarget: Standalone
|
||||
maxTextureSize: 4096
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 2
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- serializedVersion: 2
|
||||
buildTarget: Android
|
||||
maxTextureSize: 4096
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 2
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- serializedVersion: 2
|
||||
buildTarget: WebGL
|
||||
maxTextureSize: 4096
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 2
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID:
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
spritePackingTag:
|
||||
pSDRemoveMatte: 0
|
||||
pSDShowRemoveMatteOption: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,88 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 6
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: UIParticle_PerformanceDemo_Spread
|
||||
m_Shader: {fileID: 4800000, guid: ecfa8f5732b504ef98fba10aa18d0326, type: 3}
|
||||
m_ShaderKeywords:
|
||||
m_LightmapFlags: 4
|
||||
m_EnableInstancingVariants: 0
|
||||
m_DoubleSidedGI: 0
|
||||
m_CustomRenderQueue: -1
|
||||
stringTagMap: {}
|
||||
disabledShaderPasses: []
|
||||
m_SavedProperties:
|
||||
serializedVersion: 3
|
||||
m_TexEnvs:
|
||||
- _BumpMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailAlbedoMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailMask:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailNormalMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _EmissionMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MainTex:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MetallicGlossMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _OcclusionMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _ParallaxMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_Floats:
|
||||
- _BumpScale: 1
|
||||
- _ColorMask: 15
|
||||
- _Cutoff: 0.5
|
||||
- _DetailNormalMapScale: 1
|
||||
- _DstBlend: 0
|
||||
- _GlossMapScale: 1
|
||||
- _Glossiness: 0.5
|
||||
- _GlossyReflections: 1
|
||||
- _Glow: 1
|
||||
- _InvFade: 1
|
||||
- _Metallic: 0
|
||||
- _Mode: 0
|
||||
- _OcclusionStrength: 1
|
||||
- _Parallax: 0.02
|
||||
- _SmoothnessTextureChannel: 0
|
||||
- _SpecularHighlights: 1
|
||||
- _SrcBlend: 1
|
||||
- _Stencil: 0
|
||||
- _StencilComp: 8
|
||||
- _StencilOp: 0
|
||||
- _StencilReadMask: 255
|
||||
- _StencilWriteMask: 255
|
||||
- _UVSec: 0
|
||||
- _UseUIAlphaClip: 0
|
||||
- _ZWrite: 1
|
||||
m_Colors:
|
||||
- _ClipRect: {r: -32767, g: -32767, b: 32767, a: 32767}
|
||||
- _Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
|
||||
- _TintColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b7ac7640c2f1047c887aa52ff1ce9fcc
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 2100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/Demo/Performance Demo/Scripts.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: db256ad6e34f94a4a95dedcbce09ddf1
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "Coffee.UIParticle.PerformanceDemo",
|
||||
"references": [
|
||||
"Coffee.UIParticle"
|
||||
],
|
||||
"optionalUnityReferences": [],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": false,
|
||||
"defineConstraints": []
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9c1a1a5e813ba46d2b837936f34e33a7
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,84 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.Serialization;
|
||||
|
||||
namespace Coffee.UIExtensions.Demo
|
||||
{
|
||||
public class UIParticle_PerformanceDemo : MonoBehaviour
|
||||
{
|
||||
[FormerlySerializedAs("copyOrigin")]
|
||||
[SerializeField]
|
||||
private GameObject m_CopyOrigin;
|
||||
|
||||
[FormerlySerializedAs("copyCount")]
|
||||
[SerializeField]
|
||||
public int m_CopyCount;
|
||||
|
||||
[FormerlySerializedAs("root")]
|
||||
[SerializeField]
|
||||
public Canvas m_RootCanvas;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
Application.targetFrameRate = 60;
|
||||
|
||||
if (m_CopyOrigin)
|
||||
{
|
||||
m_CopyOrigin.SetActive(false);
|
||||
|
||||
var parent = m_CopyOrigin.transform.parent;
|
||||
for (var i = 0; i < m_CopyCount; i++)
|
||||
{
|
||||
var go = Instantiate(m_CopyOrigin, parent, false);
|
||||
go.name = string.Format("{0} {1}", m_CopyOrigin.name, i + 1);
|
||||
go.hideFlags = HideFlags.DontSave;
|
||||
|
||||
go.SetActive(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void UIParticle_Enable(bool flag)
|
||||
{
|
||||
foreach (var uip in m_RootCanvas.GetComponentsInChildren<UIParticle>(true))
|
||||
{
|
||||
uip.enabled = flag;
|
||||
}
|
||||
|
||||
if (!flag)
|
||||
{
|
||||
foreach (var ps in FindObjectsOfType<ParticleSystem>())
|
||||
{
|
||||
ps.Play(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void UIParticle_MeshSharing(bool flag)
|
||||
{
|
||||
foreach (var uip in m_RootCanvas.GetComponentsInChildren<UIParticle>(true))
|
||||
{
|
||||
uip.meshSharing = flag
|
||||
? UIParticle.MeshSharing.Auto
|
||||
: UIParticle.MeshSharing.None;
|
||||
}
|
||||
}
|
||||
|
||||
public void UIParticle_RandomGroup(bool flag)
|
||||
{
|
||||
foreach (var uip in m_RootCanvas.GetComponentsInChildren<UIParticle>(true))
|
||||
{
|
||||
uip.groupMaxId = flag
|
||||
? 4
|
||||
: 0;
|
||||
}
|
||||
}
|
||||
|
||||
public void ParticleSystem_SetScale(float scale)
|
||||
{
|
||||
foreach (var ps in FindObjectsOfType<ParticleSystem>())
|
||||
{
|
||||
ps.transform.localScale = new Vector3(scale, scale, scale);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a7a2e11131111447cb7fc0394a14da65
|
||||
guid: 3a595cf9cf93f4e0686f247a5e7e19ce
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
8
Assets/Demo/Performance Demo/Sprites.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: aacefbb114f024ec0bd6d3153b28bb36
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
@@ -0,0 +1,132 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fc4e1d816001842709cf8a393c69dd14
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
externalObjects: {}
|
||||
serializedVersion: 9
|
||||
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
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: -1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: -1
|
||||
aniso: -1
|
||||
mipBias: -100
|
||||
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: 8
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 2
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- serializedVersion: 2
|
||||
buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- serializedVersion: 2
|
||||
buildTarget: iPhone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- serializedVersion: 2
|
||||
buildTarget: Android
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- serializedVersion: 2
|
||||
buildTarget: WebGL
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID: de8a1691f8aae4be18d66008040aa1a7
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
spritePackingTag:
|
||||
pSDRemoveMatte: 0
|
||||
pSDShowRemoveMatteOption: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
@@ -0,0 +1,88 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9b9aa386e19cb4bf4b7e055e962419e2
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
externalObjects: {}
|
||||
serializedVersion: 9
|
||||
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
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: -1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: 0
|
||||
aniso: 16
|
||||
mipBias: -100
|
||||
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: 8
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 2
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID: 84e9fd7e25cf94cfc81bd77bc4f1d566
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
spritePackingTag:
|
||||
pSDRemoveMatte: 0
|
||||
pSDShowRemoveMatteOption: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
3420
Assets/Demo/Performance Demo/UIParticle_PerformanceDemo.unity
Normal file
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 870ee15d24ba04925bce26ece2edb10e
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a4669dfbba654429bbcddf0c9b79fb8b
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 398e06c9985ad4291a95f0749c2927fb
|
||||
guid: 64db617a76e9a4f1e90d0731175c1f7b
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
33
Assets/ProjectSettings/NanoMonitor.asset
Normal file
@@ -0,0 +1,33 @@
|
||||
%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: 194d2f2eb25c64ec0af5c323c74eb518, type: 3}
|
||||
m_Name: NanoMonitor
|
||||
m_EditorClassIdentifier:
|
||||
m_NanoMonitorEnabled: 1
|
||||
m_BootSceneNameRegex: .*
|
||||
m_DevelopmentBuildOnly: 1
|
||||
m_EnabledInEditor: 1
|
||||
m_AlwaysIncludeAssembly: 1
|
||||
m_InstantiateOnLoad: 1
|
||||
m_Prefab: {fileID: 7211429669315726685, guid: b73940fc30a2f4eb9a73783e9c1f8da6,
|
||||
type: 3}
|
||||
m_Opened: 1
|
||||
m_Interval: 0.5
|
||||
m_Anchor: 1
|
||||
m_CustomMonitorItems:
|
||||
- m_Format: Screen:{0}x{1}
|
||||
m_Arg0:
|
||||
m_Path: UnityEngine.Screen, UnityEngine.CoreModule;width
|
||||
m_Arg1:
|
||||
m_Path: UnityEngine.Screen, UnityEngine.CoreModule;height
|
||||
m_Arg2:
|
||||
m_Path:
|
||||
8
Assets/ProjectSettings/NanoMonitor.asset.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 86087a0847f384b538391745dad4565c
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
1555
Assets/ProjectSettings/NanoMonitor.prefab
Normal file
7
Assets/ProjectSettings/NanoMonitor.prefab.meta
Normal file
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b73940fc30a2f4eb9a73783e9c1f8da6
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
20
Assets/ProjectSettings/SimpleSceneNavigator.asset
Normal file
@@ -0,0 +1,20 @@
|
||||
%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}
|
||||
8
Assets/ProjectSettings/SimpleSceneNavigator.asset.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: be3e05903ef7041d39b3ef8ecdd47f08
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
513
Assets/ProjectSettings/SimpleSceneNavigator.prefab
Normal file
@@ -0,0 +1,513 @@
|
||||
%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: <<
|
||||
7
Assets/ProjectSettings/SimpleSceneNavigator.prefab.meta
Normal file
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 46deb9632f6a14713b8460bd01e879c9
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
1
Assets/Samples
Symbolic link
@@ -0,0 +1 @@
|
||||
../Packages/src/Samples~
|
||||
8
Assets/Samples.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2132c9464acf94912a959f8cc6a68fa6
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/Tests.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 57d832714402a4bc5a0ed550741823ad
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
16
Assets/Tests/Coffee.UIParticle.Tests.asmdef
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"name": "Coffee.UIParticle.Tests",
|
||||
"references": [
|
||||
"Coffee.UIParticle"
|
||||
],
|
||||
"optionalUnityReferences": [
|
||||
"TestAssemblies"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": false,
|
||||
"defineConstraints": []
|
||||
}
|
||||
7
Assets/Tests/Coffee.UIParticle.Tests.asmdef.meta
Normal file
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0253956e76ec342d49f1377578eb86be
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/Tests/Editor.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c49dbc815ad044a919bd5b7d4e6c59cf
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
19
Assets/Tests/Editor/Coffee.UIParticle.Editor.Tests.asmdef
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "Coffee.UIParticle.Editor.Tests",
|
||||
"references": [
|
||||
"Coffee.UIParticle",
|
||||
"Coffee.UIParticle.Editor"
|
||||
],
|
||||
"optionalUnityReferences": [
|
||||
"TestAssemblies"
|
||||
],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": false,
|
||||
"defineConstraints": []
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 78daa55fa55814a33a3377d6ede8c43d
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
26
Assets/Tests/Editor/NewTestScript.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
using System.Collections;
|
||||
using NUnit.Framework;
|
||||
using UnityEngine.TestTools;
|
||||
|
||||
namespace Coffee.UIParticle.Editor.Tests
|
||||
{
|
||||
public class NewTestScript
|
||||
{
|
||||
// A Test behaves as an ordinary method
|
||||
[Test]
|
||||
public void NewTestScriptSimplePasses()
|
||||
{
|
||||
// Use the Assert class to test conditions
|
||||
}
|
||||
|
||||
// A UnityTest behaves like a coroutine in Play Mode. In Edit Mode you can use
|
||||
// `yield return null;` to skip a frame.
|
||||
[UnityTest]
|
||||
public IEnumerator NewTestScriptWithEnumeratorPasses()
|
||||
{
|
||||
// Use the Assert class to test conditions.
|
||||
// Use yield to skip a frame.
|
||||
yield return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9dd767b8c0f95478386e7d5079cd44df
|
||||
guid: 5623180b85e024006b9a6772c3f241c5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
26
Assets/Tests/NewTestScript.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
using System.Collections;
|
||||
using NUnit.Framework;
|
||||
using UnityEngine.TestTools;
|
||||
|
||||
namespace Coffee.UIParticle.Tests
|
||||
{
|
||||
public class NewTestScript
|
||||
{
|
||||
// A Test behaves as an ordinary method
|
||||
[Test]
|
||||
public void NewTestScriptSimplePasses()
|
||||
{
|
||||
// Use the Assert class to test conditions
|
||||
}
|
||||
|
||||
// A UnityTest behaves like a coroutine in Play Mode. In Edit Mode you can use
|
||||
// `yield return null;` to skip a frame.
|
||||
[UnityTest]
|
||||
public IEnumerator NewTestScriptWithEnumeratorPasses()
|
||||
{
|
||||
// Use the Assert class to test conditions.
|
||||
// Use yield to skip a frame.
|
||||
yield return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0ef431b9df32c410ea5fa46be81def6b
|
||||
guid: d52f7d64d782c421284267dd1c197210
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
8
Packages/manifest.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"com.unity.ide.rider": "3.0.27",
|
||||
"com.unity.test-framework": "1.1.33",
|
||||
"com.unity.modules.animation": "1.0.0",
|
||||
"com.unity.modules.physics": "1.0.0"
|
||||
}
|
||||
}
|
||||
85
Packages/packages-lock.json
Normal file
@@ -0,0 +1,85 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"com.coffee.ui-particle": {
|
||||
"version": "file:src",
|
||||
"depth": 0,
|
||||
"source": "embedded",
|
||||
"dependencies": {
|
||||
"com.unity.ugui": "1.0.0",
|
||||
"com.unity.modules.particlesystem": "1.0.0"
|
||||
}
|
||||
},
|
||||
"com.unity.ext.nunit": {
|
||||
"version": "1.0.6",
|
||||
"depth": 1,
|
||||
"source": "registry",
|
||||
"dependencies": {},
|
||||
"url": "https://packages.unity.com"
|
||||
},
|
||||
"com.unity.ide.rider": {
|
||||
"version": "3.0.27",
|
||||
"depth": 0,
|
||||
"source": "registry",
|
||||
"dependencies": {
|
||||
"com.unity.ext.nunit": "1.0.6"
|
||||
},
|
||||
"url": "https://packages.unity.com"
|
||||
},
|
||||
"com.unity.test-framework": {
|
||||
"version": "1.1.33",
|
||||
"depth": 0,
|
||||
"source": "registry",
|
||||
"dependencies": {
|
||||
"com.unity.ext.nunit": "1.0.6",
|
||||
"com.unity.modules.imgui": "1.0.0",
|
||||
"com.unity.modules.jsonserialize": "1.0.0"
|
||||
},
|
||||
"url": "https://packages.unity.com"
|
||||
},
|
||||
"com.unity.ugui": {
|
||||
"version": "1.0.0",
|
||||
"depth": 1,
|
||||
"source": "builtin",
|
||||
"dependencies": {
|
||||
"com.unity.modules.ui": "1.0.0",
|
||||
"com.unity.modules.imgui": "1.0.0"
|
||||
}
|
||||
},
|
||||
"com.unity.modules.animation": {
|
||||
"version": "1.0.0",
|
||||
"depth": 0,
|
||||
"source": "builtin",
|
||||
"dependencies": {}
|
||||
},
|
||||
"com.unity.modules.imgui": {
|
||||
"version": "1.0.0",
|
||||
"depth": 1,
|
||||
"source": "builtin",
|
||||
"dependencies": {}
|
||||
},
|
||||
"com.unity.modules.jsonserialize": {
|
||||
"version": "1.0.0",
|
||||
"depth": 1,
|
||||
"source": "builtin",
|
||||
"dependencies": {}
|
||||
},
|
||||
"com.unity.modules.particlesystem": {
|
||||
"version": "1.0.0",
|
||||
"depth": 1,
|
||||
"source": "builtin",
|
||||
"dependencies": {}
|
||||
},
|
||||
"com.unity.modules.physics": {
|
||||
"version": "1.0.0",
|
||||
"depth": 0,
|
||||
"source": "builtin",
|
||||
"dependencies": {}
|
||||
},
|
||||
"com.unity.modules.ui": {
|
||||
"version": "1.0.0",
|
||||
"depth": 2,
|
||||
"source": "builtin",
|
||||
"dependencies": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,7 @@
|
||||
"release-4.x",
|
||||
{
|
||||
"name": "release-preview",
|
||||
"prerelease": "preview"
|
||||
"prerelease": true
|
||||
}
|
||||
],
|
||||
"plugins": [
|
||||
@@ -1,192 +1,3 @@
|
||||
# [4.12.0](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.11.4...v4.12.0) (2026-03-24)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* explicit null checks ([5384f61](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/5384f61c569e9f78ff9d5b45acfc6f5c2f021a87))
|
||||
|
||||
## [4.11.4](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.11.3...v4.11.4) (2025-12-24)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* add early return for case where subEmitter module is disabled ([d1386a1](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/d1386a12216743a6e09f1b9b87bea1dfcf7702e4))
|
||||
* avoid endless loop ([eb2e862](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/eb2e862e80e549c8cf16ddfed776c101c2413bac)), closes [#392](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/392)
|
||||
|
||||
## [4.11.3](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.11.2...v4.11.3) (2025-10-14)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* fix icon ([a9461ec](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/a9461ecb4d40d7fe878e12465d6e38faae7ae65b))
|
||||
* fix URL link in README ([1c8c65d](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/1c8c65d25e7f6fe7b1d20da4461333df8fc7578e)), closes [#376](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/376)
|
||||
* fix: second and subsequent bursts not displayed when world simulation and non-looping ([df2f3ca](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/df2f3caafbe279f1457d74f8183cb561ac14aa17)), closes [#326](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/326)
|
||||
* UIParticle in canvas with 0f-0.01f alpha value does not start to play until alpha value is greater than 0.01f, causes play calls to be delayed unintentionally if canvas alpha value is set to mentioned value range ([38aec2e](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/38aec2ea1afd77677d629c86665a3342d92e49d9))
|
||||
|
||||
## [4.11.2](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.11.1...v4.11.2) (2025-03-15)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* IL2CPP build fails on older versions of Unity ([0da6525](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/0da652520cd165b43de7404c0b0ab1fbcf9349d1))
|
||||
* NRE on enable ([0cff50e](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/0cff50ef696aa53fb7c46a9a737b7cf3a05b7b9b)), closes [#359](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/359)
|
||||
|
||||
## [4.11.1](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.11.0...v4.11.1) (2025-02-21)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* component icons will no longer be displayed in the scene view ([6dfbdae](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/6dfbdae38d3822ab9c2c6f0e4ca1ca32ee98a239))
|
||||
|
||||
# [4.11.0](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.10.7...v4.11.0) (2025-02-21)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add 'TimeScaleMultiplier' option ([925af0b](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/925af0b6046f65f23a778f67cefa8ff9cbedb513))
|
||||
|
||||
## [4.10.7](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.10.6...v4.10.7) (2025-01-14)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* editor crashed on exit play mode (editor, windows) ([47ee45c](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/47ee45cbbe651a8f87ca2b8a3948f8b88db8211e)), closes [#351](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/351)
|
||||
|
||||
## [4.10.6](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.10.5...v4.10.6) (2025-01-03)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* sub-emitter particles may not render correctly in certain scenarios ([8276684](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/8276684c3b1646f0490ed64557547ba15281664a)), closes [#348](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/348)
|
||||
* sub-emitter's `inherit velocity` module doubles at runtime ([67de3d1](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/67de3d1bd3e16dc9b564625cb990c53d75769506)), closes [#349](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/349)
|
||||
|
||||
## [4.10.5](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.10.4...v4.10.5) (2024-12-23)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* '3D' scale toggle in the inspector does not keep on reload ([934f4b8](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/934f4b8f1c61f8ff20228d0ebcea9f636a3758ed)), closes [#346](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/346)
|
||||
|
||||
## [4.10.4](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.10.3...v4.10.4) (2024-12-19)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* rendering issues when playing with opening a prefab stage ([95235a9](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/95235a929b82cf681365ed6eba837d857f83e3d2)), closes [#345](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/345)
|
||||
|
||||
## [4.10.3](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.10.2...v4.10.3) (2024-11-20)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* if not configured as a preloaded asset, the project settings asset will be regenerated ([abe0948](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/abe09485f65dd4efd18e74675e752e0213bdf3be)), closes [#342](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/342)
|
||||
|
||||
## [4.10.2](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.10.1...v4.10.2) (2024-11-01)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* trail incorrect offset ([afe00a1](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/afe00a1dde80eb1c0a7bb668b75f4c3733d3fa43)), closes [#335](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/335)
|
||||
|
||||
## [4.10.1](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.10.0...v4.10.1) (2024-09-29)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* mainTex will be ignored ([2ee69d0](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/2ee69d04245fabce185f67dc9bd68c870e556564))
|
||||
|
||||
# [4.10.0](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.9.1...v4.10.0) (2024-09-29)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* component icon is not set ([5ff6ec8](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/5ff6ec815a174de5d3f16d424f1204c60912a8d8))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add project settings ([1ce4e31](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/1ce4e31a9681bf1a201d2723c8d97e07ecc16592))
|
||||
|
||||
## [4.9.1](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.9.0...v4.9.1) (2024-08-07)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* ParticleSystem trails gain offset on parent canvas change ([2a1cd50](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/2a1cd502b452b5b56edf8bcfe91adf99d1bb5147)), closes [#323](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/323)
|
||||
|
||||
# [4.9.0](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.8.1...v4.9.0) (2024-07-18)
|
||||
|
||||
|
||||
### 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.Append(b);
|
||||
return s_Sb.Append(", ");
|
||||
});
|
||||
result.Aggregate(s_Sb, (a, b) => s_Sb.AppendFormat("{0}, ", b));
|
||||
s_Sb.Length -= 2;
|
||||
}
|
||||
|
||||
return s_Sb.ToString();
|
||||
}
|
||||
|
||||
public static void Draw(SerializedProperty sp, List<Material> mats)
|
||||
public static void Draw(SerializedProperty sp, Material[] mats)
|
||||
{
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
if (!GUI.Button(rect, text, EditorStyles.popup)) return;
|
||||
if (!isClicked) return;
|
||||
|
||||
var gm = new GenericMenu();
|
||||
gm.AddItem(s_ContentNothing, s_ActiveNames.Count == 0, x =>
|
||||
gm.AddItem(s_ContentNothing, s_ActiveNames.Count == 0, () =>
|
||||
{
|
||||
var current = (SerializedProperty)x;
|
||||
current.ClearArray();
|
||||
current.serializedObject.ApplyModifiedProperties();
|
||||
}, sp);
|
||||
sp.ClearArray();
|
||||
sp.serializedObject.ApplyModifiedProperties();
|
||||
});
|
||||
|
||||
if (!sp.hasMultipleDifferentValues)
|
||||
{
|
||||
@@ -73,16 +73,17 @@ namespace Coffee.UIExtensions
|
||||
}
|
||||
|
||||
s_Names.Clear();
|
||||
for (var j = 0; j < mats.Count; j++)
|
||||
for (var j = 0; j < mats.Length; j++)
|
||||
{
|
||||
var mat = mats[j];
|
||||
if (mat == null || mat.shader == null) continue;
|
||||
if (!mat || !mat.shader) continue;
|
||||
|
||||
for (var i = 0; i < ShaderUtil.GetPropertyCount(mat.shader); i++)
|
||||
{
|
||||
var name = ShaderUtil.GetPropertyName(mat.shader, i);
|
||||
var type = (AnimatableProperty.ShaderPropertyType)ShaderUtil.GetPropertyType(mat.shader, i);
|
||||
if (!s_Names.Add(name)) continue;
|
||||
if (s_Names.Contains(name)) continue;
|
||||
s_Names.Add(name);
|
||||
|
||||
AddMenu(gm, sp, new ShaderProperty(name, type), true);
|
||||
|
||||
@@ -5,9 +5,8 @@ using UnityEditor;
|
||||
using UnityEditor.UI;
|
||||
using UnityEditorInternal;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Profiling;
|
||||
using UnityEngine.UI;
|
||||
using Coffee.UIParticleInternal;
|
||||
using Coffee.UIParticleExtensions;
|
||||
#if UNITY_2021_2_OR_NEWER
|
||||
using UnityEditor.Overlays;
|
||||
#else
|
||||
@@ -17,7 +16,6 @@ using Object = UnityEngine.Object;
|
||||
#endif
|
||||
#if UNITY_2021_2_OR_NEWER
|
||||
using UnityEditor.SceneManagement;
|
||||
|
||||
#elif UNITY_2018_3_OR_NEWER
|
||||
using UnityEditor.Experimental.SceneManagement;
|
||||
#endif
|
||||
@@ -28,29 +26,42 @@ namespace Coffee.UIExtensions
|
||||
[CanEditMultipleObjects]
|
||||
internal class UIParticleEditor : GraphicEditor
|
||||
{
|
||||
internal class State : ScriptableSingleton<State>
|
||||
#if UNITY_2021_2_OR_NEWER
|
||||
#if UNITY_2022_1_OR_NEWER
|
||||
[Overlay(typeof(SceneView), "Scene View/UI Particles", "UI Particles", true,
|
||||
defaultDockPosition = DockPosition.Bottom,
|
||||
defaultDockZone = DockZone.Floating,
|
||||
defaultLayout = Layout.Panel)]
|
||||
#else
|
||||
[Overlay(typeof(SceneView), "Scene View/UI Particles", "UI Particles", true)]
|
||||
#endif
|
||||
private class UIParticleOverlay : IMGUIOverlay, ITransientOverlay
|
||||
{
|
||||
public bool is3DScaleMode;
|
||||
public bool visible => s_SerializedObject != null;
|
||||
|
||||
public override void OnGUI()
|
||||
{
|
||||
if (visible)
|
||||
{
|
||||
WindowFunction();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//################################
|
||||
// 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 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 static SerializedObject s_SerializedObject;
|
||||
private static bool s_XYZMode;
|
||||
|
||||
private SerializedProperty _maskable;
|
||||
private SerializedProperty _scale3D;
|
||||
@@ -60,12 +71,8 @@ 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
|
||||
@@ -81,6 +88,56 @@ namespace Coffee.UIExtensions
|
||||
"_ColorMask"
|
||||
};
|
||||
|
||||
[InitializeOnLoadMethod]
|
||||
private static void Init()
|
||||
{
|
||||
#if !UNITY_2021_2_OR_NEWER
|
||||
var miSceneViewOverlayWindow = Type.GetType("UnityEditor.SceneViewOverlay, UnityEditor")
|
||||
?.GetMethods(BindingFlags.Public | BindingFlags.Static)
|
||||
.First(x => x.Name == "Window" && 5 <= x.GetParameters().Length);
|
||||
var windowFunction = (Action<Object, SceneView>)WindowFunction;
|
||||
var windowFunctionType = Type.GetType("UnityEditor.SceneViewOverlay+WindowFunction, UnityEditor");
|
||||
var windowFunctionDelegate = Delegate.CreateDelegate(windowFunctionType, windowFunction.Method);
|
||||
var windowTitle = new GUIContent(ObjectNames.NicifyVariableName(nameof(UIParticle)));
|
||||
#if UNITY_2019_2_OR_NEWER
|
||||
//public static void Window(GUIContent title, WindowFunction sceneViewFunc, int order, Object target, WindowDisplayOption option, EditorWindow window = null)
|
||||
var sceneViewArgs = new object[] { windowTitle, windowFunctionDelegate, 599, null, 2, null };
|
||||
#else
|
||||
//public static void Window(GUIContent title, WindowFunction sceneViewFunc, int order, Object target, WindowDisplayOption option)
|
||||
var sceneViewArgs = new object[] { windowTitle, windowFunctionDelegate, 599, null, 2 };
|
||||
#endif
|
||||
|
||||
#if UNITY_2019_1_OR_NEWER
|
||||
SceneView.duringSceneGui += _ =>
|
||||
#else
|
||||
SceneView.onSceneGUIDelegate += _ =>
|
||||
#endif
|
||||
{
|
||||
if (s_SerializedObject != null)
|
||||
{
|
||||
miSceneViewOverlayWindow.Invoke(null, sceneViewArgs);
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
SerializedObject CreateSerializeObject()
|
||||
{
|
||||
var uiParticles = Selection.gameObjects.Select(x => x.GetComponent<ParticleSystem>())
|
||||
.Where(x => x)
|
||||
.Select(x => x.GetComponentInParent<UIParticle>(true))
|
||||
.Where(x => x && x.canvas)
|
||||
.Concat(Selection.gameObjects.Select(x => x.GetComponent<UIParticle>())
|
||||
.Where(x => x && x.canvas))
|
||||
.Distinct()
|
||||
.OfType<Object>()
|
||||
.ToArray();
|
||||
return 0 < uiParticles.Length ? new SerializedObject(uiParticles) : null;
|
||||
}
|
||||
|
||||
s_SerializedObject = CreateSerializeObject();
|
||||
Selection.selectionChanged += () => s_SerializedObject = CreateSerializeObject();
|
||||
}
|
||||
|
||||
//################################
|
||||
// Public/Protected Members.
|
||||
//################################
|
||||
@@ -99,44 +156,31 @@ 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)
|
||||
{
|
||||
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);
|
||||
},
|
||||
elementHeight = EditorGUIUtility.singleLineHeight * 3 + 4,
|
||||
elementHeightCallback = _ => 3 * (EditorGUIUtility.singleLineHeight + 2),
|
||||
drawElementCallback = (rect, index, _, __) =>
|
||||
{
|
||||
rect.y += 2;
|
||||
EditorGUI.BeginDisabledGroup(sp.hasMultipleDifferentValues);
|
||||
rect.y += 1;
|
||||
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 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)
|
||||
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)
|
||||
{
|
||||
materials.serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
@@ -170,18 +214,19 @@ namespace Coffee.UIExtensions
|
||||
uip.RefreshParticles(uip.particles);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize 3D scale mode.
|
||||
_is3DScaleMode = State.instance.is3DScaleMode;
|
||||
if (!_is3DScaleMode)
|
||||
private static void MaterialField(Rect rect, GUIContent label, SerializedProperty sp, int index)
|
||||
{
|
||||
if (sp == null || sp.arraySize <= index)
|
||||
{
|
||||
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;
|
||||
EditorGUI.BeginDisabledGroup(true);
|
||||
EditorGUI.ObjectField(rect, label, null, typeof(Material), true);
|
||||
EditorGUI.EndDisabledGroup();
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUI.PropertyField(rect, sp.GetArrayElementAtIndex(index), label);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -191,9 +236,8 @@ namespace Coffee.UIExtensions
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
var current = target as UIParticle;
|
||||
if (current == null) return;
|
||||
if (!current) return;
|
||||
|
||||
Profiler.BeginSample("(UIP:E) OnInspectorGUI");
|
||||
serializedObject.Update();
|
||||
|
||||
// Maskable
|
||||
@@ -201,16 +245,17 @@ namespace Coffee.UIExtensions
|
||||
|
||||
// Scale
|
||||
EditorGUI.BeginDisabledGroup(!_meshSharing.hasMultipleDifferentValues && _meshSharing.intValue == 4);
|
||||
if (DrawFloatOrVector3Field(_scale3D, _is3DScaleMode) != _is3DScaleMode)
|
||||
{
|
||||
State.instance.is3DScaleMode = _is3DScaleMode = !_is3DScaleMode;
|
||||
}
|
||||
|
||||
s_XYZMode = DrawFloatOrVector3Field(_scale3D, s_XYZMode);
|
||||
EditorGUI.EndDisabledGroup();
|
||||
|
||||
// AnimatableProperties
|
||||
current.GetMaterials(s_TempMaterials);
|
||||
AnimatablePropertyEditor.Draw(_animatableProperties, s_TempMaterials);
|
||||
var mats = current.particles
|
||||
.Where(x => x)
|
||||
.Select(x => x.GetComponent<ParticleSystemRenderer>().sharedMaterial)
|
||||
.Where(x => x)
|
||||
.ToArray();
|
||||
|
||||
AnimatablePropertyEditor.Draw(_animatableProperties, mats);
|
||||
|
||||
// Mesh sharing
|
||||
EditorGUI.BeginChangeCheck();
|
||||
@@ -218,12 +263,9 @@ namespace Coffee.UIExtensions
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
foreach (var t in targets)
|
||||
foreach (var uip in targets.OfType<UIParticle>())
|
||||
{
|
||||
if (t is UIParticle uip)
|
||||
{
|
||||
uip.ResetGroupId();
|
||||
}
|
||||
uip.ResetGroupId();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -231,32 +273,16 @@ namespace Coffee.UIExtensions
|
||||
EditorGUILayout.PropertyField(_positionMode);
|
||||
|
||||
// Auto Scaling
|
||||
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);
|
||||
DrawAutoScaling(_autoScalingMode, targets.OfType<UIParticle>());
|
||||
|
||||
// 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);
|
||||
@@ -264,10 +290,9 @@ namespace Coffee.UIExtensions
|
||||
}
|
||||
|
||||
// Non-UI built-in shader is not supported.
|
||||
Profiler.BeginSample("(UIP:E) Non-UI built-in shader is not supported.");
|
||||
foreach (var mat in s_TempMaterials)
|
||||
foreach (var mat in current.materials)
|
||||
{
|
||||
if (mat == null || mat.shader == null) continue;
|
||||
if (!mat || !mat.shader) continue;
|
||||
var shader = mat.shader;
|
||||
if (IsBuiltInObject(shader) && !shader.name.StartsWith("UI/"))
|
||||
{
|
||||
@@ -278,18 +303,15 @@ 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 s_TempMaterials)
|
||||
foreach (var mat in current.materials)
|
||||
{
|
||||
if (mat == null || mat.shader == null) continue;
|
||||
if (!mat || !mat.shader) continue;
|
||||
var shader = mat.shader;
|
||||
if (!s_Shaders.Add(shader)) continue;
|
||||
|
||||
if (s_Shaders.Contains(shader)) continue;
|
||||
s_Shaders.Add(shader);
|
||||
foreach (var propName in s_MaskablePropertyNames)
|
||||
{
|
||||
if (mat.HasProperty(propName)) continue;
|
||||
@@ -303,9 +325,7 @@ 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.";
|
||||
@@ -344,14 +364,12 @@ namespace Coffee.UIExtensions
|
||||
}
|
||||
}
|
||||
#endif
|
||||
Profiler.EndSample();
|
||||
}
|
||||
|
||||
private static bool IsBuiltInObject(Object obj)
|
||||
private bool IsBuiltInObject(Object obj)
|
||||
{
|
||||
return AssetDatabase.IsMainAsset(obj)
|
||||
&& AssetDatabase.TryGetGUIDAndLocalFileIdentifier(obj, out var guid, out long _)
|
||||
&& s_RegexBuiltInGuid.IsMatch(guid);
|
||||
return AssetDatabase.TryGetGUIDAndLocalFileIdentifier(obj, out var guid, out long _)
|
||||
&& Regex.IsMatch(guid, "^0{16}.0{15}$", RegexOptions.Compiled);
|
||||
}
|
||||
|
||||
#if UNITY_2018 || UNITY_2019
|
||||
@@ -445,7 +463,7 @@ namespace Coffee.UIExtensions
|
||||
{
|
||||
EditorGUI.BeginDisabledGroup(true);
|
||||
var obj = UIParticleUpdater.GetPrimary(spGroupId.intValue);
|
||||
EditorGUILayout.ObjectField(s_ContentPrimary, obj, typeof(UIParticle), false);
|
||||
EditorGUILayout.ObjectField("Primary", obj, typeof(UIParticle), false);
|
||||
EditorGUI.EndDisabledGroup();
|
||||
}
|
||||
|
||||
@@ -455,9 +473,54 @@ namespace Coffee.UIExtensions
|
||||
return showMax;
|
||||
}
|
||||
|
||||
private static void DrawAutoScaling(SerializedProperty prop)
|
||||
private static void DrawAutoScaling(SerializedProperty prop, IEnumerable<UIParticle> uiParticles)
|
||||
{
|
||||
var isTransformMode = prop.intValue == (int)UIParticle.AutoScalingMode.Transform;
|
||||
EditorGUI.BeginChangeCheck();
|
||||
EditorGUILayout.PropertyField(prop);
|
||||
if (!EditorGUI.EndChangeCheck() || !isTransformMode) return;
|
||||
|
||||
// on changed true->false, reset scale.
|
||||
EditorApplication.delayCall += () =>
|
||||
{
|
||||
foreach (var uip in uiParticles)
|
||||
{
|
||||
if (!uip) continue;
|
||||
uip.transform.localScale = Vector3.one;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#if UNITY_2021_2_OR_NEWER
|
||||
private static void WindowFunction()
|
||||
#else
|
||||
private static void WindowFunction(Object _, SceneView __)
|
||||
#endif
|
||||
{
|
||||
try
|
||||
{
|
||||
if (s_SerializedObject == null || !s_SerializedObject.targetObject) return;
|
||||
var uiParticles = s_SerializedObject.targetObjects.OfType<UIParticle>().ToArray();
|
||||
if (uiParticles.Any(x => !x || !x.canvas)) return;
|
||||
|
||||
s_SerializedObject.Update();
|
||||
using (new EditorGUILayout.VerticalScope(GUILayout.Width(220f)))
|
||||
{
|
||||
var labelWidth = EditorGUIUtility.labelWidth;
|
||||
EditorGUIUtility.labelWidth = 100;
|
||||
EditorGUILayout.PropertyField(s_SerializedObject.FindProperty("m_Enabled"));
|
||||
s_XYZMode = DrawFloatOrVector3Field(s_SerializedObject.FindProperty("m_Scale3D"), s_XYZMode);
|
||||
EditorGUILayout.PropertyField(s_SerializedObject.FindProperty("m_PositionMode"));
|
||||
DrawAutoScaling(s_SerializedObject.FindProperty("m_AutoScalingMode"), uiParticles);
|
||||
EditorGUIUtility.labelWidth = labelWidth;
|
||||
}
|
||||
|
||||
s_SerializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
|
||||
private void DestroyUIParticle(UIParticle p, bool ignoreCurrent = false)
|
||||
8
Packages/src/Icons.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7a55e246f37df405bac88eac692e3a86
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
Before Width: | Height: | Size: 418 B After Width: | Height: | Size: 418 B |
@@ -1,4 +1,4 @@
|
||||
Copyright 2018-2024 mob-sakai
|
||||
Copyright 2018-2023 mob-sakai
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
483
Packages/src/README.md
Normal file
@@ -0,0 +1,483 @@
|
||||
# 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.
|
||||
|
||||
[](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)
|
||||

|
||||

|
||||
[](http://makeapullrequest.com)
|
||||
[](https://twitter.com/intent/follow?screen_name=mob_sakai)
|
||||
|
||||
<< [📝 Description](#-description) | [🎮 Demo](#-demo) | [⚙ Installation](#-installation) | [🚀 Usage](#-usage) | [🛠 Development Note](#-development-note) | [🤝 Contributing](#-contributing) >>
|
||||
|
||||
<br><br>
|
||||
|
||||
## 📝 Description
|
||||
|
||||

|
||||
|
||||
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.
|
||||
|
||||
### Features
|
||||
|
||||
* 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]
|
||||
|
||||
[AnimatableProperty.gif]: https://user-images.githubusercontent.com/12690315/53286323-2d94a980-37b0-11e9-8afb-c4a207805ff2.gif
|
||||
|
||||
[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
|
||||
|
||||
<br><br>
|
||||
|
||||
## 🎮 Demo
|
||||
|
||||
* [WebGL Demo](https://mob-sakai.github.io/demos/UIParticle_Demo/index.html)
|
||||
|
||||
> 
|
||||
|
||||
* [WebGL Demo (Cartoon FX & War FX)](https://mob-sakai.github.io/Demos/ParticleEffectForUGUI_CFX)
|
||||
* [Cartoon FX Free][CFX] & [War FX][WFX] (by [Jean Moreno (JMO)][JMO]) with UIParticle
|
||||
|
||||
> 
|
||||
|
||||
[CFX]: https://assetstore.unity.com/packages/vfx/particles/cartoon-fx-free-109565
|
||||
|
||||
[WFX]: https://assetstore.unity.com/packages/vfx/particles/war-fx-5669
|
||||
|
||||
[JMO]: https://assetstore.unity.com/publishers/1669
|
||||
|
||||
|
||||
<br><br>
|
||||
|
||||
## ⚙ Installation
|
||||
|
||||
_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.
|
||||
|
||||
If you have [openupm-cli](https://github.com/openupm/openupm-cli) installed, then run the following command in your
|
||||
project's directory:
|
||||
|
||||
```sh
|
||||
openupm add com.coffee.ui-particle
|
||||
```
|
||||
|
||||
#### Install via UPM (using Git URL)
|
||||
|
||||
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",
|
||||
...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
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.6.0",`
|
||||
|
||||
Or, use [UpmGitExtension](https://github.com/mob-sakai/UpmGitExtension) to install and update the package.
|
||||
|
||||
<br><br>
|
||||
|
||||
## 🚀 Usage
|
||||
|
||||
### UIParticle Component
|
||||
|
||||
`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.
|
||||
- **Animatable Properties**: If you want to update material properties (e.g., `_MainTex_ST`, `_Color`) in AnimationClip,
|
||||
use this to mark the changes.
|
||||
- **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.
|
||||
- **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`.
|
||||
- **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
|
||||
and z-position.
|
||||
|
||||
<br><br>
|
||||
|
||||
#### Basic Usage
|
||||
|
||||
1. Select `GameObject/UI/ParticleSystem` to create UIParticle with a ParticleSystem.
|
||||

|
||||
2. Adjust the ParticleSystem as you like.
|
||||

|
||||
|
||||
<br>
|
||||
|
||||
#### With Your Existing ParticleSystem Prefab
|
||||
|
||||
1. Select `GameObject/UI/ParticleSystem (Empty)` to create UIParticle.
|
||||

|
||||
2. Drag and drop your ParticleSystem prefab onto UIParticle.
|
||||

|
||||
|
||||
<br>
|
||||
|
||||
#### 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)
|
||||
section.
|
||||
|
||||

|
||||
|
||||
<br><br>
|
||||
|
||||
### Script usage
|
||||
|
||||
```cs
|
||||
// Instant ParticleSystem prefab with UIParticle on runtime.
|
||||
var go = GameObject.Instantiate(prefab);
|
||||
var uiParticle = go.AddComponent<UIParticle>();
|
||||
|
||||
// Control by ParticleSystem.
|
||||
particleSystem.Play();
|
||||
particleSystem.Emit(10);
|
||||
|
||||
// Control by UIParticle.
|
||||
uiParticle.Play();
|
||||
uiParticle.Stop();
|
||||
```
|
||||
|
||||
<br><br>
|
||||
|
||||
### UIParticleAttractor component
|
||||
|
||||
`UIParticleAttractor` attracts particles generated by the specified ParticleSystem.
|
||||
|
||||

|
||||

|
||||
|
||||
- **Particle System**: Attracts particles generated by the specified particle system.
|
||||
- **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.
|
||||
- **Max Speed**: Maximum speed of attracting. If this value is too small, attracting may not be completed by the end of
|
||||
the lifetime, and `OnAttracted` may not be called.
|
||||
- **Movement**: Attracting movement type. (`Linear`, `Smooth`, `Sphere`)
|
||||
- **Update Mode**: Update mode.
|
||||
- **Normal:** Update with scaled delta time.
|
||||
- **Unscaled Time:** Update with unscaled delta time.
|
||||
- **OnAttracted**: An event called when attracting is complete (per particle).
|
||||
|
||||
<br><br>
|
||||
|
||||
## 🛠 Development Note
|
||||
|
||||
### Compares the Baking mesh approach with the conventional approach
|
||||
|
||||
- **Baking mesh approach (=UIParticle)**
|
||||

|
||||
- ✅ Rendered as is.
|
||||
- ✅ Maskable.
|
||||
- ✅ Sortable.
|
||||
- ✅ Less objects.
|
||||
|
||||
- **Do nothing (=Plain ParticleSystem)**
|
||||

|
||||
- ✅ Rendered as is.
|
||||
- ❌ Looks like a glitch.
|
||||
- ❌ Not maskable.
|
||||
- ❌ Not sortable.
|
||||
|
||||
- **Convert particle to UIVertex (=[UIParticleSystem][UIParticleSystem])**
|
||||

|
||||
- ✅ Maskable.
|
||||
- ✅ Sortable.
|
||||
- ❌ Adjustment is difficult.
|
||||
- ❌ Requires UI shaders.
|
||||
- ❌ Difficult to adjust scale.
|
||||
- ❌ Force hierarchy scalling.
|
||||
- ❌ Simulation results are incorrect.
|
||||
- ❌ Trail, rotation of transform, time scaling are not supported.
|
||||
- ❌ Generate heavy GC every frame.
|
||||
|
||||
- **Use Canvas to sort (Sorting By Canvas )**
|
||||

|
||||
- ✅ Rendered as is.
|
||||
- ✅ Sortable.
|
||||
- ❌ You must to manage sorting orders.
|
||||
- ❌ Not maskable.
|
||||
- ❌ More batches.
|
||||
- ❌ Requires Canvas.
|
||||
|
||||
- **Use RenderTexture**
|
||||

|
||||
- ✅ Maskable.
|
||||
- ✅ Sortable.
|
||||
- ❌ Requires Camera and RenderTexture.
|
||||
- ❌ Difficult to adjust position and size.
|
||||
- ❌ Quality depends on the RenderTexture's setting.
|
||||
|
||||
[UIParticleSystem]: https://forum.unity.com/threads/free-script-particle-systems-in-ui-screen-space-overlay.406862/
|
||||
|
||||
#### [Performance test results](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/193#issuecomment-1160028374)
|
||||
|
||||
| Approach | FPS on Editor | FPS on iPhone6 | FPS on Xperia XZ |
|
||||
|-----------------------------|---------------|----------------|------------------|
|
||||
| Particle System | 43 | 57 | 22 |
|
||||
| UIParticleSystem | 4 | 3 | 0 (unmeasurable) |
|
||||
| Sorting By Canvas | 43 | 44 | 18 |
|
||||
| UIParticle | 17 | 12 | 4 |
|
||||
| UIParticle with MeshSharing | 44 | 45 | 30 |
|
||||
|
||||
### 🔍 FAQ: Why Are My UIParticles Not Displayed Correctly?
|
||||
|
||||
If `ParticleSystem` alone displays particles correctly but `UIParticle` does not, please check the following points:
|
||||
|
||||
- [Shader Limitation](#shader-limitation)
|
||||
- `UIParticle` does not support all built-in shaders except for `UI/Default`.
|
||||
- Most cases can be solved by using `UI/Additive` or `UI/Default`.
|
||||
- Particles are not masked
|
||||
- `UIParticle` is maskable.
|
||||
- Set `Mask` or `RectMask2D` component properly.
|
||||
- [Use maskable/clipable shader](#how-to-make-a-custom-shader-to-support-maskrectmask2d-component) (such
|
||||
as `UI/Additive` or `UI/Default`)
|
||||
- Particles are too small
|
||||
- If particles are small enough, they will not appear on the screen.
|
||||
- Increase the `Scale` value.
|
||||
- If you don't want to change the apparent size depending on the resolution, try the `Auto Scaling` option.
|
||||
- Particles are too many
|
||||
- No more than 65535 vertices can be displayed (for mesh combination limitations).
|
||||
- Please set `Emission` module and `Max Particles` of ParticleSystem properly.
|
||||
- Particles are emitted off-screen.
|
||||
- When `Position Mode = Relative`, particles are emitted from the scaled position of the ParticleSystem, not from
|
||||
the screen point of the ParticleSystem.
|
||||
- Place the ParticleSystem in the proper position or try `Position Mode = Absolute`.
|
||||
- Attaching `UIParticle` to the same object as `ParticleSystem`
|
||||
- `Transform.localScale` will be overridden by the `Auto Scaling` option.
|
||||
- It is recommended to place `ParticleSystem` under `UIParticle`.
|
||||
- If `Transform.localScale` contains 0, rendering will be skipped.
|
||||
- Displayed particles are in the correct position but too large/too small
|
||||
- Adjust `ParticleSystem.renderer.Min/MaxParticleSize`.
|
||||
|
||||
<br>
|
||||
|
||||
### Shader Limitation
|
||||
|
||||
The use of UI shaders is recommended.
|
||||
|
||||
- If you need a simple Additive shader, use the `UI/Additive` shader instead.
|
||||
- If you need a simple alpha-blend shader, use the `UI/Default` shader instead.
|
||||
- If your custom shader does not work properly with UIParticle, consider creating a custom UI shader.
|
||||
|
||||
#### Built-in shaders are not supported
|
||||
|
||||
`UIParticle` does not support all built-in shaders except for `UI/Default`.
|
||||
If their use is detected, an error is displayed in the inspector.
|
||||
Use UI shaders instead.
|
||||
|
||||
#### (Unity 2018 or 2019) UV.zw components will be discarded
|
||||
|
||||
UIParticleRenderer renders the particles based on UIVertex.
|
||||
Therefore, only the xy components are available for each UV in the shader. (zw components will be discarded).
|
||||
So unfortunately, UIParticles will not work well with some shaders.
|
||||
|
||||
#### (Unity 2018 or 2019) Custom vertex streams
|
||||
|
||||
When using custom vertex streams, you can fill zw components with "unnecessary" data.
|
||||
Refer to [this issue](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/191) for more information.
|
||||
|
||||
<br>
|
||||
|
||||
### Overheads
|
||||
|
||||
UIParticle has some overheads, and the batching depends on uGUI.
|
||||
When improving performance, keep the following in mind:
|
||||
|
||||
- If you are displaying a large number of the same effect, consider the `Mesh Sharing` feature in
|
||||
the [UIParticle Component](#uiparticle-component).
|
||||
- If you don't like the uniform output, consider the `Random Group` feature.
|
||||

|
||||
- If you are using multiple materials, you will have more draw calls.
|
||||
- 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
|
||||
|
||||
<details>
|
||||
<summary>Shader tips</summary>
|
||||
|
||||
```ShaderLab
|
||||
Shader "Your/Custom/Shader"
|
||||
{
|
||||
Properties
|
||||
{
|
||||
// ...
|
||||
// #### required for Mask ####
|
||||
_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
|
||||
{
|
||||
// ...
|
||||
}
|
||||
|
||||
// #### required for Mask ####
|
||||
Stencil
|
||||
{
|
||||
Ref [_Stencil]
|
||||
Comp [_StencilComp]
|
||||
Pass [_StencilOp]
|
||||
ReadMask [_StencilReadMask]
|
||||
WriteMask [_StencilWriteMask]
|
||||
}
|
||||
ColorMask [_ColorMask]
|
||||
// ...
|
||||
|
||||
Pass
|
||||
{
|
||||
// ...
|
||||
// #### required for RectMask2D ####
|
||||
#include "UnityUI.cginc"
|
||||
#pragma multi_compile __ UNITY_UI_CLIP_RECT
|
||||
float4 _ClipRect;
|
||||
|
||||
// #### required for Mask ####
|
||||
#pragma multi_compile __ UNITY_UI_ALPHACLIP
|
||||
|
||||
struct appdata_t
|
||||
{
|
||||
// ...
|
||||
};
|
||||
|
||||
struct v2f
|
||||
{
|
||||
// ...
|
||||
// #### required for RectMask2D ####
|
||||
float4 worldPosition : TEXCOORD1;
|
||||
};
|
||||
|
||||
v2f vert(appdata_t v)
|
||||
{
|
||||
v2f OUT;
|
||||
// ...
|
||||
// #### required for RectMask2D ####
|
||||
OUT.worldPosition = v.vertex;
|
||||
return OUT;
|
||||
}
|
||||
|
||||
fixed4 frag(v2f IN) : SV_Target
|
||||
{
|
||||
// ...
|
||||
// #### required for RectMask2D ####
|
||||
#ifdef UNITY_UI_CLIP_RECT
|
||||
color.a *= UnityGet2DClipping(IN.worldPosition.xy, _ClipRect);
|
||||
#endif
|
||||
|
||||
// #### required for Mask ####
|
||||
#ifdef UNITY_UI_ALPHACLIP
|
||||
clip (color.a - 0.001);
|
||||
#endif
|
||||
|
||||
return color;
|
||||
}
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
<br><br>
|
||||
|
||||
## 🤝 Contributing
|
||||
|
||||
### Issues
|
||||
|
||||
Issues are incredibly valuable to this project:
|
||||
|
||||
- Ideas provide a valuable source of contributions that others can make.
|
||||
- Problems help identify areas where this project needs improvement.
|
||||
- Questions indicate where contributors can enhance the user experience.
|
||||
|
||||
### Pull Requests
|
||||
|
||||
Pull requests offer a fantastic way to contribute your ideas to this repository.
|
||||
Please refer to [CONTRIBUTING.md](https://github.com/mob-sakai/ParticleEffectForUGUI/blob/main/CONTRIBUTING.md)
|
||||
and [develop branch](https://github.com/mob-sakai/ParticleEffectForUGUI/tree/develop) for guidelines.
|
||||
|
||||
### Support
|
||||
|
||||
This is an open-source project developed during my spare time.
|
||||
If you appreciate it, consider supporting me.
|
||||
Your support allows me to dedicate more time to development. 😊
|
||||
|
||||
[](https://www.patreon.com/join/2343451?)
|
||||
[](https://github.com/users/mob-sakai/sponsorship)
|
||||
|
||||
<br><br>
|
||||
|
||||
## License
|
||||
|
||||
* MIT
|
||||
|
||||
## Author
|
||||
|
||||
*  [mob-sakai](https://github.com/mob-sakai) [](https://twitter.com/intent/follow?screen_name=mob_sakai) 
|
||||
|
||||
## See Also
|
||||
|
||||
* GitHub page : https://github.com/mob-sakai/ParticleEffectForUGUI
|
||||
* Releases : https://github.com/mob-sakai/ParticleEffectForUGUI/releases
|
||||
* Issue tracker : https://github.com/mob-sakai/ParticleEffectForUGUI/issues
|
||||
* Change log : https://github.com/mob-sakai/ParticleEffectForUGUI/blob/main/CHANGELOG.md
|
||||
72
Packages/src/Runtime/ModifiedMaterial.cs
Normal file
@@ -0,0 +1,72 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Coffee.UIParticleExtensions
|
||||
{
|
||||
internal class ModifiedMaterial
|
||||
{
|
||||
private static readonly List<MatEntry> s_Entries = new List<MatEntry>();
|
||||
|
||||
public static Material Add(Material baseMat, Texture texture, int id, int props)
|
||||
{
|
||||
MatEntry e;
|
||||
for (var i = 0; i < s_Entries.Count; i++)
|
||||
{
|
||||
e = s_Entries[i];
|
||||
if (e.baseMat != baseMat || e.texture != texture || e.id != id || e.props != props) continue;
|
||||
++e.count;
|
||||
return e.customMat;
|
||||
}
|
||||
|
||||
e = new MatEntry
|
||||
{
|
||||
count = 1,
|
||||
baseMat = baseMat,
|
||||
texture = texture,
|
||||
id = id,
|
||||
props = props,
|
||||
customMat = new Material(baseMat)
|
||||
{
|
||||
name = $"{baseMat.name}_{id}",
|
||||
hideFlags = HideFlags.DontSave | HideFlags.NotEditable,
|
||||
mainTexture = texture ? texture : baseMat.mainTexture
|
||||
}
|
||||
};
|
||||
s_Entries.Add(e);
|
||||
//Debug.LogFormat(">>>> ModifiedMaterial.Add -> count = count:{0}, mat:{1}, tex:{2}, id:{3}", s_Entries.Count, baseMat, texture, id);
|
||||
return e.customMat;
|
||||
}
|
||||
|
||||
public static void Remove(Material customMat)
|
||||
{
|
||||
if (!customMat) return;
|
||||
|
||||
for (var i = 0; i < s_Entries.Count; ++i)
|
||||
{
|
||||
var e = s_Entries[i];
|
||||
if (e.customMat != customMat) continue;
|
||||
if (--e.count == 0)
|
||||
{
|
||||
//Debug.LogFormat(">>>> ModifiedMaterial.Remove -> count:{0}, mat:{1}, tex:{2}, id:{3}", s_Entries.Count - 1, e.customMat, e.texture, e.id);
|
||||
Misc.DestroyImmediate(e.customMat);
|
||||
e.customMat = null;
|
||||
e.baseMat = null;
|
||||
e.texture = null;
|
||||
s_Entries.RemoveAt(i);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private class MatEntry
|
||||
{
|
||||
public Material baseMat;
|
||||
public int count;
|
||||
public Material customMat;
|
||||
public int id;
|
||||
public int props;
|
||||
public Texture texture;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Packages/src/Runtime/ModifiedMaterial.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b0beae5bb1cb142b9ab90dc0d371f026
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,7 +1,8 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Coffee.UIParticleInternal;
|
||||
using Coffee.UIParticleExtensions;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
using UnityEngine.Serialization;
|
||||
@@ -9,16 +10,12 @@ 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))]
|
||||
@@ -48,26 +45,23 @@ namespace Coffee.UIExtensions
|
||||
|
||||
[HideInInspector]
|
||||
[SerializeField]
|
||||
[Obsolete]
|
||||
internal bool m_IsTrail;
|
||||
|
||||
[HideInInspector]
|
||||
[FormerlySerializedAs("m_IgnoreParent")]
|
||||
[SerializeField]
|
||||
[Obsolete]
|
||||
private bool m_IgnoreCanvasScaler;
|
||||
|
||||
[HideInInspector]
|
||||
[SerializeField]
|
||||
[Obsolete]
|
||||
internal bool m_AbsoluteMode;
|
||||
private bool m_AbsoluteMode;
|
||||
|
||||
[Tooltip("Scale the rendering particles. When the `3D` toggle is enabled, 3D scale (x, y, z) is supported.")]
|
||||
[Tooltip("Particle effect scale")]
|
||||
[SerializeField]
|
||||
private Vector3 m_Scale3D = new Vector3(10, 10, 10);
|
||||
|
||||
[Tooltip("If you want to update material properties (e.g. _MainTex_ST, _Color) in AnimationClip, " +
|
||||
"use this to mark as animatable.")]
|
||||
[Tooltip("Animatable material properties.\n" +
|
||||
"If you want to change the material properties of the ParticleSystem in Animation, enable it.")]
|
||||
[SerializeField]
|
||||
internal AnimatableProperty[] m_AnimatableProperties = new AnimatableProperty[0];
|
||||
|
||||
@@ -75,13 +69,12 @@ namespace Coffee.UIExtensions
|
||||
[SerializeField]
|
||||
private List<ParticleSystem> m_Particles = new List<ParticleSystem>();
|
||||
|
||||
[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" +
|
||||
[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" +
|
||||
"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;
|
||||
|
||||
@@ -93,43 +86,23 @@ namespace Coffee.UIExtensions
|
||||
[SerializeField]
|
||||
private int m_GroupMaxId;
|
||||
|
||||
[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.")]
|
||||
[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.")]
|
||||
[SerializeField]
|
||||
private PositionMode m_PositionMode = PositionMode.Relative;
|
||||
|
||||
[SerializeField]
|
||||
[Obsolete]
|
||||
internal bool m_AutoScaling;
|
||||
[Tooltip("Prevent the root-Canvas scale from affecting the hierarchy-scaled ParticleSystem.")]
|
||||
private bool m_AutoScaling = true;
|
||||
|
||||
[SerializeField]
|
||||
[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.")]
|
||||
[Tooltip("Transform: Transform.lossyScale (=world scale) will be set to (1, 1, 1)." +
|
||||
"UIParticle: UIParticle.scale will be adjusted.")]
|
||||
private AutoScalingMode m_AutoScalingMode = AutoScalingMode.Transform;
|
||||
|
||||
[SerializeField]
|
||||
[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 Camera _bakeCamera;
|
||||
private int _groupId;
|
||||
private bool _isScaleStored;
|
||||
private Vector3 _storedScale;
|
||||
private Camera _orthoCamera;
|
||||
private DrivenRectTransformTracker _tracker;
|
||||
|
||||
/// <summary>
|
||||
@@ -142,8 +115,7 @@ namespace Coffee.UIExtensions
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Particle simulation results are shared within the same group.
|
||||
/// A large number of the same effects can be displayed with a small load.
|
||||
/// Mesh sharing.
|
||||
/// None: disable mesh sharing.
|
||||
/// Auto: automatically select Primary/Replica.
|
||||
/// Primary: provides particle simulation results to the same group.
|
||||
@@ -186,9 +158,9 @@ namespace Coffee.UIExtensions
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Emission position mode.
|
||||
/// Relative: The particles will be emitted from the scaled position.
|
||||
/// Absolute: The particles will be emitted from the world position.
|
||||
/// 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.
|
||||
/// </summary>
|
||||
public PositionMode positionMode
|
||||
{
|
||||
@@ -201,7 +173,6 @@ 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;
|
||||
@@ -219,12 +190,8 @@ namespace Coffee.UIExtensions
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// How to automatically adjust when the Canvas scale is changed by the screen size or reference resolution.
|
||||
/// <para/>
|
||||
/// None: Do nothing.
|
||||
/// <para/>
|
||||
/// Auto scaling mode.
|
||||
/// Transform: Transform.lossyScale (=world scale) will be set to (1, 1, 1).
|
||||
/// <para/>
|
||||
/// UIParticle: UIParticle.scale will be adjusted.
|
||||
/// </summary>
|
||||
public AutoScalingMode autoScalingMode
|
||||
@@ -234,44 +201,10 @@ namespace Coffee.UIExtensions
|
||||
{
|
||||
if (m_AutoScalingMode == value) return;
|
||||
m_AutoScalingMode = value;
|
||||
|
||||
if (autoScalingMode != AutoScalingMode.Transform && _isScaleStored)
|
||||
{
|
||||
transform.localScale = _storedScale;
|
||||
_isScaleStored = false;
|
||||
}
|
||||
UpdateTracker();
|
||||
}
|
||||
}
|
||||
|
||||
/// <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 =>
|
||||
@@ -311,12 +244,30 @@ namespace Coffee.UIExtensions
|
||||
/// <summary>
|
||||
/// Particle effect scale.
|
||||
/// </summary>
|
||||
public Vector3 scale3DForCalc => autoScalingMode == AutoScalingMode.Transform
|
||||
? m_Scale3D
|
||||
: m_Scale3D.GetScaled(canvasScale, transform.localScale);
|
||||
public Vector3 scale3DForCalc => autoScalingMode == AutoScalingMode.UIParticle
|
||||
? m_Scale3D.GetScaled(canvasScale)
|
||||
: m_Scale3D;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override Material materialForRendering => null;
|
||||
|
||||
/// <summary>
|
||||
/// Paused.
|
||||
/// </summary>
|
||||
@@ -328,8 +279,8 @@ namespace Coffee.UIExtensions
|
||||
|
||||
protected override void OnEnable()
|
||||
{
|
||||
_isScaleStored = false;
|
||||
ResetGroupId();
|
||||
UpdateTracker();
|
||||
UIParticleUpdater.Register(this);
|
||||
RegisterDirtyMaterialCallback(UpdateRendererMaterial);
|
||||
|
||||
@@ -350,13 +301,7 @@ namespace Coffee.UIExtensions
|
||||
/// </summary>
|
||||
protected override void OnDisable()
|
||||
{
|
||||
_tracker.Clear();
|
||||
if (autoScalingMode == AutoScalingMode.Transform && _isScaleStored)
|
||||
{
|
||||
transform.localScale = _storedScale;
|
||||
}
|
||||
|
||||
_isScaleStored = false;
|
||||
UpdateTracker();
|
||||
UIParticleUpdater.Unregister(this);
|
||||
_renderers.ForEach(r => r.Reset());
|
||||
UnregisterDirtyMaterialCallback(UpdateRendererMaterial);
|
||||
@@ -371,13 +316,20 @@ namespace Coffee.UIExtensions
|
||||
{
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
protected override void OnValidate()
|
||||
{
|
||||
base.OnValidate();
|
||||
UpdateTracker();
|
||||
}
|
||||
#endif
|
||||
|
||||
void ISerializationCallbackReceiver.OnBeforeSerialize()
|
||||
{
|
||||
}
|
||||
|
||||
void ISerializationCallbackReceiver.OnAfterDeserialize()
|
||||
{
|
||||
#pragma warning disable CS0612 // Type or member is obsolete
|
||||
if (m_IgnoreCanvasScaler || m_AutoScaling)
|
||||
{
|
||||
m_IgnoreCanvasScaler = false;
|
||||
@@ -390,47 +342,31 @@ namespace Coffee.UIExtensions
|
||||
m_AbsoluteMode = false;
|
||||
m_PositionMode = PositionMode.Absolute;
|
||||
}
|
||||
#pragma warning restore CS0612 // Type or member is obsolete
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Play the ParticleSystems.
|
||||
/// </summary>
|
||||
public void Play()
|
||||
{
|
||||
particles.Exec(p => p.Simulate(0, false, true));
|
||||
isPaused = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pause the ParticleSystems.
|
||||
/// </summary>
|
||||
public void Pause()
|
||||
{
|
||||
particles.Exec(p => p.Pause());
|
||||
isPaused = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unpause the ParticleSystems.
|
||||
/// </summary>
|
||||
public void Resume()
|
||||
{
|
||||
isPaused = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stop the ParticleSystems.
|
||||
/// </summary>
|
||||
public void Stop()
|
||||
{
|
||||
particles.Exec(p => p.Stop());
|
||||
isPaused = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Start emission of the ParticleSystems.
|
||||
/// </summary>
|
||||
public void StartEmission()
|
||||
{
|
||||
particles.Exec(p =>
|
||||
@@ -440,9 +376,6 @@ namespace Coffee.UIExtensions
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stop emission of the ParticleSystems.
|
||||
/// </summary>
|
||||
public void StopEmission()
|
||||
{
|
||||
particles.Exec(p =>
|
||||
@@ -452,52 +385,24 @@ namespace Coffee.UIExtensions
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clear the particles of the ParticleSystems.
|
||||
/// </summary>
|
||||
public void Clear()
|
||||
{
|
||||
particles.Exec(p => p.Clear());
|
||||
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>
|
||||
public void SetParticleSystemInstance(GameObject instance)
|
||||
{
|
||||
SetParticleSystemInstance(instance, true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Refresh UIParticle using the ParticleSystem instance.
|
||||
/// </summary>
|
||||
public void SetParticleSystemInstance(GameObject instance, bool destroyOldParticles)
|
||||
{
|
||||
if (instance == null) return;
|
||||
if (!instance) return;
|
||||
|
||||
var childCount = transform.childCount;
|
||||
for (var i = 0; i < childCount; i++)
|
||||
foreach (Transform child in transform)
|
||||
{
|
||||
var go = transform.GetChild(i).gameObject;
|
||||
if (go.TryGetComponent<Camera>(out var cam) && cam == _bakeCamera) continue;
|
||||
if (go.TryGetComponent<UIParticleRenderer>(out var _)) continue;
|
||||
|
||||
var go = child.gameObject;
|
||||
go.SetActive(false);
|
||||
if (destroyOldParticles)
|
||||
{
|
||||
@@ -512,42 +417,23 @@ namespace Coffee.UIExtensions
|
||||
RefreshParticles(instance);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Refresh UIParticle using the prefab.
|
||||
/// The prefab is automatically instantiated.
|
||||
/// </summary>
|
||||
public void SetParticleSystemPrefab(GameObject prefab)
|
||||
{
|
||||
if (prefab == null) return;
|
||||
if (!prefab) return;
|
||||
|
||||
SetParticleSystemInstance(Instantiate(prefab.gameObject), true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Refresh UIParticle.
|
||||
/// Collect ParticleSystems under the GameObject and refresh the UIParticle.
|
||||
/// </summary>
|
||||
public void RefreshParticles()
|
||||
{
|
||||
RefreshParticles(gameObject);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Refresh UIParticle.
|
||||
/// Collect ParticleSystems under the GameObject and refresh the UIParticle.
|
||||
/// </summary>
|
||||
private void RefreshParticles(GameObject root)
|
||||
{
|
||||
if (root == null) return;
|
||||
if (!root) return;
|
||||
root.GetComponentsInChildren(true, particles);
|
||||
for (var i = particles.Count - 1; 0 <= i; i--)
|
||||
{
|
||||
var ps = particles[i];
|
||||
if (!ps || ps.GetComponentInParent<UIParticle>(true) != this)
|
||||
{
|
||||
particles.RemoveAt(i);
|
||||
}
|
||||
}
|
||||
particles.RemoveAll(x => x.GetComponentInParent<UIParticle>(true) != this);
|
||||
|
||||
for (var i = 0; i < particles.Count; i++)
|
||||
{
|
||||
@@ -562,74 +448,46 @@ namespace Coffee.UIExtensions
|
||||
RefreshParticles(particles);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Refresh UIParticle using a list of ParticleSystems.
|
||||
/// </summary>
|
||||
public void RefreshParticles(List<ParticleSystem> particleSystems)
|
||||
public void RefreshParticles(List<ParticleSystem> particles)
|
||||
{
|
||||
// Collect children UIParticleRenderer components.
|
||||
// #246: Nullptr exceptions when using nested UIParticle components in hierarchy
|
||||
_renderers.Clear();
|
||||
var childCount = transform.childCount;
|
||||
for (var i = 0; i < childCount; i++)
|
||||
foreach (Transform child in transform)
|
||||
{
|
||||
var child = transform.GetChild(i);
|
||||
if (child.TryGetComponent(out UIParticleRenderer uiParticleRenderer))
|
||||
var uiParticleRenderer = child.GetComponent<UIParticleRenderer>();
|
||||
|
||||
if (uiParticleRenderer != null)
|
||||
{
|
||||
_renderers.Add(uiParticleRenderer);
|
||||
}
|
||||
}
|
||||
|
||||
// Reset the UIParticleRenderer components.
|
||||
for (var i = 0; i < _renderers.Count; i++)
|
||||
{
|
||||
_renderers[i].Reset(i);
|
||||
}
|
||||
|
||||
// Set the ParticleSystem to the UIParticleRenderer. If the trail is enabled, set it additionally.
|
||||
var j = 0;
|
||||
for (var i = 0; i < particleSystems.Count; i++)
|
||||
for (var i = 0; i < particles.Count; i++)
|
||||
{
|
||||
var ps = particleSystems[i];
|
||||
if (ps == null) continue;
|
||||
|
||||
var mainEmitter = ps.GetMainEmitter(particleSystems);
|
||||
GetRenderer(j++).Set(this, ps, false, mainEmitter);
|
||||
|
||||
// If the trail is enabled, set it additionally.
|
||||
var ps = particles[i];
|
||||
if (!ps) continue;
|
||||
GetRenderer(j++).Set(this, ps, false);
|
||||
if (ps.trails.enabled)
|
||||
{
|
||||
GetRenderer(j++).Set(this, ps, true, mainEmitter);
|
||||
GetRenderer(j++).Set(this, ps, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal void UpdateTransformScale()
|
||||
{
|
||||
_tracker.Clear();
|
||||
canvasScale = canvas.rootCanvas.transform.localScale.Inverse();
|
||||
parentScale = transform.parent.lossyScale;
|
||||
if (autoScalingMode != AutoScalingMode.Transform)
|
||||
{
|
||||
if (_isScaleStored)
|
||||
{
|
||||
transform.localScale = _storedScale;
|
||||
}
|
||||
if (autoScalingMode != AutoScalingMode.Transform) return;
|
||||
|
||||
_isScaleStored = false;
|
||||
return;
|
||||
}
|
||||
|
||||
var currentScale = transform.localScale;
|
||||
if (!_isScaleStored)
|
||||
{
|
||||
_storedScale = currentScale.IsVisible() ? currentScale : Vector3.one;
|
||||
_isScaleStored = true;
|
||||
}
|
||||
|
||||
_tracker.Add(this, rectTransform, DrivenTransformProperties.Scale);
|
||||
var newScale = parentScale.Inverse();
|
||||
if (currentScale != newScale)
|
||||
if (transform.localScale != newScale)
|
||||
{
|
||||
transform.localScale = newScale;
|
||||
}
|
||||
@@ -642,18 +500,18 @@ namespace Coffee.UIExtensions
|
||||
for (var i = 0; i < _renderers.Count; i++)
|
||||
{
|
||||
var r = _renderers[i];
|
||||
if (r != null) continue;
|
||||
|
||||
RefreshParticles(particles);
|
||||
break;
|
||||
if (!r)
|
||||
{
|
||||
RefreshParticles(particles);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var bakeCamera = GetBakeCamera();
|
||||
for (var i = 0; i < _renderers.Count; i++)
|
||||
{
|
||||
var r = _renderers[i];
|
||||
if (r == null) continue;
|
||||
|
||||
if (!r) continue;
|
||||
r.UpdateMesh(bakeCamera);
|
||||
}
|
||||
}
|
||||
@@ -681,7 +539,7 @@ namespace Coffee.UIExtensions
|
||||
for (var i = 0; i < _renderers.Count; i++)
|
||||
{
|
||||
var r = _renderers[i];
|
||||
if (r == null) continue;
|
||||
if (!r) continue;
|
||||
r.maskable = maskable;
|
||||
r.SetMaterialDirty();
|
||||
}
|
||||
@@ -694,7 +552,7 @@ namespace Coffee.UIExtensions
|
||||
_renderers.Add(UIParticleRenderer.AddRenderer(this, index));
|
||||
}
|
||||
|
||||
if (_renderers[index] == null)
|
||||
if (!_renderers[index])
|
||||
{
|
||||
_renderers[index] = UIParticleRenderer.AddRenderer(this, index);
|
||||
}
|
||||
@@ -704,56 +562,65 @@ namespace Coffee.UIExtensions
|
||||
|
||||
private Camera GetBakeCamera()
|
||||
{
|
||||
if (canvas == null) return Camera.main;
|
||||
if (!useCustomView && canvas.renderMode != RenderMode.ScreenSpaceOverlay && canvas.rootCanvas.worldCamera)
|
||||
if (!canvas) return Camera.main;
|
||||
|
||||
// When render mode is ScreenSpaceCamera or WorldSpace, use world camera.
|
||||
var root = canvas.rootCanvas;
|
||||
if (root.renderMode != RenderMode.ScreenSpaceOverlay)
|
||||
{
|
||||
return canvas.rootCanvas.worldCamera;
|
||||
return root.worldCamera ? root.worldCamera : Camera.main;
|
||||
}
|
||||
|
||||
if (_bakeCamera != null)
|
||||
// When render mode is ScreenSpaceOverlay, use ortho-camera.
|
||||
if (!_orthoCamera)
|
||||
{
|
||||
_bakeCamera.orthographicSize = useCustomView ? customViewSize : 10;
|
||||
return _bakeCamera;
|
||||
}
|
||||
|
||||
// Find existing baking camera.
|
||||
var childCount = transform.childCount;
|
||||
for (var i = 0; i < childCount; i++)
|
||||
{
|
||||
if (transform.GetChild(i).TryGetComponent<Camera>(out var cam)
|
||||
&& cam.name == "[generated] UIParticle BakingCamera")
|
||||
// Find existing ortho-camera.
|
||||
foreach (Transform child in transform)
|
||||
{
|
||||
_bakeCamera = cam;
|
||||
break;
|
||||
var cam = child.GetComponent<Camera>();
|
||||
if (cam && cam.name == "[generated] UIParticleOverlayCamera")
|
||||
{
|
||||
_orthoCamera = cam;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Create ortho-camera.
|
||||
if (!_orthoCamera)
|
||||
{
|
||||
var go = new GameObject("[generated] UIParticleOverlayCamera")
|
||||
{
|
||||
hideFlags = HideFlags.HideAndDontSave
|
||||
};
|
||||
go.SetActive(false);
|
||||
go.transform.SetParent(transform, false);
|
||||
_orthoCamera = go.AddComponent<Camera>();
|
||||
_orthoCamera.enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Create baking camera.
|
||||
if (_bakeCamera == null)
|
||||
//
|
||||
var size = ((RectTransform)root.transform).rect.size;
|
||||
_orthoCamera.orthographicSize = Mathf.Max(size.x, size.y) * root.scaleFactor;
|
||||
_orthoCamera.transform.SetPositionAndRotation(new Vector3(0, 0, -1000), Quaternion.identity);
|
||||
_orthoCamera.orthographic = true;
|
||||
_orthoCamera.farClipPlane = 2000f;
|
||||
|
||||
return _orthoCamera;
|
||||
}
|
||||
|
||||
private void UpdateTracker()
|
||||
{
|
||||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
if (!enabled || !autoScaling || autoScalingMode != AutoScalingMode.Transform)
|
||||
#pragma warning restore CS0618 // Type or member is obsolete
|
||||
{
|
||||
var go = new GameObject("[generated] UIParticle BakingCamera");
|
||||
go.SetActive(false);
|
||||
go.transform.SetParent(transform, false);
|
||||
_bakeCamera = go.AddComponent<Camera>();
|
||||
_tracker.Clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
_tracker.Add(this, rectTransform, DrivenTransformProperties.Scale);
|
||||
}
|
||||
|
||||
// Setup baking camera.
|
||||
_bakeCamera.enabled = false;
|
||||
_bakeCamera.orthographicSize = useCustomView ? customViewSize : 10;
|
||||
_bakeCamera.transform.SetPositionAndRotation(new Vector3(0, 0, -1000), Quaternion.identity);
|
||||
_bakeCamera.orthographic = true;
|
||||
_bakeCamera.farClipPlane = 2000f;
|
||||
_bakeCamera.clearFlags = CameraClearFlags.Nothing;
|
||||
_bakeCamera.cullingMask = 0; // Nothing
|
||||
_bakeCamera.allowHDR = false;
|
||||
_bakeCamera.allowMSAA = false;
|
||||
_bakeCamera.renderingPath = RenderingPath.Forward;
|
||||
_bakeCamera.useOcclusionCulling = false;
|
||||
|
||||
_bakeCamera.gameObject.SetActive(false);
|
||||
_bakeCamera.gameObject.hideFlags = UIParticleProjectSettings.globalHideFlags;
|
||||
|
||||
return _bakeCamera;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 00e55ae1441ff4583859c55384964d86
|
||||
guid: 16f0b0b6d0b7542bfbd20a3e05b04ff1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
262
Packages/src/Runtime/UIParticleAttractor.cs
Normal file
@@ -0,0 +1,262 @@
|
||||
using System;
|
||||
using Coffee.UIParticleExtensions;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
|
||||
namespace Coffee.UIExtensions
|
||||
{
|
||||
[ExecuteAlways]
|
||||
public class UIParticleAttractor : MonoBehaviour
|
||||
{
|
||||
public enum Movement
|
||||
{
|
||||
Linear,
|
||||
Smooth,
|
||||
Sphere
|
||||
}
|
||||
|
||||
public enum UpdateMode
|
||||
{
|
||||
Normal,
|
||||
UnscaledTime
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private ParticleSystem m_ParticleSystem;
|
||||
|
||||
[Range(0.1f, 10f)]
|
||||
[SerializeField]
|
||||
private float m_DestinationRadius = 1;
|
||||
|
||||
[Range(0f, 0.95f)]
|
||||
[SerializeField]
|
||||
private float m_DelayRate;
|
||||
|
||||
[Range(0.001f, 100f)]
|
||||
[SerializeField]
|
||||
private float m_MaxSpeed = 1;
|
||||
|
||||
[SerializeField]
|
||||
private Movement m_Movement;
|
||||
|
||||
[SerializeField]
|
||||
private UpdateMode m_UpdateMode;
|
||||
|
||||
[SerializeField]
|
||||
private UnityEvent m_OnAttracted;
|
||||
|
||||
private UIParticle _uiParticle;
|
||||
|
||||
public float destinationRadius
|
||||
{
|
||||
get => m_DestinationRadius;
|
||||
set => m_DestinationRadius = Mathf.Clamp(value, 0.1f, 10f);
|
||||
}
|
||||
|
||||
public float delay
|
||||
{
|
||||
get => m_DelayRate;
|
||||
set => m_DelayRate = value;
|
||||
}
|
||||
|
||||
public float maxSpeed
|
||||
{
|
||||
get => m_MaxSpeed;
|
||||
set => m_MaxSpeed = value;
|
||||
}
|
||||
|
||||
public Movement movement
|
||||
{
|
||||
get => m_Movement;
|
||||
set => m_Movement = value;
|
||||
}
|
||||
|
||||
public UpdateMode updateMode
|
||||
{
|
||||
get => m_UpdateMode;
|
||||
set => m_UpdateMode = value;
|
||||
}
|
||||
|
||||
public UnityEvent onAttracted
|
||||
{
|
||||
get => m_OnAttracted;
|
||||
set => m_OnAttracted = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The target ParticleSystem to attract.
|
||||
/// </summary>
|
||||
#if UNITY_EDITOR
|
||||
public new ParticleSystem particleSystem
|
||||
#else
|
||||
public ParticleSystem particleSystem
|
||||
#endif
|
||||
{
|
||||
get => m_ParticleSystem;
|
||||
set
|
||||
{
|
||||
m_ParticleSystem = value;
|
||||
ApplyParticleSystem();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
ApplyParticleSystem();
|
||||
UIParticleUpdater.Register(this);
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
UIParticleUpdater.Unregister(this);
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
_uiParticle = null;
|
||||
m_ParticleSystem = null;
|
||||
}
|
||||
|
||||
internal void Attract()
|
||||
{
|
||||
if (m_ParticleSystem == null) return;
|
||||
|
||||
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++)
|
||||
{
|
||||
// Attracted
|
||||
var p = particles[i];
|
||||
if (0f < p.remainingLifetime && Vector3.Distance(p.position, dstPos) < m_DestinationRadius)
|
||||
{
|
||||
p.remainingLifetime = 0f;
|
||||
particles[i] = p;
|
||||
|
||||
if (m_OnAttracted != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
m_OnAttracted.Invoke();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogException(e);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
m_ParticleSystem.SetParticles(particles, count);
|
||||
}
|
||||
|
||||
private Vector3 GetDestinationPosition()
|
||||
{
|
||||
var isUI = _uiParticle && _uiParticle.enabled;
|
||||
var psPos = m_ParticleSystem.transform.position;
|
||||
var attractorPos = transform.position;
|
||||
var dstPos = attractorPos;
|
||||
var isLocalSpace = m_ParticleSystem.IsLocalSpace();
|
||||
|
||||
if (isLocalSpace)
|
||||
{
|
||||
dstPos = m_ParticleSystem.transform.InverseTransformPoint(dstPos);
|
||||
}
|
||||
|
||||
if (isUI)
|
||||
{
|
||||
var inverseScale = _uiParticle.parentScale.Inverse();
|
||||
var scale3d = _uiParticle.scale3DForCalc;
|
||||
dstPos = dstPos.GetScaled(inverseScale, scale3d.Inverse());
|
||||
|
||||
// Relative mode
|
||||
if (_uiParticle.positionMode == UIParticle.PositionMode.Relative)
|
||||
{
|
||||
var diff = _uiParticle.transform.position - psPos;
|
||||
diff.Scale(scale3d - inverseScale);
|
||||
diff.Scale(scale3d.Inverse());
|
||||
dstPos += diff;
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
if (!Application.isPlaying && !isLocalSpace)
|
||||
{
|
||||
dstPos += psPos - psPos.GetScaled(inverseScale, scale3d.Inverse());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return dstPos;
|
||||
}
|
||||
|
||||
private Vector3 GetAttractedPosition(Vector3 current, Vector3 target, float duration, float time)
|
||||
{
|
||||
var speed = m_MaxSpeed;
|
||||
switch (m_UpdateMode)
|
||||
{
|
||||
case UpdateMode.Normal:
|
||||
speed *= 60 * Time.deltaTime;
|
||||
break;
|
||||
case UpdateMode.UnscaledTime:
|
||||
speed *= 60 * Time.unscaledDeltaTime;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (m_Movement)
|
||||
{
|
||||
case Movement.Linear:
|
||||
speed /= duration;
|
||||
break;
|
||||
case Movement.Smooth:
|
||||
target = Vector3.Lerp(current, target, time / duration);
|
||||
break;
|
||||
case Movement.Sphere:
|
||||
target = Vector3.Slerp(current, target, time / duration);
|
||||
break;
|
||||
}
|
||||
|
||||
return Vector3.MoveTowards(current, target, speed);
|
||||
}
|
||||
|
||||
private void ApplyParticleSystem()
|
||||
{
|
||||
_uiParticle = null;
|
||||
if (m_ParticleSystem == null)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (Application.isPlaying)
|
||||
#endif
|
||||
{
|
||||
Debug.LogError("No particle system attached to particle attractor script", this);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
_uiParticle = m_ParticleSystem.GetComponentInParent<UIParticle>(true);
|
||||
if (_uiParticle && !_uiParticle.particles.Contains(m_ParticleSystem))
|
||||
{
|
||||
_uiParticle = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||