Compare commits

...

52 Commits
0.7.1 ... main

Author SHA1 Message Date
semantic-release-bot b870d64b57 chore(release): 1.0.2 [skip ci]
## [1.0.2](https://github.com/mob-sakai/SoftMaskForUGUI/compare/1.0.1...1.0.2) (2022-05-15)

### Bug Fixes

* support TextMeshPro v2 or later ([c85409e](c85409e56f))
2022-05-15 06:52:50 +00:00
mob-sakai c85409e56f fix: support TextMeshPro v2 or later 2022-05-15 15:47:53 +09:00
semantic-release-bot 29def6dbe5 chore(release): 1.0.1 [skip ci]
## [1.0.1](https://github.com/mob-sakai/SoftMaskForUGUI/compare/1.0.0...1.0.1) (2022-05-15)

### Bug Fixes

* applied a workaround to fix a Microsoft HLSL compiler issue ([50c41f2](50c41f29cc)), closes [#131](https://github.com/mob-sakai/SoftMaskForUGUI/issues/131)
* fixed shader compilation in some platforms ([40b450b](40b450ba24))
2022-05-15 06:18:12 +00:00
jnncoutinho 40b450ba24 fix: fixed shader compilation in some platforms
The overload abs(float4x4, float4x4) is not present in some platforms
supported by Unity
Decomposing the operation fixes the problem
2022-05-15 15:17:00 +09:00
Mane Function 50c41f29cc fix: applied a workaround to fix a Microsoft HLSL compiler issue
close #131
https://fogbugz.unity3d.com/default.asp?934464_sjh4cs4ok77ne0cj&_ga=2.124069071.432066521.1640792064-45545210.1640792064
2022-05-15 15:17:00 +09:00
semantic-release-bot f59d147fe0 chore(release): 1.0.0 [skip ci]
# [1.0.0](https://github.com/mob-sakai/SoftMaskForUGUI/compare/0.9.1...1.0.0) (2021-02-24)

### Features

* release 1.0.0 ([127b455](127b455f38))

### BREAKING CHANGES

* release 1.0.0
2021-02-24 00:53:06 +00:00
mob-sakai 127b455f38 feat: release 1.0.0
BREAKING CHANGE: release 1.0.0
2021-02-24 09:51:24 +09:00
mob-sakai 837c1404a5
docs: update readme 2021-02-23 15:00:02 +09:00
mob-sakai 7aec93c09c test: update test 2021-02-23 14:53:52 +09:00
mob-sakai 4c6552253a build: update release workflow 2021-02-23 14:51:47 +09:00
mob-sakai 625af2a384 docs: update 2021-02-23 02:04:12 +09:00
semantic-release-bot 5c54622518 1.0.0-preview.14
# [1.0.0-preview.14](https://github.com/mob-sakai/SoftMaskForUGUI/compare/v1.0.0-preview.13...v1.0.0-preview.14) (2020-10-08)

### Bug Fixes

* incorrect behavior when a world space canvas and an overlay canvas are enabled together ([a6e82fa](a6e82fa2a7)), closes [#107](https://github.com/mob-sakai/SoftMaskForUGUI/issues/107)
2020-10-08 15:59:24 +00:00
semantic-release-bot 73177082e5 1.0.0-preview.13
# [1.0.0-preview.13](https://github.com/mob-sakai/SoftMaskForUGUI/compare/v1.0.0-preview.12...v1.0.0-preview.13) (2020-10-01)

### Bug Fixes

* screen resolution in full screen mode is incorrect ([39e3084](39e3084ec8))
2020-10-01 09:57:56 +00:00
semantic-release-bot db266a8cf0 1.0.0-preview.12
# [1.0.0-preview.12](https://github.com/mob-sakai/SoftMaskForUGUI/compare/v1.0.0-preview.11...v1.0.0-preview.12) (2020-09-28)

### Bug Fixes

* clickable area inverted on Metal ([3c189ff](3c189ffed6))
* in Unity 2018.x, sample import failed on Windows ([207ea9c](207ea9c1dc))
2020-09-28 01:35:57 +00:00
semantic-release-bot 9b6205070f 1.0.0-preview.11
# [1.0.0-preview.11](https://github.com/mob-sakai/SoftMaskForUGUI/compare/v1.0.0-preview.10...v1.0.0-preview.11) (2020-09-27)

### Bug Fixes

* an exception is thrown when the game view is inactive ([97e5a21](97e5a21b78)), closes [#104](https://github.com/mob-sakai/SoftMaskForUGUI/issues/104)
* graphic.materialForRendering always returns different material ([3f6acec](3f6acec67b)), closes [#103](https://github.com/mob-sakai/SoftMaskForUGUI/issues/103)
2020-09-27 09:46:59 +00:00
semantic-release-bot ded86d96af 1.0.0-preview.10
# [1.0.0-preview.10](https://github.com/mob-sakai/SoftMaskForUGUI/compare/v1.0.0-preview.9...v1.0.0-preview.10) (2020-09-14)

### Bug Fixes

* if the package was installed via openupm, an unintended directory 'Samples' was included ([d8fd47a](d8fd47aadb)), closes [#102](https://github.com/mob-sakai/SoftMaskForUGUI/issues/102)
2020-09-14 13:55:22 +00:00
semantic-release-bot 4d6a3a4f01 1.0.0-preview.9
# [1.0.0-preview.9](https://github.com/mob-sakai/SoftMaskForUGUI/compare/v1.0.0-preview.8...v1.0.0-preview.9) (2020-09-08)

### Bug Fixes

* TextMeshPro not work TMP_SubMeshUI ([56995e9](56995e9f81)), closes [#94](https://github.com/mob-sakai/SoftMaskForUGUI/issues/94)
2020-09-08 02:44:49 +00:00
semantic-release-bot 58eeefc698 1.0.0-preview.8
# [1.0.0-preview.8](https://github.com/mob-sakai/SoftMaskForUGUI/compare/v1.0.0-preview.7...v1.0.0-preview.8) (2020-09-08)

### Features

* if the 'UIMask' sprite is specified as the source image, it is suggested to use another image ([ea904db](ea904dbe3a)), closes [#82](https://github.com/mob-sakai/SoftMaskForUGUI/issues/82)
* option to disable softening completely ([dedd847](dedd847fd0)), closes [#98](https://github.com/mob-sakai/SoftMaskForUGUI/issues/98)
* use the stencil buffer outside the scene view canvas for editing ([dbab85c](dbab85c0f0)), closes [#100](https://github.com/mob-sakai/SoftMaskForUGUI/issues/100)
2020-09-08 02:33:58 +00:00
semantic-release-bot 1479064931 1.0.0-preview.7
# [1.0.0-preview.7](https://github.com/mob-sakai/SoftMaskForUGUI/compare/v1.0.0-preview.6...v1.0.0-preview.7) (2020-08-17)

### Features

* memoryless mode (depth) ([8cf202f](8cf202f958))
2020-08-17 02:38:49 +00:00
semantic-release-bot 52c3a09e61 1.0.0-preview.6
# [1.0.0-preview.6](https://github.com/mob-sakai/SoftMaskForUGUI/compare/v1.0.0-preview.5...v1.0.0-preview.6) (2020-08-17)

### Bug Fixes

* Always Include TextMeshPro Shaders ([7f24280](7f24280b95)), closes [#99](https://github.com/mob-sakai/SoftMaskForUGUI/issues/99)
2020-08-17 01:40:01 +00:00
semantic-release-bot 03a7b84fa2 1.0.0-preview.5
# [1.0.0-preview.5](https://github.com/mob-sakai/SoftMaskForUGUI/compare/v1.0.0-preview.4...v1.0.0-preview.5) (2020-06-09)

### Bug Fixes

* screen space overlay bug with game window resize ([91b7788](91b77885bc)), closes [#93](https://github.com/mob-sakai/SoftMaskForUGUI/issues/93)
2020-06-09 05:41:37 +00:00
semantic-release-bot 9aa9f568b8 1.0.0-preview.4
# [1.0.0-preview.4](https://github.com/mob-sakai/SoftMaskForUGUI/compare/v1.0.0-preview.3...v1.0.0-preview.4) (2020-06-07)

### Bug Fixes

* fix the tooltip text ([f38f034](f38f034148))

### Features

* add a new option to ignore stencil if it is not needed as a mask ([9edcb2d](9edcb2d22b))
* add a new public property 'useStencil' ([09dbaad](09dbaad203))
* improve performance ([018ec78](018ec78c75))
2020-06-07 04:19:49 +00:00
semantic-release-bot 9ad7d46a10 1.0.0-preview.3
# [1.0.0-preview.3](https://github.com/mob-sakai/SoftMaskForUGUI/compare/v1.0.0-preview.2...v1.0.0-preview.3) (2020-06-04)

### Bug Fixes

* outside interaction doesn't work when the RaycastFilter option is off ([1935650](19356500c5))

### Features

* Add ignore self graphic option. ([91c0099](91c00993b9))
* TextMeshPro support ([5b0906b](5b0906b608))

### BREAKING CHANGES

* TextMeshPro support is now an option.
If a shader or material has errors after a version upgrade, you will need to import the asset.
Please see the README for more information.
2020-06-04 04:43:18 +00:00
semantic-release-bot 7ebbdeb251 1.0.0-preview.2
# [1.0.0-preview.2](https://github.com/mob-sakai/SoftMaskForUGUI/compare/v1.0.0-preview.1...v1.0.0-preview.2) (2020-05-13)

### Bug Fixes

* compile error ([56b1791](56b1791bd3)), closes [#87](https://github.com/mob-sakai/SoftMaskForUGUI/issues/87)
2020-05-13 05:43:19 +00:00
semantic-release-bot 60ce6997e0 1.0.0-preview.1
# [1.0.0-preview.1](https://github.com/mob-sakai/SoftMaskForUGUI/compare/v0.10.0-preview.3...v1.0.0-preview.1) (2020-05-11)

### Bug Fixes

* Unintentional material destruction ([bf17b19](bf17b19ef2))

### change

* change namespace ([0347b04](0347b04fb7))

### Features

* support graphic connector ([3451521](34515216a3)), closes [#75](https://github.com/mob-sakai/SoftMaskForUGUI/issues/75) [#76](https://github.com/mob-sakai/SoftMaskForUGUI/issues/76) [#80](https://github.com/mob-sakai/SoftMaskForUGUI/issues/80)

### BREAKING CHANGES

* If your code contained the SoftMask API, it would fail to compile. Please change the namespace from  to .
* The name of the custom SoftMaskable shader must be changed. For more information, see the ‘Support soft masks with your custom shaders’ section of the README.
2020-05-11 07:34:23 +00:00
semantic-release-bot b9eb1a9b95 0.10.0-preview.3
# [0.10.0-preview.3](https://github.com/mob-sakai/SoftMaskForUGUI/compare/v0.10.0-preview.2...v0.10.0-preview.3) (2020-05-08)

### Bug Fixes

* compile error on build ([e7ff660](e7ff660aa5)), closes [#84](https://github.com/mob-sakai/SoftMaskForUGUI/issues/84)
* visual bug with ScreenSpaceCamera canvas on editor ([ec9ac44](ec9ac4481f))
2020-05-08 22:06:44 +00:00
semantic-release-bot f5f5b7e341 0.10.0-preview.2
# [0.10.0-preview.2](https://github.com/mob-sakai/SoftMaskForUGUI/compare/v0.10.0-preview.1...v0.10.0-preview.2) (2020-05-03)

### Bug Fixes

* visual bug with ScreenSpaceCamera canvas on editor ([482b967](482b96709b)), closes [#78](https://github.com/mob-sakai/SoftMaskForUGUI/issues/78)
2020-05-03 11:38:07 +00:00
semantic-release-bot a9c6dadfa1 0.10.0-preview.1
# [0.10.0-preview.1](https://github.com/mob-sakai/SoftMaskForUGUI/compare/v0.9.1...v0.10.0-preview.1) (2020-05-01)

### Bug Fixes

* softmask not working on PS4 ([b391c10](b391c103c5)), closes [#74](https://github.com/mob-sakai/SoftMaskForUGUI/issues/74)

### Features

* add sample importer ([d98a241](d98a241e78))
* raycast filter is now optional feature ([3b42727](3b427274c9)), closes [#73](https://github.com/mob-sakai/SoftMaskForUGUI/issues/73)
2020-05-01 09:38:38 +00:00
mob-sakai 4b59e3dc9b update documents for v0.9.1 2020-01-28 20:53:37 +09:00
mob-sakai fcbaeec420 fix: Projection Matrix check always true when using world space canvas 2020-01-28 19:52:47 +09:00
mob-sakai 0f74fb8255 fix: Raycast coordinates are incorrect
Close #52
2020-01-28 19:23:10 +09:00
mob-sakai f5bd6003a8 fix: Projection Matrix check always true when using world space canvas
Close #67
2020-01-28 19:11:35 +09:00
mob-sakai a7a3c41a51 fix: Update softmask not working when canvas component was deactivated
Close #66
2020-01-28 18:46:48 +09:00
iizzaya 0efcdfb78f Add the parameter to control mask transparency 2019-10-14 23:50:51 +08:00
mob-sakai 62ac172783 update documents for v0.9.0 2019-08-27 11:43:43 +09:00
mob-sakai df3e829ca8 fix: Prefab Mode in Play Mode is not supported bug #60 2019-08-27 11:39:01 +09:00
mob-sakai 6019799690 fix: Missing .meta file #59 2019-08-27 11:38:33 +09:00
Mane Function f59a4a8560 Improved work in prefab view 2019-05-13 17:35:42 +03:00
mob-sakai 7c89572540 update documents for v0.8.1 2019-05-07 19:27:04 +09:00
mob-sakai 2138a9bac2 fix #51; Unity 2019.1.1f1 compile failed 2019-05-07 16:33:40 +09:00
mob-sakai 3c36199b91 update documents for v0.8.0 2019-05-01 21:39:04 +09:00
mob-sakai 3d5ce6c241 close #49; Camera movement affects the mask rendering when on a World Space Canvas 2019-05-01 17:00:46 +09:00
mob-sakai ecce86f1fa fix #47; In overlay mode, mask will be incorrect if the root canvas's parent position are not zero 2019-03-26 20:38:28 +09:00
mob-sakai ce177b6837 update documents for v0.7.2 2019-03-16 23:39:46 +09:00
mob-sakai 662df310a2 Release temporary RT safety 2019-03-16 20:11:16 +09:00
mob-sakai 0fa3218849 fix #43; Pixels out of range may be read by raycaster 2019-03-16 20:11:16 +09:00
mob-sakai a4353a6f9e fix #42; The masked images all disappear when game view is resized 2019-03-16 20:11:16 +09:00
mob-sakai 7a9efce141 fix #44; The masked images all disappear if game view is maximized 2019-03-16 20:11:16 +09:00
mob-sakai 76cb9129e9 fix #41; Doesn't work with Screen-Space Overlay on Mac editor 2019-03-16 00:33:55 +09:00
mob-sakai 90000efd3d update documents for v0.7.2 2019-03-15 23:18:29 +09:00
mob-sakai 741c8b80c0 fix #41; Doesn't work with Screen-Space Camera and World-Space 2019-03-15 23:18:29 +09:00
mob-sakai bd6f85965e fix #41; Doesn't work with Screen-Space Overlay 2019-03-15 02:56:18 +09:00
76 changed files with 26501 additions and 1703 deletions

12
.github/FUNDING.yml vendored Normal file
View File

@ -0,0 +1,12 @@
# These are supported funding model platforms
github: mob-sakai # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: mob_sakai # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']

35
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@ -0,0 +1,35 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: bug
assignees: mob-sakai
---
NOTE: Your issue may already be reported! Please search on the [issue tracker](../) before creating one.
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Environment (please complete the following information):**
- Version [e.g. 1.0.0]
- Platform: [e.g. Editor(Windows/Mac), Standalone(Windows/Mac), iOS, Android, WebGL]
- Unity version: [e.g. 2018.2.8f1]
- Build options: [e.g. IL2CPP, .Net 4.x, LWRP]
**Additional context**
Add any other context about the problem here.

View File

@ -0,0 +1,22 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: enhancement
assignees: mob-sakai
---
NOTE: Your issue may already be reported! Please search on the [issue tracker](../) before creating one.
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

16
.github/ISSUE_TEMPLATE/question.md vendored Normal file
View File

@ -0,0 +1,16 @@
---
name: Question
about: Ask a question about this project
title: ''
labels: question
assignees: mob-sakai
---
NOTE: Your issue may already be reported! Please search on the [issue tracker](../) before creating one.
**Describe what help do you need**
A description of the question.
**Additional context**
Add any other context or screenshots about the question here.

9
.github/pull_request_template.md vendored Normal file
View File

@ -0,0 +1,9 @@
---
name: Pull Request
about: Create a pull request
title: ''
assignees: mob-sakai
---
**NOTE: Create a pull request to merge into `develop` branch**

25
.github/workflows/release.yml vendored Normal file
View File

@ -0,0 +1,25 @@
name: release
on:
workflow_dispatch:
push:
branches:
- preview
- main
- v*.x
tags-ignore:
- "**"
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: cycjimmy/semantic-release-action@v2
with:
extra_plugins: |
@semantic-release/changelog
@semantic-release/git
env:
GITHUB_TOKEN: ${{ github.token }}

93
.github/workflows/test.yml vendored Normal file
View File

@ -0,0 +1,93 @@
# Secrets
# UNITY_LICENSE:
name: test
on:
push:
branches:
- develop
tags:
- "!*"
pull_request:
types:
- opened
- synchronize
jobs:
unity-test:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
unityVersion: [
"2018.3.14f1",
"2018.4.30f1",
"2019.2.21f1",
"2019.3.15f1",
"2019.4.16f1",
"2020.1.17f1",
"2020.2.1f1",
]
steps:
# Checkout sandbox project
- uses: actions/checkout@v2
with:
ref: sandbox
submodules: true
fetch-depth: 0
# Update package submodule
- name: "Update package submodule"
working-directory: Packages/dev
run: git checkout ${{ github.sha }}
- uses: actions/cache@v2
with:
path: Library
key: Library-${{ matrix.unityVersion }}-${{ github.sha }}
restore-keys: |
Library-${{ matrix.unityVersion }}-
Library-
# Install codecoverage package
- name: "Install codecoverage package"
if: startsWith(matrix.unityVersion, '2019.4.')
run: |
npx openupm-cli add -f com.unity.testtools.codecoverage@0.4.0-preview
# Run tests
- name: "Run tests"
uses: game-ci/unity-test-runner@main
with:
unityVersion: ${{ matrix.unityVersion }}
customParameters: -nographics -enableCodeCoverage -coverageOptions assemblyFilters:+Coffee.UIParticle.*Tests
env:
UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }}
- uses: actions/upload-artifact@v2
if: always()
with:
name: TestResults-${{ matrix.unityVersion }}
path: |
artifacts/*.xml
CodeCoverage/**/TestCoverageResults_*.xml
publish:
needs: unity-test
runs-on: ubuntu-latest
if: always()
steps:
- uses: actions/download-artifact@v2
with:
path: artifacts
- uses: testspace-com/setup-testspace@v1
with:
domain: ${{github.repository_owner}}
- name: Push test results
if: always()
run: |
testspace `find . -name '*.xml' | tr '\n' ' '`

45
.gitignore vendored
View File

@ -1,45 +0,0 @@
[Ll]ibrary/
[Tt]emp/
[Oo]bj/
[Bb]uild/
/[Bb]uilds/
/Assets/AssetStoreTools*
# Autogenerated VS/MD solution and project files
ExportedObj/
*.csproj
*.unityproj
*.sln
*.suo
*.tmp
*.user
*.userprefs
*.pidb
*.booproj
*.svd
# Unity3D generated meta files
*.pidb.meta
# Unity3D Generated File On Crash Reports
sysinfo.txt
# Mac
*.DS_Store
# Builds
*.apk
# Packages
build.app
unity.log
.vs/
_Android/
_iOS/
_WebGL/
_Standalone/
Assets/TextMesh Pro/
Assets/TextMesh Pro.meta

25
.releaserc.json Normal file
View File

@ -0,0 +1,25 @@
{
"branches": [
"+([0-9])?(.{+([0-9]),x}).x",
"master",
"main",
{
"name": "preview",
"prerelease": true
}
],
"tagFormat": "${version}",
"plugins": [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
"@semantic-release/changelog",
[
"@semantic-release/npm",
{
"npmPublish": false
}
],
"@semantic-release/git",
"@semantic-release/github"
]
}

View File

@ -1,5 +1,255 @@
## [1.0.2](https://github.com/mob-sakai/SoftMaskForUGUI/compare/1.0.1...1.0.2) (2022-05-15)
### Bug Fixes
* support TextMeshPro v2 or later ([c85409e](https://github.com/mob-sakai/SoftMaskForUGUI/commit/c85409e56ff09607244061c59518f5d1f460a918))
## [1.0.1](https://github.com/mob-sakai/SoftMaskForUGUI/compare/1.0.0...1.0.1) (2022-05-15)
### Bug Fixes
* applied a workaround to fix a Microsoft HLSL compiler issue ([50c41f2](https://github.com/mob-sakai/SoftMaskForUGUI/commit/50c41f29ccc9b70acdd7f15490debd8eacf5a102)), closes [#131](https://github.com/mob-sakai/SoftMaskForUGUI/issues/131)
* fixed shader compilation in some platforms ([40b450b](https://github.com/mob-sakai/SoftMaskForUGUI/commit/40b450ba24e77c34c97fe8411f7b0b1dd103d487))
# [1.0.0](https://github.com/mob-sakai/SoftMaskForUGUI/compare/0.9.1...1.0.0) (2021-02-24)
### Features
* release 1.0.0 ([127b455](https://github.com/mob-sakai/SoftMaskForUGUI/commit/127b455f38889dfe9a1c6ae5449d2c537d2a4d78))
### BREAKING CHANGES
* release 1.0.0
# [1.0.0-preview.14](https://github.com/mob-sakai/SoftMaskForUGUI/compare/v1.0.0-preview.13...v1.0.0-preview.14) (2020-10-08)
### Bug Fixes
* incorrect behavior when a world space canvas and an overlay canvas are enabled together ([a6e82fa](https://github.com/mob-sakai/SoftMaskForUGUI/commit/a6e82fa2a7baa06aa4e1fb7e4a8099c5e1039d67)), closes [#107](https://github.com/mob-sakai/SoftMaskForUGUI/issues/107)
# [1.0.0-preview.13](https://github.com/mob-sakai/SoftMaskForUGUI/compare/v1.0.0-preview.12...v1.0.0-preview.13) (2020-10-01)
### Bug Fixes
* screen resolution in full screen mode is incorrect ([39e3084](https://github.com/mob-sakai/SoftMaskForUGUI/commit/39e3084ec840293f2ad461f50d51eeafe66cbebf))
# [1.0.0-preview.12](https://github.com/mob-sakai/SoftMaskForUGUI/compare/v1.0.0-preview.11...v1.0.0-preview.12) (2020-09-28)
### Bug Fixes
* clickable area inverted on Metal ([3c189ff](https://github.com/mob-sakai/SoftMaskForUGUI/commit/3c189ffed61baa6806aadc6ff89c41b9102491b5))
* in Unity 2018.x, sample import failed on Windows ([207ea9c](https://github.com/mob-sakai/SoftMaskForUGUI/commit/207ea9c1dc4117ab6c00e70290d5f7651fa906d8))
# [1.0.0-preview.11](https://github.com/mob-sakai/SoftMaskForUGUI/compare/v1.0.0-preview.10...v1.0.0-preview.11) (2020-09-27)
### Bug Fixes
* an exception is thrown when the game view is inactive ([97e5a21](https://github.com/mob-sakai/SoftMaskForUGUI/commit/97e5a21b784ae9081aec8f17603355eef7e8b2b9)), closes [#104](https://github.com/mob-sakai/SoftMaskForUGUI/issues/104)
* graphic.materialForRendering always returns different material ([3f6acec](https://github.com/mob-sakai/SoftMaskForUGUI/commit/3f6acec67b3c0467670eb8f4b10928fa8724e082)), closes [#103](https://github.com/mob-sakai/SoftMaskForUGUI/issues/103)
# [1.0.0-preview.10](https://github.com/mob-sakai/SoftMaskForUGUI/compare/v1.0.0-preview.9...v1.0.0-preview.10) (2020-09-14)
### Bug Fixes
* if the package was installed via openupm, an unintended directory 'Samples' was included ([d8fd47a](https://github.com/mob-sakai/SoftMaskForUGUI/commit/d8fd47aadbbb99fc6ebd830820abaee4ab1d9cf2)), closes [#102](https://github.com/mob-sakai/SoftMaskForUGUI/issues/102)
# [1.0.0-preview.9](https://github.com/mob-sakai/SoftMaskForUGUI/compare/v1.0.0-preview.8...v1.0.0-preview.9) (2020-09-08)
### Bug Fixes
* TextMeshPro not work TMP_SubMeshUI ([56995e9](https://github.com/mob-sakai/SoftMaskForUGUI/commit/56995e9f81218a40cfd777f51b9f11a86775a131)), closes [#94](https://github.com/mob-sakai/SoftMaskForUGUI/issues/94)
# [1.0.0-preview.8](https://github.com/mob-sakai/SoftMaskForUGUI/compare/v1.0.0-preview.7...v1.0.0-preview.8) (2020-09-08)
### Features
* if the 'UIMask' sprite is specified as the source image, it is suggested to use another image ([ea904db](https://github.com/mob-sakai/SoftMaskForUGUI/commit/ea904dbe3afd9f18eab0d449bd08bf78375fd53d)), closes [#82](https://github.com/mob-sakai/SoftMaskForUGUI/issues/82)
* option to disable softening completely ([dedd847](https://github.com/mob-sakai/SoftMaskForUGUI/commit/dedd847fd0c5faa5094a08293600cbb8aa4b6456)), closes [#98](https://github.com/mob-sakai/SoftMaskForUGUI/issues/98)
* use the stencil buffer outside the scene view canvas for editing ([dbab85c](https://github.com/mob-sakai/SoftMaskForUGUI/commit/dbab85c0f0bd8a58b8ab09306bed351ad1cf6375)), closes [#100](https://github.com/mob-sakai/SoftMaskForUGUI/issues/100)
# [1.0.0-preview.7](https://github.com/mob-sakai/SoftMaskForUGUI/compare/v1.0.0-preview.6...v1.0.0-preview.7) (2020-08-17)
### Features
* memoryless mode (depth) ([8cf202f](https://github.com/mob-sakai/SoftMaskForUGUI/commit/8cf202f958be902d34994f3c07082f893f9b455b))
# [1.0.0-preview.6](https://github.com/mob-sakai/SoftMaskForUGUI/compare/v1.0.0-preview.5...v1.0.0-preview.6) (2020-08-17)
### Bug Fixes
* Always Include TextMeshPro Shaders ([7f24280](https://github.com/mob-sakai/SoftMaskForUGUI/commit/7f24280b9586f5ccc50d233d0eb4241bb8cd9b10)), closes [#99](https://github.com/mob-sakai/SoftMaskForUGUI/issues/99)
# [1.0.0-preview.5](https://github.com/mob-sakai/SoftMaskForUGUI/compare/v1.0.0-preview.4...v1.0.0-preview.5) (2020-06-09)
### Bug Fixes
* screen space overlay bug with game window resize ([91b7788](https://github.com/mob-sakai/SoftMaskForUGUI/commit/91b77885bc5f60cb59e8081009982a4635f9245c)), closes [#93](https://github.com/mob-sakai/SoftMaskForUGUI/issues/93)
# [1.0.0-preview.4](https://github.com/mob-sakai/SoftMaskForUGUI/compare/v1.0.0-preview.3...v1.0.0-preview.4) (2020-06-07)
### Bug Fixes
* fix the tooltip text ([f38f034](https://github.com/mob-sakai/SoftMaskForUGUI/commit/f38f0341480cfd8eda6bea3e488c7ae052b89924))
### Features
* add a new option to ignore stencil if it is not needed as a mask ([9edcb2d](https://github.com/mob-sakai/SoftMaskForUGUI/commit/9edcb2d22be25c285b0a7f853314884c3e9df499))
* add a new public property 'useStencil' ([09dbaad](https://github.com/mob-sakai/SoftMaskForUGUI/commit/09dbaad203fa9eaaa16abf683add04267f82439d))
* improve performance ([018ec78](https://github.com/mob-sakai/SoftMaskForUGUI/commit/018ec78c759745907c2e06d3ab09167939bdb05a))
# [1.0.0-preview.3](https://github.com/mob-sakai/SoftMaskForUGUI/compare/v1.0.0-preview.2...v1.0.0-preview.3) (2020-06-04)
### Bug Fixes
* outside interaction doesn't work when the RaycastFilter option is off ([1935650](https://github.com/mob-sakai/SoftMaskForUGUI/commit/19356500c5b777aa5857fa5176fc09f0fd7951cb))
### Features
* Add ignore self graphic option. ([91c0099](https://github.com/mob-sakai/SoftMaskForUGUI/commit/91c00993b9afbdda0386b8e426e181f8f31618b9))
* TextMeshPro support ([5b0906b](https://github.com/mob-sakai/SoftMaskForUGUI/commit/5b0906b6086193bc8f62fa174955c9df901ef3f0))
### BREAKING CHANGES
* TextMeshPro support is now an option.
If a shader or material has errors after a version upgrade, you will need to import the asset.
Please see the README for more information.
# [1.0.0-preview.2](https://github.com/mob-sakai/SoftMaskForUGUI/compare/v1.0.0-preview.1...v1.0.0-preview.2) (2020-05-13)
### Bug Fixes
* compile error ([56b1791](https://github.com/mob-sakai/SoftMaskForUGUI/commit/56b1791bd3995ba387b1dc866ea68325b56a8830)), closes [#87](https://github.com/mob-sakai/SoftMaskForUGUI/issues/87)
# [1.0.0-preview.1](https://github.com/mob-sakai/SoftMaskForUGUI/compare/v0.10.0-preview.3...v1.0.0-preview.1) (2020-05-11)
### Bug Fixes
* Unintentional material destruction ([bf17b19](https://github.com/mob-sakai/SoftMaskForUGUI/commit/bf17b19ef29ea35b54cbaf5473611ad58136540a))
### change
* change namespace ([0347b04](https://github.com/mob-sakai/SoftMaskForUGUI/commit/0347b04fb70d970b3558ebb454ecd2dbbd3dfce0))
### Features
* support graphic connector ([3451521](https://github.com/mob-sakai/SoftMaskForUGUI/commit/34515216a39d69601595dffbbac1803da3a27379)), closes [#75](https://github.com/mob-sakai/SoftMaskForUGUI/issues/75) [#76](https://github.com/mob-sakai/SoftMaskForUGUI/issues/76) [#80](https://github.com/mob-sakai/SoftMaskForUGUI/issues/80)
### BREAKING CHANGES
* If your code contained the SoftMask API, it would fail to compile. Please change the namespace from `Coffee.UIExtensions` to `Coffee.UISoftMask`.
* The name of the custom SoftMaskable shader must be changed. For more information, see the Support soft masks with your custom shaders section of the README.
# [0.10.0-preview.3](https://github.com/mob-sakai/SoftMaskForUGUI/compare/v0.10.0-preview.2...v0.10.0-preview.3) (2020-05-08)
### Bug Fixes
* compile error on build ([e7ff660](https://github.com/mob-sakai/SoftMaskForUGUI/commit/e7ff660aa5539ae0a2fb88b49582a5b7f7c11c45)), closes [#84](https://github.com/mob-sakai/SoftMaskForUGUI/issues/84)
* visual bug with ScreenSpaceCamera canvas on editor ([ec9ac44](https://github.com/mob-sakai/SoftMaskForUGUI/commit/ec9ac4481f9b1ecaf4044743efe02533e7f1ff66))
# [0.10.0-preview.2](https://github.com/mob-sakai/SoftMaskForUGUI/compare/v0.10.0-preview.1...v0.10.0-preview.2) (2020-05-03)
### Bug Fixes
* visual bug with ScreenSpaceCamera canvas on editor ([482b967](https://github.com/mob-sakai/SoftMaskForUGUI/commit/482b96709b9dce680e48214df26c81b7e963dc09)), closes [#78](https://github.com/mob-sakai/SoftMaskForUGUI/issues/78)
# [0.10.0-preview.1](https://github.com/mob-sakai/SoftMaskForUGUI/compare/v0.9.1...v0.10.0-preview.1) (2020-05-01)
### Bug Fixes
* softmask not working on PS4 ([b391c10](https://github.com/mob-sakai/SoftMaskForUGUI/commit/b391c103c57cdb3a848701ee5663b86b962031cd)), closes [#74](https://github.com/mob-sakai/SoftMaskForUGUI/issues/74)
### Features
* add sample importer ([d98a241](https://github.com/mob-sakai/SoftMaskForUGUI/commit/d98a241e78f81a92bf22181d94a7622c6a65b589))
* raycast filter is now optional feature ([3b42727](https://github.com/mob-sakai/SoftMaskForUGUI/commit/3b427274c9842c46dd90fa8845dc5156822b04e1)), closes [#73](https://github.com/mob-sakai/SoftMaskForUGUI/issues/73)
# Changelog
## [v0.9.1](https://github.com/mob-sakai/SoftMaskForUGUI/tree/v0.9.1) (2020-01-28)
[Full Changelog](https://github.com/mob-sakai/SoftMaskForUGUI/compare/v0.9.0...v0.9.1)
**Implemented enhancements:**
- Add the parameter to control mask transparency [\#62](https://github.com/mob-sakai/SoftMaskForUGUI/pull/62) ([IIzzaya](https://github.com/IIzzaya))
**Fixed bugs:**
- Projection Matrix check always true when using world space canvas [\#67](https://github.com/mob-sakai/SoftMaskForUGUI/issues/67)
- Update softmask not working when canvas component was deactivated [\#66](https://github.com/mob-sakai/SoftMaskForUGUI/issues/66)
- Raycast coordinates are incorrect [\#52](https://github.com/mob-sakai/SoftMaskForUGUI/issues/52)
## [v0.9.0](https://github.com/mob-sakai/SoftMaskForUGUI/tree/v0.9.0) (2019-08-27)
[Full Changelog](https://github.com/mob-sakai/SoftMaskForUGUI/compare/v0.8.1...v0.9.0)
**Implemented enhancements:**
- Improved work in prefab view [\#55](https://github.com/mob-sakai/SoftMaskForUGUI/pull/55) ([ManeFunction](https://github.com/ManeFunction))
**Fixed bugs:**
- Prefab Mode in Play Mode is not supported [\#60](https://github.com/mob-sakai/SoftMaskForUGUI/issues/60)
- Missing .meta file [\#59](https://github.com/mob-sakai/SoftMaskForUGUI/issues/59)
## [v0.8.1](https://github.com/mob-sakai/SoftMaskForUGUI/tree/v0.8.1) (2019-05-07)
[Full Changelog](https://github.com/mob-sakai/SoftMaskForUGUI/compare/v0.8.0...v0.8.1)
**Fixed bugs:**
- Unity 2018.x compile failed [\#51](https://github.com/mob-sakai/SoftMaskForUGUI/issues/51)
## [v0.8.0](https://github.com/mob-sakai/SoftMaskForUGUI/tree/v0.8.0) (2019-05-01)
[Full Changelog](https://github.com/mob-sakai/SoftMaskForUGUI/compare/v0.7.2...v0.8.0)
Camera movement affects the mask rendering when on a World Space Canvas.
![](https://user-images.githubusercontent.com/12690315/57015752-68540b80-6c51-11e9-8511-2d4534dd9d58.gif)
**Fixed bugs:**
- In overlay mode, mask will be incorrect if the root canvas's parent position are not zero [\#47](https://github.com/mob-sakai/SoftMaskForUGUI/issues/47)
## [v0.7.2](https://github.com/mob-sakai/SoftMaskForUGUI/tree/v0.7.2) (2019-03-16)
[Full Changelog](https://github.com/mob-sakai/SoftMaskForUGUI/compare/v0.7.1...v0.7.2)
**Fixed bugs:**
- The masked images all disappear if game view is maximized [\#44](https://github.com/mob-sakai/SoftMaskForUGUI/issues/44)
- Pixels out of range may be read by raycaster [\#43](https://github.com/mob-sakai/SoftMaskForUGUI/issues/43)
- The masked images all disappear when the game view is resized [\#42](https://github.com/mob-sakai/SoftMaskForUGUI/issues/42)
- Doesn't work with Screen-Space Overlay [\#41](https://github.com/mob-sakai/SoftMaskForUGUI/issues/41)
## [v0.7.1](https://github.com/mob-sakai/SoftMaskForUGUI/tree/v0.7.1) (2019-03-11)
[Full Changelog](https://github.com/mob-sakai/SoftMaskForUGUI/compare/v0.7.0...v0.7.1)

84
CODE_OF_CONDUCT.md Normal file
View File

@ -0,0 +1,84 @@
# Contributor Covenant Code of Conduct
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment for our community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience
* Focusing on what is best not just for us as individuals, but for the overall community
Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or
advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful.
Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at sakai861104@gmail.com. All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series of actions.
**Consequence**: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within the community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.0,
available at https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
Community Impact Guidelines were inspired by [Mozilla's code of conduct enforcement ladder](https://github.com/mozilla/diversity).
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at https://www.contributor-covenant.org/translations.

7
CODE_OF_CONDUCT.md.meta Normal file
View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 5f41710f6064b41fbaf51e156c625d77
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

30
CONTRIBUTING.md Normal file
View File

@ -0,0 +1,30 @@
# Contributing
## How to Contribute
#### Code of Conduct
This repository has adopted the Contributor Covenant as it's
Code of Conduct. It is expected that participants adhere to it.
#### Proposing a Change
If you are unsure about whether or not a change is desired,
you can create an issue. This is useful because it creates
the possibility for a discussion that's visible to everyone.
When fixing a bug it is fine to submit a pull request right away.
#### Sending a Pull Request
Steps to be performed to submit a pull request:
1. Fork the repository and create your branch from `develop`.
2. If you have fixed a bug or added code that should be tested, add tests.
3. Click `Window > Generals > Test Runner` to test
4. Commit with a massage based on [Angular Commit Message Conventions](https://gist.github.com/stephenparish/9941e89d80e2bc58a153).
5. Fill out the description, link any related issues and submit your pull request.
#### License
By contributing to this repository, you agree that your contributions will be licensed under its MIT license.

7
CONTRIBUTING.md.meta Normal file
View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 5f0ea36eaae4d4ed48433b77e190bd6d
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

8
Icons.meta Normal file
View File

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

View File

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

Before

Width:  |  Height:  |  Size: 4.1 KiB

After

Width:  |  Height:  |  Size: 4.1 KiB

View File

@ -1,4 +1,4 @@
Copyright 2018 mob-sakai
Copyright 2018-2020 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:

341
README.md
View File

@ -1,30 +1,29 @@
SoftMaskForUGUI
===
Soft masking for uGUI elements in Unity.
**:warning: NOTE: Do not use [the obsolete tags and branches](https://github.com/mob-sakai/SoftMaskForUGUI/issues/112) to reference the package. They will be removed in near future. :warning:**
UI Soft Mask is a smooth masking component for Unity UI (uGUI) elements.
![](https://user-images.githubusercontent.com/12690315/50282438-18408d80-0496-11e9-8f86-81e804edadd4.png)
[![](https://img.shields.io/github/release/mob-sakai/SoftMaskForUGUI.svg?label=latest%20version)](https://github.com/mob-sakai/SoftMaskForUGUI/releases)
[![](https://img.shields.io/github/release-date/mob-sakai/SoftMaskForUGUI.svg)](https://github.com/mob-sakai/SoftMaskForUGUI/releases)
![](https://img.shields.io/badge/unity-2017%2B-green.svg)
[![](https://img.shields.io/github/license/mob-sakai/SoftMaskForUGUI.svg)](https://github.com/mob-sakai/SoftMaskForUGUI/blob/upm/LICENSE.txt)
[![](https://img.shields.io/npm/v/com.coffee.softmask-for-ugui?label=openupm&registry_uri=https://package.openupm.com)](https://openupm.com/packages/com.coffee.softmask-for-ugui/)
[![](https://img.shields.io/github/v/release/mob-sakai/SoftMaskForUGUI?include_prereleases)](https://github.com/mob-sakai/SoftMaskForUGUI/releases)
[![](https://img.shields.io/github/release-date/mob-sakai/SoftMaskForUGUI.svg)](https://github.com/mob-sakai/SoftMaskForUGUI/releases)
![](https://img.shields.io/badge/unity-2017.1%20or%20later-green.svg)
[![](https://img.shields.io/github/license/mob-sakai/SoftMaskForUGUI.svg)](https://github.com/mob-sakai/SoftMaskForUGUI/blob/main/LICENSE.txt)
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-orange.svg)](http://makeapullrequest.com)
[![](https://img.shields.io/github/watchers/mob-sakai/SoftMaskForUGUI.svg?style=social&label=Watch)](https://github.com/mob-sakai/SoftMaskForUGUI/subscription)
[![](https://img.shields.io/twitter/follow/mob_sakai.svg?label=Follow&style=social)](https://twitter.com/intent/follow?screen_name=mob_sakai)
<< [Description](#Description) | [WebGL Demo](#demo) | [Download](https://github.com/mob-sakai/SoftMaskForUGUI/releases) | [Usage](#usage) | [Development Note](#development-note) >>
### What's new? [See changelog ![](https://img.shields.io/github/release-date/mob-sakai/SoftMaskForUGUI.svg?label=last%20updated)](https://github.com/mob-sakai/SoftMaskForUGUI/blob/develop/CHANGELOG.md)
### Do you want to receive notifications for new releases? [Watch this repo ![](https://img.shields.io/github/watchers/mob-sakai/SoftMaskForUGUI.svg?style=social&label=Watch)](https://github.com/mob-sakai/SoftMaskForUGUI/subscription)
### Support me on Patreon! [![become_a_patron](https://user-images.githubusercontent.com/12690315/50731629-3b18b480-11ad-11e9-8fad-4b13f27969c1.png)](https://www.patreon.com/join/2343451?)
<< [Description](#Description) | [WebGL Demo](#demo) | [Installation](#installation) | [Usage](#usage) | [For Your Custom Shader](#support-soft-masks-with-your-custom-shaders) | [Contributing](#contributing) >>
<br><br><br><br>
## Description
SoftMask is a smooth masking component for uGUI elements in Unity.
By using SoftMask instead of default Mask, rounded edges of UI elements can be expressed beautifully.
By using SoftMask instead of the default Mask component, you can beautifully represent the rounded edges of UI elements.
![](https://user-images.githubusercontent.com/12690315/50282806-4b375100-0497-11e9-891c-35309d332c7b.png)
@ -43,7 +42,7 @@ By using SoftMask instead of default Mask, rounded edges of UI elements can be e
![](https://user-images.githubusercontent.com/12690315/48708328-a0d4cf80-ec45-11e8-9945-e877faabc968.png)
* Support overlay, camera space and world space.
![](https://user-images.githubusercontent.com/12690315/48708329-a0d4cf80-ec45-11e8-8328-16b697f981ec.png)
* Raycast is filtered only for the visible part.
* (Option) Raycast is filtered only for the visible part.
![](https://user-images.githubusercontent.com/12690315/48708330-a16d6600-ec45-11e8-94bf-afecd1bd9a39.png)
* Contain soft maskable UI shader.
* Support soft masks in your custom shaders by adding just 3 lines. For details, please see [Development Note](#support-soft-masks-in-your-custom-shaders).
@ -55,251 +54,200 @@ By using SoftMask instead of default Mask, rounded edges of UI elements can be e
![](https://user-images.githubusercontent.com/12690315/50284153-76bc3a80-049b-11e9-8c55-719af897960a.png)
* Preview soft mask buffer in inspector.
![](https://user-images.githubusercontent.com/12690315/50284151-7459e080-049b-11e9-9cd3-24fb476766dc.png)
* Support TextMeshPro.
![](https://user-images.githubusercontent.com/12690315/50284145-71f78680-049b-11e9-8be1-ac0ccbdf0144.png)
* Make multiple holes on one background by 'Parts of parent' option
* Make multiple holes on one background by 'Parts of parent' option.
![](https://user-images.githubusercontent.com/12690315/54102470-f5c26e80-440b-11e9-89d1-899aa4dca00d.png)
* [Support TextMeshPro](#support-textmeshpro)
#### Components
|Component|Description|Screenshot|
|-|-|-|
|SoftMask|Use instead of Mask for smooth masking.<br><br>**Show Mask Graphic:** Show the graphic that is associated with the Mask render area.<br>**Desampling Rate:** The desampling rate for soft mask buffer. The larger the value, the better the performance but the lower the quality.<br>**Softness:** The value used by the soft mask to select the area of influence defined over the soft mask's graphic.<br>**Ignore Parent:** Should the soft mask ignore parent soft masks?<br>**Part Of Parent:** Is the soft mask a part of parent soft mask?|<img src="https://user-images.githubusercontent.com/12690315/50319746-377a0200-050c-11e9-96ae-a3a0ec81765f.png" width="600px">|
|SoftMaskable|Add this component to Graphic under SoftMask for smooth masking.<br><br>**Inverse:** The graphic will be visible only in areas where no mask is present.|<img src="https://user-images.githubusercontent.com/12690315/50319747-39dc5c00-050c-11e9-85fa-dd6ea9065daf.png" width="600px">|
| Component | Description | Screenshot |
| ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------- |
| SoftMask | Use instead of Mask for smooth masking.<br><br>**Show Mask Graphic:** Show the graphic that is associated with the Mask render area.<br>**Desampling Rate:** The desampling rate for soft mask buffer. The larger the value, the better the performance but the lower the quality.<br>**Softness:** The value used by the soft mask to select the area of influence defined over the soft mask's graphic.<br>**Ignore Parent:** Should the soft mask ignore parent soft masks?<br>**Part Of Parent:** Is the soft mask a part of parent soft mask? | ![softmask][] |
| SoftMaskable | Add this component to Graphic under SoftMask for smooth masking.<br><br>**Use Stencil:** Use stencil buffer to mask. If disabled, the stencil buffer is ignored.<br>**RaycastFilter:** Use soft-masked raycast target. **This option is expensive.**<br>**Mask Interaction:** The interaction for each mask layers. | ![softmaskable][] |
[softmask]:https://user-images.githubusercontent.com/12690315/90349065-44e5e780-e073-11ea-8ca2-c005bff90def.png
[softmaskable]:https://user-images.githubusercontent.com/12690315/90349068-47e0d800-e073-11ea-9749-18df13b8cb87.png
<br><br><br><br>
## Demo
[WebGL Demo](http://mob-sakai.github.io/SoftMaskForUGUI)
<br><br><br><br>
## Install
#### Using UnityPackageManager (for Unity 2018.3+)
<br><br><br><br>
## Installation
#### Requirement
* Unity 2017.1 or later (2018.x, 2019.x and 2020.x are included)
* No other SDK are required
#### Using OpenUPM (for Unity 2018.3 or later)
This package is available on [OpenUPM](https://openupm.com).
You can install it via [openupm-cli](https://github.com/openupm/openupm-cli).
```
openupm add com.coffee.softmask-for-ugui
```
#### Using Git (for Unity 2018.3 or later)
Find the manifest.json file in the Packages folder of your project and edit it to look like this:
```js
{
"dependencies": {
"com.coffee.softmask-for-ugui": "https://github.com/mob-sakai/SoftMaskForUGUI.git#0.7.0",
"com.coffee.softmask-for-ugui": "https://github.com/mob-sakai/SoftMaskForUGUI.git",
...
},
}
```
To update the package, change `#{version}` to the target version.
Or, use [UpmGitExtension](https://github.com/mob-sakai/UpmGitExtension).
#### Using .unitypackage file (for Unity 2017.1+)
To update the package, change suffix `#{version}` to the target version.
* e.g. `"com.coffee.softmask-for-ugui": "https://github.com/mob-sakai/SoftMaskForUGUI.git#1.0.0",`
Or, use [UpmGitExtension](https://github.com/mob-sakai/UpmGitExtension) to install and update the package.
#### For Unity 2018.2 or earlier
1. Download a source code zip file from [Releases](https://github.com/mob-sakai/SoftMaskForUGUI/releases) page
2. Extract it
3. Import it into the following directory in your Unity project
- `Packages` (It works as an embedded package. For Unity 2018.1 or later)
- `Assets` (Legacy way. For Unity 2017.1 or later)
Download `*.unitypackage` from [Releases](https://github.com/mob-sakai/SoftMaskForUGUI/releases) and import the package into your Unity project.
Select `Assets > Import Package > Custom Package` from the menu.
![](https://user-images.githubusercontent.com/12690315/46570979-edbb5a00-c9a7-11e8-845d-c5ee279effec.png)
<br><br><br><br>
## How to play demo
* Import `SoftMask_Demo.unitypackage` into your project.
* The unitypackage exists in `Assets/Assets/Coffee/UIExtensions/SoftMaskForUGUI` or `Packages/Soft Mask For uGUI`.
![](https://user-images.githubusercontent.com/12690315/51080546-ff3b9d00-1720-11e9-8a58-9e22003714af.png)
* Open SoftMask_Demo scene and play it.
* The demo requires `TextMeshPro` and `TextMeshPro Essential Resources`. Import it before playing.
- For Unity 2019.1 or later
- Open `Package Manager` window and select `UI Soft Mask` package in package list and click `Demo > Import in project` button
- For Unity 2018.4 or earlier
- Click `Assets/Samples/UISoftMask/Import Demo` from menu
The assets will be imported into `Assets/Samples/UI Soft Mask/{version}/Demo`.
Open `UISoftMask_Demo` scene and play it.
<br><br><br><br>
## Usage
1. Add SoftMask component instead of Mask component.
Or, convert existing Mask component to SoftMask component from the context menu.
1. Add a SoftMask component instead of Mask component.
Or, convert an existing Mask component to SoftMask component from the context menu.
![](https://user-images.githubusercontent.com/12690315/48659018-902e2900-ea8e-11e8-9b6e-224365cdde7f.png)
2. Add SoftMaskable components to the child UI elements of SoftMask component.
2. Add a SoftMaskable components to the child UI elements of the SoftMask component.
![](https://user-images.githubusercontent.com/12690315/48704424-d4a9f800-ec39-11e8-8d65-8b7d1975750c.png)
Or, add SoftMaskable components from the inspector of SoftMask component.
Or, add a SoftMaskable components from the inspector of the SoftMask component.
![](https://user-images.githubusercontent.com/12690315/50284153-76bc3a80-049b-11e9-8c55-719af897960a.png)
3. Adjust softness of SoftMask.
3. Adjust softness setting of SoftMask.
![](https://user-images.githubusercontent.com/12690315/48661087-01ca9f00-eab0-11e8-8878-772a1ed1fb7b.gif)
4. Enjoy!
##### Requirement
* Unity 2017+ *(including Unity 2018.x)*
* No other SDK are required
<br><br><br><br>
## Usage with TextMeshPro
To use SoftMask with TextMeshPro, import a sample asset.
- For Unity 2019.1 or later
- Open `Package Manager` window and select `UI Soft Mask` package in package list and click `TextMeshPro Support > Import in project` button
- For Unity 2018.4 or earlier
- Click `Assets/Samples/UISoftMask/Import TextMeshPro Support` from menu
The assets will be imported into `Assets/Samples/UI Soft Mask/{version}/TextMeshPro Support`.
**NOTE:** You must import `TMP Essential Resources` before using. They include shaders, fonts, etc.
![](https://user-images.githubusercontent.com/12690315/83823700-8bcc6e00-a70f-11ea-8177-942860b7d4f0.png)
**NOTE:** If the shader error is not resolved, reimport the shader. Or, import the `TextMeshPro Support` again.
<br><br><br><br>
## Development Note
#### Support soft masks in your custom shaders
## Support soft masks with your custom shaders
You can support soft masks in your custom shaders, by adding just 3 lines!
Only a few steps are needed to support soft mask in your custom shaders!
1. Add `#pragma` and `#include`. `SOFTMASK_EDITOR` is a keyword for editor, not included in the build.
1. Duplicate your shader file and add the ` (SoftMaskable)` suffix to the file name.
```
#include "Assets/Coffee/UIExtensions/SoftMaskForUGUI/SoftMask.cginc"
Your_Custom_Shader.shader
-> Your_Custom_Shader (SoftMaskable).shader
```
1. Modify the shader name (defined at the beginning of the shader file) as follows:
- Add `Hidden/` prefix
- Add ` (SoftMaskable)` suffix
```
Shader "UI/Your_Custom_Shader"
-> Shader "Hidden/UI/Your_Custom_Shader (SoftMaskable)"
```
1. Add `#pragma` and `#include` directives, where `SOFTMASK_EDITOR` is an editor-only keyword and is not included in the build.
If you didn't use package manager to install, include `SoftMask.cginc` in the appropriate path instead.
```
#include "Packages/com.coffee.softmask-for-ugui/Shaders/SoftMask.cginc"
#pragma shader_feature __ SOFTMASK_EDITOR
```
2. Apply a soft mask in the fragment shader. `IN.vertex` is clip position.
2. Apply a soft mask in the fragment shader.
This operation determines the final alpha according to the soft mask buffer.
- `IN.vertex`: the clip position
- `IN.worldPosition`: the world position
```
color.a *= SoftMask(IN.vertex);
color.a *= SoftMask(IN.vertex, IN.worldPosition);
```
As an example of implementation, please see [UI-Default-SoftMask.shader](https://raw.githubusercontent.com/mob-sakai/SoftMaskForUGUI/upm/Shaders/Resources/UI-Default-SoftMask.shader).
As an example of implementation, please see [UI-Default-SoftMask.shader](https://github.com/mob-sakai/SoftMaskForUGUI/blob/main/Shaders/Resources/UI-Default-SoftMaskable.shader).
<br><br>
#### Tips: Convert component from context menu
Converting components from the context menu is very convenient.
You can convert multiple components at the same time, without having to remove the source components.
![](https://user-images.githubusercontent.com/12690315/48659018-902e2900-ea8e-11e8-9b6e-224365cdde7f.png)
If the destination component has the same properties as the source component, the value is set automatically.
In addition, if the destination component is compatible with the source component, it will not lose its reference.
For example, if `public Mask mask;` refers to a Mask, converting it to SoftMask in this way does not lose references.
This way consists of two generic methods.
```cs
/// <summary>
/// Verify whether it can be converted to the specified component.
/// </summary>
protected static bool CanConvertTo<T>(Object context)
where T : MonoBehaviour
{
return context && context.GetType() != typeof(T);
}
/// <summary>
/// Convert to the specified component.
/// </summary>
protected static void ConvertTo<T>(Object context) where T : MonoBehaviour
{
var target = context as MonoBehaviour;
var so = new SerializedObject(target);
so.Update();
bool oldEnable = target.enabled;
target.enabled = false;
// Find MonoScript of the specified component.
foreach (var script in Resources.FindObjectsOfTypeAll<MonoScript>())
{
if (script.GetClass() != typeof(T))
continue;
// Set 'm_Script' to convert.
so.FindProperty("m_Script").objectReferenceValue = script;
so.ApplyModifiedProperties();
break;
}
(so.targetObject as MonoBehaviour).enabled = oldEnable;
}
```
In SoftMask, they are implemented as follows.
* Mask and SoftMask can be converted to each other.
* If conversion is not possible, gray out the context menu.
```cs
[MenuItem("CONTEXT/Mask/Convert To SoftMask", true)]
static bool _ConvertToSoftMask(MenuCommand command)
{
return CanConvertTo<SoftMask>(command.context);
}
[MenuItem("CONTEXT/Mask/Convert To SoftMask", false)]
static void ConvertToSoftMask(MenuCommand command)
{
ConvertTo<SoftMask>(command.context);
}
[MenuItem("CONTEXT/Mask/Convert To Mask", true)]
static bool _ConvertToMask(MenuCommand command)
{
return CanConvertTo<Mask>(command.context);
}
[MenuItem("CONTEXT/Mask/Convert To Mask", false)]
static void ConvertToMask(MenuCommand command)
{
ConvertTo<Mask>(command.context);
}
```
For details, please see [SoftMaskEditor.cs](https://raw.githubusercontent.com/mob-sakai/SoftMaskForUGUI/upm/Scripts/Editor/SoftMaskEditor.cs).
<br><br>
#### Tips: Shader code for editor only
Do you know how to implement shader code "for editor only"?
SoftMask uses `SOFTMASK_EDITOR` keyword in shader code to determine whether it is running in the editor.
`#pragma shader_feature __ SOFTMASK_EDITOR`
`SOFTMASK_EDITOR` keyword is set from the editor script, but it is not set after it is built. Also, this shader variant will be excluded from build.
```cs
#if UNITY_EDITOR
material = new Material(shader);
material.hideFlags = HideFlags.HideAndDontSave;
material.EnableKeyword("SOFTMASK_EDITOR");
#endif
```
<br><br>
#### Tips: Shader code for SceneView only
Do you know how to implement shader code "for SceneView only"?
SoftMask understands that the current rendering is for SceneView, when SceneView's view projection matrix and UNITY_MATRIX_VP match.
`fixed isSceneView = 1 - any(UNITY_MATRIX_VP - _SceneViewVP);`
Actually, because of the movement operation in SceneView, use "approximate" instead of "match".
```cs
float4x4 _SceneViewVP;
fixed Approximate(float4x4 a, float4x4 b)
{
float4x4 d = abs(a - b);
return step(
max(d._m00,max(d._m01,max(d._m02,max(d._m03,
max(d._m10,max(d._m11,max(d._m12,max(d._m13,
max(d._m20,max(d._m21,max(d._m22,max(d._m23,
max(d._m30,max(d._m31,max(d._m32,d._m33))))))))))))))),
0.01);
}
fixed isSceneView = Approximate(UNITY_MATRIX_VP, _SceneViewVP);
```
`_SceneViewVP` is set every frame from the editor script.
```cs
#if UNITY_EDITOR
UnityEditor.EditorApplication.update += ()
{
Camera cam = UnityEditor.SceneView.lastActiveSceneView.camera;
Matrix4x4 vp = cam.projectionMatrix * cam.worldToCameraMatrix;
material.SetMatrix("_SceneViewVP", vp);
};
#endif
```
<br><br><br><br>
## Contributing
### Issues
Issues are very valuable to this project.
- Ideas are a valuable source of contributions others can make
- Problems show where this project is lacking
- With a question you show where contributors can improve the user experience
### Pull Requests
Pull requests are, a great way to get your ideas into this repository.
See [CONTRIBUTING.md](/../../blob/main/CONTRIBUTING.md).
### Support
This is an open source project that I am developing in my spare time.
If you like it, please support me.
With your support, I can spend more time on development. :)
[![](https://user-images.githubusercontent.com/12690315/50731629-3b18b480-11ad-11e9-8fad-4b13f27969c1.png)](https://www.patreon.com/join/2343451?)
[![](https://user-images.githubusercontent.com/12690315/66942881-03686280-f085-11e9-9586-fc0b6011029f.png)](https://github.com/users/mob-sakai/sponsorship)
<br><br><br><br>
## License
* MIT
@ -309,9 +257,7 @@ UnityEditor.EditorApplication.update += ()
## Author
[mob-sakai](https://github.com/mob-sakai)
[![](https://img.shields.io/twitter/follow/mob_sakai.svg?label=Follow&style=social)](https://twitter.com/intent/follow?screen_name=mob_sakai)
[![become_a_patron](https://user-images.githubusercontent.com/12690315/50731615-ce9db580-11ac-11e9-964f-e0423533dc69.png)](https://www.patreon.com/join/2343451?)
* ![](https://user-images.githubusercontent.com/12690315/96986908-434a0b80-155d-11eb-8275-85138ab90afa.png) [mob-sakai](https://github.com/mob-sakai) [![](https://img.shields.io/twitter/follow/mob_sakai.svg?label=Follow&style=social)](https://twitter.com/intent/follow?screen_name=mob_sakai) ![GitHub followers](https://img.shields.io/github/followers/mob-sakai?style=social)
@ -320,5 +266,4 @@ UnityEditor.EditorApplication.update += ()
* GitHub page : https://github.com/mob-sakai/SoftMaskForUGUI
* Releases : https://github.com/mob-sakai/SoftMaskForUGUI/releases
* Issue tracker : https://github.com/mob-sakai/SoftMaskForUGUI/issues
* Current project : https://github.com/mob-sakai/SoftMaskForUGUI/projects/1
* Change log : https://github.com/mob-sakai/SoftMaskForUGUI/blob/upm/CHANGELOG.md
* Change log : https://github.com/mob-sakai/SoftMaskForUGUI/blob/main/CHANGELOG.md

8
Samples~/Demo.meta Normal file
View File

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

View File

@ -0,0 +1,14 @@
{
"name": "Coffee.SoftMaskForUGUI_Demo",
"references": [
"Coffee.SoftMaskForUGUI"
],
"optionalUnityReferences": [],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": []
}

View File

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

View File

@ -1,6 +1,7 @@
fileFormatVersion: 2
guid: fdbf04e4a4f2a4ce3aebd88b2e996fbe
timeCreated: 1547267633
guid: bd241c18e6c1945cb8b6c9cc5beaa014
folderAsset: yes
timeCreated: 1540000506
licenseType: Pro
DefaultImporter:
userData:

View File

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

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

Binary file not shown.

View File

@ -0,0 +1,20 @@
fileFormatVersion: 2
guid: ab2cfde409d710b47b0b502877abb479
timeCreated: 1473937939
licenseType: Pro
TrueTypeFontImporter:
serializedVersion: 4
fontSize: 72
forceTextureCase: -1
characterSpacing: 0
characterPadding: 1
includeFontData: 1
fontNames:
- Luckiest Guy
fallbackFontReferences: []
customCharacters:
fontRenderingMode: 0
ascentCalculationMode: 2
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

View File

@ -0,0 +1,132 @@
fileFormatVersion: 2
guid: 3ad57d818b4f448a190e524e494130b0
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: -1
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
- 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: 1a57a60f7f37742a2bb34df8b6da51de
vertices: []
indices:
edges: []
weights: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

View File

@ -0,0 +1,132 @@
fileFormatVersion: 2
guid: dee1cb6c2ee294c6087ea9d89d368417
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: 31, y: 31, z: 31, w: 31}
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: 2775f4bfe28684615aa97cccf30fd220
vertices: []
indices:
edges: []
weights: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

View File

@ -0,0 +1,132 @@
fileFormatVersion: 2
guid: f3749669408984358921fc148ed3aa83
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: 31, y: 0, z: 31, 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: af5cd8d820f234217a321d94198ab089
vertices: []
indices:
edges: []
weights: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -0,0 +1,132 @@
fileFormatVersion: 2
guid: 801e306fcae92475592a6d3511bf58d7
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: 8058b3f596fe543db9d4d736085b08b5
vertices: []
indices:
edges: []
weights: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

View File

@ -0,0 +1,132 @@
fileFormatVersion: 2
guid: 0f125745ff7d640519fb2300ed8a96c7
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: 31, z: 0, w: 31}
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: cf7ce3728c4c646cf88a7a642c89aa74
vertices: []
indices:
edges: []
weights: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,59 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
namespace Coffee.UISoftMask.Demos
{
public class SoftMask_Demo : MonoBehaviour
{
[SerializeField] RawImage[] softMaskBufferViewer;
[SerializeField] SoftMask[] softMask;
[SerializeField] Text text;
[SerializeField] GameObject title;
// Use this for initialization
void OnEnable()
{
title.SetActive(true);
text.text = string.Format("GPU: {0}\nDeviceType: {1}\nShaderLevel: {2}\nUVStartsAtTop: {3}",
SystemInfo.graphicsDeviceName,
SystemInfo.graphicsDeviceType,
SystemInfo.graphicsShaderLevel,
SystemInfo.graphicsUVStartsAtTop);
for (int i = 0; i < softMask.Length; i++)
{
softMaskBufferViewer[i].texture = softMask[i].softMaskBuffer;
}
}
public void SetWorldSpase(bool flag)
{
if (flag)
{
GetComponent<Canvas>().renderMode = RenderMode.ScreenSpaceCamera;
GetComponent<Canvas>().renderMode = RenderMode.WorldSpace;
transform.rotation = Quaternion.Euler(new Vector3(0, 6, 0));
}
}
public void SetScreenSpase(bool flag)
{
if (flag)
{
GetComponent<Canvas>().renderMode = RenderMode.ScreenSpaceCamera;
}
}
public void SetOverlay(bool flag)
{
if (flag)
{
GetComponent<Canvas>().renderMode = RenderMode.ScreenSpaceOverlay;
}
}
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 3ebfb22aa6f994ac8b91971f164836fe
timeCreated: 1540726460
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -0,0 +1,713 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!91 &9100000
AnimatorController:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_Name: SoftMask_Demo_Title
serializedVersion: 5
m_AnimatorParameters: []
m_AnimatorLayers:
- serializedVersion: 5
m_Name: Base Layer
m_StateMachine: {fileID: 1107074086602143662}
m_Mask: {fileID: 0}
m_Motions: []
m_Behaviours: []
m_BlendingMode: 0
m_SyncedLayerIndex: -1
m_DefaultWeight: 0
m_IKPass: 0
m_SyncedLayerAffectsTiming: 0
m_Controller: {fileID: 9100000}
--- !u!74 &74247020000484542
AnimationClip:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_Name: Loop
serializedVersion: 6
m_Legacy: 0
m_Compressed: 0
m_UseHighQualityCurve: 1
m_RotationCurves: []
m_CompressedRotationCurves: []
m_EulerCurves: []
m_PositionCurves: []
m_ScaleCurves:
- curve:
serializedVersion: 2
m_Curve:
- serializedVersion: 2
time: 0.6666667
value: {x: 2, y: 2, z: 1}
inSlope: {x: 0, y: 0, z: 0}
outSlope: {x: 0, y: 0, z: 0}
tangentMode: 0
- serializedVersion: 2
time: 0.8333333
value: {x: 2.75, y: 2.75, z: 1}
inSlope: {x: 0, y: 0, z: 0}
outSlope: {x: 0, y: 0, z: 0}
tangentMode: 0
- serializedVersion: 2
time: 1
value: {x: 2, y: 2, z: 1}
inSlope: {x: 0, y: 0, z: 0}
outSlope: {x: 0, y: 0, z: 0}
tangentMode: 0
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
path: SoftMask/Logo
- curve:
serializedVersion: 2
m_Curve:
- serializedVersion: 2
time: 0
value: {x: 1, y: 1, z: 0}
inSlope: {x: 0, y: 0, z: 0}
outSlope: {x: 0, y: 0, z: 0}
tangentMode: 0
- serializedVersion: 2
time: 0.6666667
value: {x: 1, y: 1, z: 0}
inSlope: {x: 0, y: 0, z: 0}
outSlope: {x: 0, y: 0, z: 0}
tangentMode: 0
- serializedVersion: 2
time: 0.75
value: {x: 1.1, y: 1.1, z: 0}
inSlope: {x: 0, y: 0, z: 0}
outSlope: {x: 0, y: 0, z: 0}
tangentMode: 0
- serializedVersion: 2
time: 0.8333333
value: {x: 1, y: 1, z: 0}
inSlope: {x: 0, y: 0, z: 0}
outSlope: {x: 0, y: 0, z: 0}
tangentMode: 0
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
path: SoftMask/Text
m_FloatCurves: []
m_PPtrCurves: []
m_SampleRate: 60
m_WrapMode: 0
m_Bounds:
m_Center: {x: 0, y: 0, z: 0}
m_Extent: {x: 0, y: 0, z: 0}
m_ClipBindingConstant:
genericBindings: []
pptrCurveMapping: []
m_AnimationClipSettings:
serializedVersion: 2
m_AdditiveReferencePoseClip: {fileID: 0}
m_AdditiveReferencePoseTime: 0
m_StartTime: 0
m_StopTime: 1
m_OrientationOffsetY: 0
m_Level: 0
m_CycleOffset: 0
m_HasAdditiveReferencePose: 0
m_LoopTime: 1
m_LoopBlend: 0
m_LoopBlendOrientation: 0
m_LoopBlendPositionY: 0
m_LoopBlendPositionXZ: 0
m_KeepOriginalOrientation: 0
m_KeepOriginalPositionY: 1
m_KeepOriginalPositionXZ: 0
m_HeightFromFeet: 0
m_Mirror: 0
m_EditorCurves:
- curve:
serializedVersion: 2
m_Curve:
- serializedVersion: 2
time: 0.6666667
value: 2
inSlope: 0
outSlope: 0
tangentMode: 136
- serializedVersion: 2
time: 0.8333333
value: 2.75
inSlope: 0
outSlope: 0
tangentMode: 136
- serializedVersion: 2
time: 1
value: 2
inSlope: 0
outSlope: 0
tangentMode: 136
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
attribute: m_LocalScale.x
path: SoftMask/Logo
classID: 224
script: {fileID: 0}
- curve:
serializedVersion: 2
m_Curve:
- serializedVersion: 2
time: 0.6666667
value: 2
inSlope: 0
outSlope: 0
tangentMode: 136
- serializedVersion: 2
time: 0.8333333
value: 2.75
inSlope: 0
outSlope: 0
tangentMode: 136
- serializedVersion: 2
time: 1
value: 2
inSlope: 0
outSlope: 0
tangentMode: 136
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
attribute: m_LocalScale.y
path: SoftMask/Logo
classID: 224
script: {fileID: 0}
- curve:
serializedVersion: 2
m_Curve:
- serializedVersion: 2
time: 0
value: 1
inSlope: 0
outSlope: 0
tangentMode: 136
- serializedVersion: 2
time: 0.6666667
value: 1
inSlope: 0
outSlope: 0
tangentMode: 136
- serializedVersion: 2
time: 0.75
value: 1.1
inSlope: 0
outSlope: 0
tangentMode: 136
- serializedVersion: 2
time: 0.8333333
value: 1
inSlope: 0
outSlope: 0
tangentMode: 136
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
attribute: m_LocalScale.x
path: SoftMask/Text
classID: 224
script: {fileID: 0}
- curve:
serializedVersion: 2
m_Curve:
- serializedVersion: 2
time: 0
value: 1
inSlope: 0
outSlope: 0
tangentMode: 136
- serializedVersion: 2
time: 0.6666667
value: 1
inSlope: 0
outSlope: 0
tangentMode: 136
- serializedVersion: 2
time: 0.75
value: 1.1
inSlope: 0
outSlope: 0
tangentMode: 136
- serializedVersion: 2
time: 0.8333333
value: 1
inSlope: 0
outSlope: 0
tangentMode: 136
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
attribute: m_LocalScale.y
path: SoftMask/Text
classID: 224
script: {fileID: 0}
- curve:
serializedVersion: 2
m_Curve: []
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
attribute: m_LocalScale.z
path: SoftMask/Text
classID: 224
script: {fileID: 0}
m_EulerEditorCurves: []
m_HasGenericRootTransform: 0
m_HasMotionFloatCurves: 0
m_GenerateMotionCurves: 0
m_Events: []
--- !u!74 &74250830961223546
AnimationClip:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_Name: Intro
serializedVersion: 6
m_Legacy: 0
m_Compressed: 0
m_UseHighQualityCurve: 1
m_RotationCurves: []
m_CompressedRotationCurves: []
m_EulerCurves: []
m_PositionCurves: []
m_ScaleCurves:
- curve:
serializedVersion: 2
m_Curve:
- serializedVersion: 2
time: 0
value: {x: 2, y: 2, z: 0}
inSlope: {x: 0, y: 0, z: 0}
outSlope: {x: 0, y: 0, z: 0}
tangentMode: 0
- serializedVersion: 2
time: 1
value: {x: 2, y: 2, z: 0}
inSlope: {x: 0, y: 0, z: 0}
outSlope: {x: 0, y: 0, z: 0}
tangentMode: 0
- serializedVersion: 2
time: 1.5
value: {x: 2, y: 2, z: 0}
inSlope: {x: 0, y: 0, z: 0}
outSlope: {x: 0, y: 0, z: 0}
tangentMode: 0
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
path: SoftMask/Logo
- curve:
serializedVersion: 2
m_Curve:
- serializedVersion: 2
time: 0
value: {x: 1, y: 1, z: 0}
inSlope: {x: 0, y: 0, z: 0}
outSlope: {x: 0, y: 0, z: 0}
tangentMode: 0
- serializedVersion: 2
time: 1
value: {x: 1, y: 1, z: 0}
inSlope: {x: 0, y: 0, z: 0}
outSlope: {x: 0, y: 0, z: 0}
tangentMode: 0
- serializedVersion: 2
time: 1.5
value: {x: 1, y: 1, z: 0}
inSlope: {x: 0, y: 0, z: 0}
outSlope: {x: 0, y: 0, z: 0}
tangentMode: 0
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
path: SoftMask/Text
m_FloatCurves:
- curve:
serializedVersion: 2
m_Curve:
- serializedVersion: 2
time: 0
value: 700
inSlope: 0
outSlope: 0
tangentMode: 136
- serializedVersion: 2
time: 1
value: 700
inSlope: 0
outSlope: 0
tangentMode: 136
- serializedVersion: 2
time: 1.5
value: 579.2
inSlope: 0
outSlope: 0
tangentMode: 136
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
attribute: m_SizeDelta.x
path:
classID: 224
script: {fileID: 0}
- curve:
serializedVersion: 2
m_Curve:
- serializedVersion: 2
time: 0
value: 500
inSlope: 0
outSlope: 0
tangentMode: 136
- serializedVersion: 2
time: 1
value: 500
inSlope: 0
outSlope: 0
tangentMode: 136
- serializedVersion: 2
time: 1.5
value: 354.1
inSlope: 0
outSlope: 0
tangentMode: 136
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
attribute: m_SizeDelta.y
path:
classID: 224
script: {fileID: 0}
m_PPtrCurves: []
m_SampleRate: 60
m_WrapMode: 0
m_Bounds:
m_Center: {x: 0, y: 0, z: 0}
m_Extent: {x: 0, y: 0, z: 0}
m_ClipBindingConstant:
genericBindings: []
pptrCurveMapping: []
m_AnimationClipSettings:
serializedVersion: 2
m_AdditiveReferencePoseClip: {fileID: 0}
m_AdditiveReferencePoseTime: 0
m_StartTime: 0
m_StopTime: 1.5
m_OrientationOffsetY: 0
m_Level: 0
m_CycleOffset: 0
m_HasAdditiveReferencePose: 0
m_LoopTime: 1
m_LoopBlend: 0
m_LoopBlendOrientation: 0
m_LoopBlendPositionY: 0
m_LoopBlendPositionXZ: 0
m_KeepOriginalOrientation: 0
m_KeepOriginalPositionY: 1
m_KeepOriginalPositionXZ: 0
m_HeightFromFeet: 0
m_Mirror: 0
m_EditorCurves:
- curve:
serializedVersion: 2
m_Curve:
- serializedVersion: 2
time: 0
value: 2
inSlope: 0
outSlope: 0
tangentMode: 136
- serializedVersion: 2
time: 1
value: 2
inSlope: 0
outSlope: 0
tangentMode: 136
- serializedVersion: 2
time: 1.5
value: 2
inSlope: 0
outSlope: 0
tangentMode: 136
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
attribute: m_LocalScale.x
path: SoftMask/Logo
classID: 224
script: {fileID: 0}
- curve:
serializedVersion: 2
m_Curve:
- serializedVersion: 2
time: 0
value: 2
inSlope: 0
outSlope: 0
tangentMode: 136
- serializedVersion: 2
time: 1
value: 2
inSlope: 0
outSlope: 0
tangentMode: 136
- serializedVersion: 2
time: 1.5
value: 2
inSlope: 0
outSlope: 0
tangentMode: 136
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
attribute: m_LocalScale.y
path: SoftMask/Logo
classID: 224
script: {fileID: 0}
- curve:
serializedVersion: 2
m_Curve:
- serializedVersion: 2
time: 0
value: 0
inSlope: 0
outSlope: 0
tangentMode: 136
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
attribute: m_LocalScale.z
path: SoftMask/Logo
classID: 224
script: {fileID: 0}
- curve:
serializedVersion: 2
m_Curve:
- serializedVersion: 2
time: 0
value: 1
inSlope: 0
outSlope: 0
tangentMode: 136
- serializedVersion: 2
time: 1
value: 1
inSlope: 0
outSlope: 0
tangentMode: 136
- serializedVersion: 2
time: 1.5
value: 1
inSlope: 0
outSlope: 0
tangentMode: 136
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
attribute: m_LocalScale.x
path: SoftMask/Text
classID: 224
script: {fileID: 0}
- curve:
serializedVersion: 2
m_Curve:
- serializedVersion: 2
time: 0
value: 1
inSlope: 0
outSlope: 0
tangentMode: 136
- serializedVersion: 2
time: 1
value: 1
inSlope: 0
outSlope: 0
tangentMode: 136
- serializedVersion: 2
time: 1.5
value: 1
inSlope: 0
outSlope: 0
tangentMode: 136
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
attribute: m_LocalScale.y
path: SoftMask/Text
classID: 224
script: {fileID: 0}
- curve:
serializedVersion: 2
m_Curve:
- serializedVersion: 2
time: 0
value: 0
inSlope: 0
outSlope: 0
tangentMode: 136
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
attribute: m_LocalScale.z
path: SoftMask/Text
classID: 224
script: {fileID: 0}
- curve:
serializedVersion: 2
m_Curve:
- serializedVersion: 2
time: 0
value: 700
inSlope: 0
outSlope: 0
tangentMode: 136
- serializedVersion: 2
time: 1
value: 700
inSlope: 0
outSlope: 0
tangentMode: 136
- serializedVersion: 2
time: 1.5
value: 579.2
inSlope: 0
outSlope: 0
tangentMode: 136
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
attribute: m_SizeDelta.x
path:
classID: 224
script: {fileID: 0}
- curve:
serializedVersion: 2
m_Curve:
- serializedVersion: 2
time: 0
value: 500
inSlope: 0
outSlope: 0
tangentMode: 136
- serializedVersion: 2
time: 1
value: 500
inSlope: 0
outSlope: 0
tangentMode: 136
- serializedVersion: 2
time: 1.5
value: 354.1
inSlope: 0
outSlope: 0
tangentMode: 136
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
attribute: m_SizeDelta.y
path:
classID: 224
script: {fileID: 0}
m_EulerEditorCurves: []
m_HasGenericRootTransform: 0
m_HasMotionFloatCurves: 0
m_GenerateMotionCurves: 0
m_Events: []
--- !u!1101 &1101833671069262892
AnimatorStateTransition:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_Name:
m_Conditions: []
m_DstStateMachine: {fileID: 0}
m_DstState: {fileID: 1102583906311020750}
m_Solo: 0
m_Mute: 0
m_IsExit: 0
serializedVersion: 3
m_TransitionDuration: 0.25
m_TransitionOffset: 0
m_ExitTime: 0.75
m_HasExitTime: 1
m_HasFixedDuration: 1
m_InterruptionSource: 0
m_OrderedInterruption: 1
m_CanTransitionToSelf: 1
--- !u!1102 &1102583906311020750
AnimatorState:
serializedVersion: 5
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_Name: Loop
m_Speed: 1
m_CycleOffset: 0
m_Transitions: []
m_StateMachineBehaviours: []
m_Position: {x: 50, y: 50, z: 0}
m_IKOnFeet: 0
m_WriteDefaultValues: 1
m_Mirror: 0
m_SpeedParameterActive: 0
m_MirrorParameterActive: 0
m_CycleOffsetParameterActive: 0
m_Motion: {fileID: 74247020000484542}
m_Tag:
m_SpeedParameter:
m_MirrorParameter:
m_CycleOffsetParameter:
--- !u!1102 &1102859778462102860
AnimatorState:
serializedVersion: 5
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_Name: Intro
m_Speed: 1
m_CycleOffset: 0
m_Transitions:
- {fileID: 1101833671069262892}
m_StateMachineBehaviours: []
m_Position: {x: 50, y: 50, z: 0}
m_IKOnFeet: 0
m_WriteDefaultValues: 1
m_Mirror: 0
m_SpeedParameterActive: 0
m_MirrorParameterActive: 0
m_CycleOffsetParameterActive: 0
m_Motion: {fileID: 74250830961223546}
m_Tag:
m_SpeedParameter:
m_MirrorParameter:
m_CycleOffsetParameter:
--- !u!1107 &1107074086602143662
AnimatorStateMachine:
serializedVersion: 5
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_Name: Base Layer
m_ChildStates:
- serializedVersion: 1
m_State: {fileID: 1102859778462102860}
m_Position: {x: 240, y: 108, z: 0}
- serializedVersion: 1
m_State: {fileID: 1102583906311020750}
m_Position: {x: 240, y: 180, z: 0}
m_ChildStateMachines: []
m_AnyStateTransitions: []
m_EntryTransitions: []
m_StateMachineTransitions: {}
m_StateMachineBehaviours: []
m_AnyStatePosition: {x: 50, y: 20, z: 0}
m_EntryPosition: {x: 50, y: 120, z: 0}
m_ExitPosition: {x: 800, y: 120, z: 0}
m_ParentStateMachinePosition: {x: 800, y: 20, z: 0}
m_DefaultState: {fileID: 1102859778462102860}

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: f1142cc2db608495ba510244d813cccf
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 9100000
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,401 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!91 &9100000
AnimatorController:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_Name: SoftMask_Demo_Transition
serializedVersion: 5
m_AnimatorParameters:
- m_Name: Play
m_Type: 9
m_DefaultFloat: 0
m_DefaultInt: 0
m_DefaultBool: 0
m_Controller: {fileID: 0}
m_AnimatorLayers:
- serializedVersion: 5
m_Name: Base Layer
m_StateMachine: {fileID: 1107074086602143662}
m_Mask: {fileID: 0}
m_Motions: []
m_Behaviours: []
m_BlendingMode: 0
m_SyncedLayerIndex: -1
m_DefaultWeight: 0
m_IKPass: 0
m_SyncedLayerAffectsTiming: 0
m_Controller: {fileID: 9100000}
--- !u!74 &74247020000484542
AnimationClip:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_Name: Animation
serializedVersion: 6
m_Legacy: 0
m_Compressed: 0
m_UseHighQualityCurve: 1
m_RotationCurves: []
m_CompressedRotationCurves: []
m_EulerCurves: []
m_PositionCurves: []
m_ScaleCurves:
- curve:
serializedVersion: 2
m_Curve:
- serializedVersion: 2
time: 0.6666667
value: {x: 2, y: 2, z: 1}
inSlope: {x: 0, y: 0, z: 0}
outSlope: {x: 0, y: 0, z: 0}
tangentMode: 0
- serializedVersion: 2
time: 0.8333333
value: {x: 2.75, y: 2.75, z: 1}
inSlope: {x: 0, y: 0, z: 0}
outSlope: {x: 0, y: 0, z: 0}
tangentMode: 0
- serializedVersion: 2
time: 1
value: {x: 2, y: 2, z: 1}
inSlope: {x: 0, y: 0, z: 0}
outSlope: {x: 0, y: 0, z: 0}
tangentMode: 0
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
path: SoftMask/Logo
- curve:
serializedVersion: 2
m_Curve:
- serializedVersion: 2
time: 0
value: {x: 1, y: 1, z: 0}
inSlope: {x: 0, y: 0, z: 0}
outSlope: {x: 0, y: 0, z: 0}
tangentMode: 0
- serializedVersion: 2
time: 0.6666667
value: {x: 1, y: 1, z: 0}
inSlope: {x: 0, y: 0, z: 0}
outSlope: {x: 0, y: 0, z: 0}
tangentMode: 0
- serializedVersion: 2
time: 0.75
value: {x: 1.1, y: 1.1, z: 0}
inSlope: {x: 0, y: 0, z: 0}
outSlope: {x: 0, y: 0, z: 0}
tangentMode: 0
- serializedVersion: 2
time: 0.8333333
value: {x: 1, y: 1, z: 0}
inSlope: {x: 0, y: 0, z: 0}
outSlope: {x: 0, y: 0, z: 0}
tangentMode: 0
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
path: SoftMask/Text
m_FloatCurves: []
m_PPtrCurves: []
m_SampleRate: 60
m_WrapMode: 0
m_Bounds:
m_Center: {x: 0, y: 0, z: 0}
m_Extent: {x: 0, y: 0, z: 0}
m_ClipBindingConstant:
genericBindings:
- serializedVersion: 2
path: 209171555
attribute: 3
script: {fileID: 0}
typeID: 4
customType: 0
isPPtrCurve: 0
- serializedVersion: 2
path: 3547498935
attribute: 3
script: {fileID: 0}
typeID: 4
customType: 0
isPPtrCurve: 0
pptrCurveMapping: []
m_AnimationClipSettings:
serializedVersion: 2
m_AdditiveReferencePoseClip: {fileID: 0}
m_AdditiveReferencePoseTime: 0
m_StartTime: 0
m_StopTime: 1
m_OrientationOffsetY: 0
m_Level: 0
m_CycleOffset: 0
m_HasAdditiveReferencePose: 0
m_LoopTime: 0
m_LoopBlend: 0
m_LoopBlendOrientation: 0
m_LoopBlendPositionY: 0
m_LoopBlendPositionXZ: 0
m_KeepOriginalOrientation: 0
m_KeepOriginalPositionY: 1
m_KeepOriginalPositionXZ: 0
m_HeightFromFeet: 0
m_Mirror: 0
m_EditorCurves:
- curve:
serializedVersion: 2
m_Curve:
- serializedVersion: 2
time: 0.6666667
value: 2
inSlope: 0
outSlope: 0
tangentMode: 136
- serializedVersion: 2
time: 0.8333333
value: 2.75
inSlope: 0
outSlope: 0
tangentMode: 136
- serializedVersion: 2
time: 1
value: 2
inSlope: 0
outSlope: 0
tangentMode: 136
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
attribute: m_LocalScale.x
path: SoftMask/Logo
classID: 224
script: {fileID: 0}
- curve:
serializedVersion: 2
m_Curve:
- serializedVersion: 2
time: 0.6666667
value: 2
inSlope: 0
outSlope: 0
tangentMode: 136
- serializedVersion: 2
time: 0.8333333
value: 2.75
inSlope: 0
outSlope: 0
tangentMode: 136
- serializedVersion: 2
time: 1
value: 2
inSlope: 0
outSlope: 0
tangentMode: 136
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
attribute: m_LocalScale.y
path: SoftMask/Logo
classID: 224
script: {fileID: 0}
- curve:
serializedVersion: 2
m_Curve:
- serializedVersion: 2
time: 0
value: 1
inSlope: 0
outSlope: 0
tangentMode: 136
- serializedVersion: 2
time: 0.6666667
value: 1
inSlope: 0
outSlope: 0
tangentMode: 136
- serializedVersion: 2
time: 0.75
value: 1.1
inSlope: 0
outSlope: 0
tangentMode: 136
- serializedVersion: 2
time: 0.8333333
value: 1
inSlope: 0
outSlope: 0
tangentMode: 136
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
attribute: m_LocalScale.x
path: SoftMask/Text
classID: 224
script: {fileID: 0}
- curve:
serializedVersion: 2
m_Curve:
- serializedVersion: 2
time: 0
value: 1
inSlope: 0
outSlope: 0
tangentMode: 136
- serializedVersion: 2
time: 0.6666667
value: 1
inSlope: 0
outSlope: 0
tangentMode: 136
- serializedVersion: 2
time: 0.75
value: 1.1
inSlope: 0
outSlope: 0
tangentMode: 136
- serializedVersion: 2
time: 0.8333333
value: 1
inSlope: 0
outSlope: 0
tangentMode: 136
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
attribute: m_LocalScale.y
path: SoftMask/Text
classID: 224
script: {fileID: 0}
- curve:
serializedVersion: 2
m_Curve: []
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
attribute: m_LocalScale.z
path: SoftMask/Text
classID: 224
script: {fileID: 0}
m_EulerEditorCurves: []
m_HasGenericRootTransform: 0
m_HasMotionFloatCurves: 0
m_GenerateMotionCurves: 0
m_Events: []
--- !u!1101 &1101040075164616526
AnimatorStateTransition:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_Name:
m_Conditions: []
m_DstStateMachine: {fileID: 0}
m_DstState: {fileID: 1102859778462102860}
m_Solo: 0
m_Mute: 0
m_IsExit: 0
serializedVersion: 3
m_TransitionDuration: 0.25
m_TransitionOffset: 0
m_ExitTime: 0.75
m_HasExitTime: 1
m_HasFixedDuration: 1
m_InterruptionSource: 0
m_OrderedInterruption: 1
m_CanTransitionToSelf: 1
--- !u!1101 &1101833671069262892
AnimatorStateTransition:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_Name:
m_Conditions:
- m_ConditionMode: 1
m_ConditionEvent: Play
m_EventTreshold: 0
m_DstStateMachine: {fileID: 0}
m_DstState: {fileID: 1102583906311020750}
m_Solo: 0
m_Mute: 0
m_IsExit: 0
serializedVersion: 3
m_TransitionDuration: 0.25
m_TransitionOffset: 0
m_ExitTime: 0.75
m_HasExitTime: 1
m_HasFixedDuration: 1
m_InterruptionSource: 0
m_OrderedInterruption: 1
m_CanTransitionToSelf: 1
--- !u!1102 &1102583906311020750
AnimatorState:
serializedVersion: 5
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_Name: Animation
m_Speed: 1
m_CycleOffset: 0
m_Transitions:
- {fileID: 1101040075164616526}
m_StateMachineBehaviours: []
m_Position: {x: 50, y: 50, z: 0}
m_IKOnFeet: 0
m_WriteDefaultValues: 1
m_Mirror: 0
m_SpeedParameterActive: 0
m_MirrorParameterActive: 0
m_CycleOffsetParameterActive: 0
m_Motion: {fileID: 74247020000484542}
m_Tag:
m_SpeedParameter:
m_MirrorParameter:
m_CycleOffsetParameter:
--- !u!1102 &1102859778462102860
AnimatorState:
serializedVersion: 5
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_Name: Idle
m_Speed: 1
m_CycleOffset: 0
m_Transitions:
- {fileID: 1101833671069262892}
m_StateMachineBehaviours: []
m_Position: {x: 50, y: 50, z: 0}
m_IKOnFeet: 0
m_WriteDefaultValues: 1
m_Mirror: 0
m_SpeedParameterActive: 0
m_MirrorParameterActive: 0
m_CycleOffsetParameterActive: 0
m_Motion: {fileID: 0}
m_Tag:
m_SpeedParameter:
m_MirrorParameter:
m_CycleOffsetParameter:
--- !u!1107 &1107074086602143662
AnimatorStateMachine:
serializedVersion: 5
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_Name: Base Layer
m_ChildStates:
- serializedVersion: 1
m_State: {fileID: 1102859778462102860}
m_Position: {x: 240, y: 108, z: 0}
- serializedVersion: 1
m_State: {fileID: 1102583906311020750}
m_Position: {x: 240, y: 180, z: 0}
m_ChildStateMachines: []
m_AnyStateTransitions: []
m_EntryTransitions: []
m_StateMachineTransitions: {}
m_StateMachineBehaviours: []
m_AnyStatePosition: {x: 50, y: 20, z: 0}
m_EntryPosition: {x: 50, y: 120, z: 0}
m_ExitPosition: {x: 800, y: 120, z: 0}
m_ParentStateMachinePosition: {x: 800, y: 20, z: 0}
m_DefaultState: {fileID: 1102859778462102860}

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: a3e65681898104501aee3ff30e223f28
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 9100000
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 391 KiB

View File

@ -0,0 +1,132 @@
fileFormatVersion: 2
guid: e5a8e8d861f62472d8f99611cf9d12c5
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: -1
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
- 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: 351a811034e0f411db84265dae66b273
vertices: []
indices:
edges: []
weights: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

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

View File

@ -1,4 +1,4 @@
Shader "TextMeshPro/Distance Field (SoftMaskable)" {
Shader "Hidden/TextMeshPro/Distance Field (SoftMaskable)" {
Properties {
_FaceTex ("Face Texture", 2D) = "white" {}
@ -35,7 +35,7 @@ Properties {
_ReflectOutlineColor("Reflection Color", Color) = (0,0,0,1)
_Cube ("Reflection Cubemap", Cube) = "black" { /* TexGen CubeReflect */ }
_EnvMatrixRotation ("Texture Rotation", vector) = (0, 0, 0, 0)
_UnderlayColor ("Border Color", Color) = (0,0,0, 0.5)
_UnderlayOffsetX ("Border OffsetX", Range(-1,1)) = 0
@ -67,7 +67,7 @@ Properties {
_VertexOffsetX ("Vertex OffsetX", float) = 0
_VertexOffsetY ("Vertex OffsetY", float) = 0
_MaskCoord ("Mask Coordinates", vector) = (0, 0, 32767, 32767)
_ClipRect ("Clip Rect", vector) = (-32767, -32767, 32767, 32767)
_MaskSoftnessX ("Mask SoftnessX", float) = 0
@ -95,7 +95,7 @@ SubShader {
{
Ref [_Stencil]
Comp [_StencilComp]
Pass [_StencilOp]
Pass [_StencilOp]
ReadMask [_StencilReadMask]
WriteMask [_StencilWriteMask]
}
@ -124,10 +124,15 @@ SubShader {
#include "UnityCG.cginc"
#include "UnityUI.cginc"
#if UNITY_VERSION < 201910
#include "Assets/TextMesh Pro/Resources/Shaders/TMPro_Properties.cginc"
#include "Assets/TextMesh Pro/Resources/Shaders/TMPro.cginc"
#include "./../SoftMask.cginc"
#else
#include "Assets/TextMesh Pro/Shaders/TMPro_Properties.cginc"
#include "Assets/TextMesh Pro/Shaders/TMPro.cginc"
#endif
#include "Packages/com.coffee.softmask-for-ugui/Shaders/SoftMask.cginc"
#pragma shader_feature __ SOFTMASK_EDITOR
struct vertex_t {
@ -146,7 +151,7 @@ SubShader {
float4 param : TEXCOORD1; // alphaClip, scale, bias, weight
float4 mask : TEXCOORD2; // Position in object space(xy), pixel Size(zw)
float3 viewDir : TEXCOORD3;
#if (UNDERLAY_ON || UNDERLAY_INNER)
float4 texcoord2 : TEXCOORD4; // u,v, scale, bias
fixed4 underlayColor : COLOR1;
@ -181,7 +186,7 @@ SubShader {
float bias =(.5 - weight) + (.5 / scale);
float alphaClip = (1.0 - _OutlineWidth*_ScaleRatioA - _OutlineSoftness*_ScaleRatioA);
#if GLOW_ON
alphaClip = min(alphaClip, 1.0 - _GlowOffset * _ScaleRatioB - _GlowOuter * _ScaleRatioB);
#endif
@ -232,7 +237,7 @@ SubShader {
fixed4 PixShader(pixel_t input) : SV_Target
{
float c = tex2D(_MainTex, input.atlas).a;
#ifndef UNDERLAY_ON
clip(c - input.param.x);
#endif
@ -249,7 +254,7 @@ SubShader {
half4 outlineColor = _OutlineColor;
faceColor.rgb *= input.color.rgb;
faceColor *= tex2D(_FaceTex, input.textures.xy + float2(_FaceUVSpeedX, _FaceUVSpeedY) * _Time.y);
outlineColor *= tex2D(_OutlineTex, input.textures.zw + float2(_OutlineUVSpeedX, _OutlineUVSpeedY) * _Time.y);
@ -294,9 +299,9 @@ SubShader {
half2 m = saturate((_ClipRect.zw - _ClipRect.xy - abs(input.mask.xy)) * input.mask.zw);
faceColor *= m.x * m.y;
#endif
faceColor *= SoftMask(input.position, input.worldPosition);
#if UNITY_UI_ALPHACLIP
clip(faceColor.a - 0.001);
#endif

View File

@ -1,7 +1,9 @@
fileFormatVersion: 2
guid: 935b7be1c88464d2eb87204fdfab5a38
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@ -3,7 +3,7 @@
// - No Glow Option
// - Softness is applied on both side of the outline
Shader "TextMeshPro/Mobile/Distance Field (SoftMaskable)" {
Shader "Hidden/TextMeshPro/Mobile/Distance Field (SoftMaskable)" {
Properties {
_FaceColor ("Face Color", Color) = (1,1,1,1)
@ -41,18 +41,18 @@ Properties {
_ClipRect ("Clip Rect", vector) = (-32767, -32767, 32767, 32767)
_MaskSoftnessX ("Mask SoftnessX", float) = 0
_MaskSoftnessY ("Mask SoftnessY", float) = 0
_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
}
SubShader {
Tags
Tags
{
"Queue"="Transparent"
"IgnoreProjector"="True"
@ -64,7 +64,7 @@ SubShader {
{
Ref [_Stencil]
Comp [_StencilComp]
Pass [_StencilOp]
Pass [_StencilOp]
ReadMask [_StencilReadMask]
WriteMask [_StencilWriteMask]
}
@ -93,9 +93,13 @@ SubShader {
#include "UnityCG.cginc"
#include "UnityUI.cginc"
#if UNITY_VERSION < 201910
#include "Assets/TextMesh Pro/Resources/Shaders/TMPro_Properties.cginc"
#include "./../SoftMask.cginc"
#else
#include "Assets/TextMesh Pro/Shaders/TMPro_Properties.cginc"
#endif
#include "Packages/com.coffee.softmask-for-ugui/Shaders/SoftMask.cginc"
#pragma shader_feature __ SOFTMASK_EDITOR
struct vertex_t {
@ -132,7 +136,7 @@ SubShader {
float2 pixelSize = vPosition.w;
pixelSize /= float2(_ScaleX, _ScaleY) * abs(mul((float2x2)UNITY_MATRIX_P, _ScreenParams.xy));
float scale = rsqrt(dot(pixelSize, pixelSize));
scale *= abs(input.texcoord1.y) * _GradientScale * 1.5;
if(UNITY_MATRIX_P[3][3] == 0) scale = lerp(abs(scale) * (1 - _PerspectiveFilter), scale, abs(dot(UnityObjectToWorldNormal(input.normal.xyz), normalize(WorldSpaceViewDir(vert)))));
@ -223,9 +227,9 @@ SubShader {
#if (UNDERLAY_ON | UNDERLAY_INNER)
c *= input.texcoord1.z;
#endif
c *= SoftMask(input.vertex, input.worldPosition);
#if UNITY_UI_ALPHACLIP
clip(c.a - 0.001);
#endif

View File

@ -1,7 +1,9 @@
fileFormatVersion: 2
guid: e65241fa80a374114b3f55ed746c04d9
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,10 +1,10 @@
Shader "TextMeshPro/Sprite (SoftMaskable)"
Shader "Hidden/TextMeshPro/Sprite (SoftMaskable)"
{
Properties
{
_MainTex ("Sprite Texture", 2D) = "white" {}
_Color ("Tint", Color) = (1,1,1,1)
_StencilComp ("Stencil Comparison", Float) = 8
_Stencil ("Stencil ID", Float) = 0
_StencilOp ("Stencil Operation", Float) = 0
@ -20,19 +20,19 @@ Shader "TextMeshPro/Sprite (SoftMaskable)"
SubShader
{
Tags
{
"Queue"="Transparent"
"IgnoreProjector"="True"
"RenderType"="Transparent"
{
"Queue"="Transparent"
"IgnoreProjector"="True"
"RenderType"="Transparent"
"PreviewType"="Plane"
"CanUseSpriteAtlas"="True"
}
Stencil
{
Ref [_Stencil]
Comp [_StencilComp]
Pass [_StencilOp]
Pass [_StencilOp]
ReadMask [_StencilReadMask]
WriteMask [_StencilWriteMask]
}
@ -55,10 +55,10 @@ Shader "TextMeshPro/Sprite (SoftMaskable)"
#pragma multi_compile __ UNITY_UI_CLIP_RECT
#pragma multi_compile __ UNITY_UI_ALPHACLIP
#include "./../SoftMask.cginc"
#include "Packages/com.coffee.softmask-for-ugui/Shaders/SoftMask.cginc"
#pragma shader_feature __ SOFTMASK_EDITOR
struct appdata_t
{
float4 vertex : POSITION;
@ -73,7 +73,7 @@ Shader "TextMeshPro/Sprite (SoftMaskable)"
half2 texcoord : TEXCOORD0;
float4 worldPosition : TEXCOORD1;
};
fixed4 _Color;
fixed4 _TextureSampleAdd;
float4 _ClipRect;
@ -85,11 +85,11 @@ Shader "TextMeshPro/Sprite (SoftMaskable)"
OUT.vertex = UnityObjectToClipPos(OUT.worldPosition);
OUT.texcoord = IN.texcoord;
#ifdef UNITY_HALF_TEXEL_OFFSET
OUT.vertex.xy += (_ScreenParams.zw-1.0)*float2(-1,1);
#endif
OUT.color = IN.color * _Color;
return OUT;
}
@ -99,13 +99,13 @@ Shader "TextMeshPro/Sprite (SoftMaskable)"
fixed4 frag(v2f IN) : SV_Target
{
half4 color = (tex2D(_MainTex, IN.texcoord) + _TextureSampleAdd) * IN.color;
#if UNITY_UI_CLIP_RECT
color.a *= UnityGet2DClipping(IN.worldPosition.xy, _ClipRect);
#endif
color.a *= SoftMask(IN.vertex, IN.worldPosition);
#ifdef UNITY_UI_ALPHACLIP
clip (color.a - 0.001);
#endif

View File

@ -1,9 +1,9 @@
fileFormatVersion: 2
guid: 94593ebff37d04a64936ebe46ce7e769
timeCreated: 1450517184
licenseType: Pro
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,56 @@
#if UNITY_2018_3_OR_NEWER
using UnityEditor.Experimental.SceneManagement;
#endif
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;
namespace Coffee.UISoftMask
{
internal static class EditorUtils
{
internal static void MarkPrefabDirty()
{
#if UNITY_2018_3_OR_NEWER
var prefabStage = PrefabStageUtility.GetCurrentPrefabStage();
if (prefabStage == null) return;
EditorSceneManager.MarkSceneDirty(prefabStage.scene);
#endif
}
/// <summary>
/// Verify whether it can be converted to the specified component.
/// </summary>
internal static bool CanConvertTo<T>(Object context) where T : MonoBehaviour
{
return context && context.GetType() != typeof(T);
}
/// <summary>
/// Convert to the specified component.
/// </summary>
internal static void ConvertTo<T>(Object context) where T : MonoBehaviour
{
var target = context as MonoBehaviour;
var so = new SerializedObject(target);
so.Update();
var oldEnable = target.enabled;
target.enabled = false;
// Find MonoScript of the specified component.
foreach (var script in Resources.FindObjectsOfTypeAll<MonoScript>())
{
if (script.GetClass() != typeof(T))
continue;
// Set 'm_Script' to convert.
so.FindProperty("m_Script").objectReferenceValue = script;
so.ApplyModifiedProperties();
break;
}
(so.targetObject as MonoBehaviour).enabled = oldEnable;
}
}
}

View File

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

View File

@ -0,0 +1,82 @@
#if !UNITY_2019_1_OR_NEWER
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using UnityEditor;
namespace Coffee.UISoftMask
{
public static class ImportSampleMenu
{
private const string jsonGuid = "c43fd233e88b347cdabc530c23ffe30a";
[MenuItem("Assets/Samples/UISoftMask/Import Demo")]
private static void ImportDemo()
{
ImportSample(jsonGuid, "Demo");
}
[MenuItem("Assets/Samples/UISoftMask/Import TextMeshPro Support")]
private static void ImportTextMeshProSupport()
{
ImportSample(jsonGuid, "TextMeshProSupport");
}
private static void ImportSample(string jsonGuid, string sampleName)
{
var jsonPath = AssetDatabase.GUIDToAssetPath(jsonGuid);
var packageRoot = Path.GetDirectoryName(jsonPath).Replace('\\', '/');
var json = File.ReadAllText(jsonPath);
var version = Regex.Match(json, "\"version\"\\s*:\\s*\"([^\"]+)\"").Groups[1].Value;
var displayName = Regex.Match(json, "\"displayName\"\\s*:\\s*\"([^\"]+)\"").Groups[1].Value;
var src = string.Format("{0}/Samples~/{1}", packageRoot, sampleName);
var srcAlt = string.Format("{0}/Samples/{1}", packageRoot, sampleName);
var dst = string.Format("Assets/Samples/{0}/{1}/{2}", displayName, version, sampleName);
var previousPath = GetPreviousSamplePath(displayName, sampleName);
// Remove the previous sample directory.
if (!string.IsNullOrEmpty(previousPath))
{
var msg = "A different version of the sample is already imported at\n\n"
+ previousPath
+ "\n\nIt will be deleted when you update. Are you sure you want to continue?";
if (!EditorUtility.DisplayDialog("Sample Importer", msg, "OK", "Cancel"))
return;
FileUtil.DeleteFileOrDirectory(previousPath);
var metaFile = previousPath + ".meta";
if (File.Exists(metaFile))
FileUtil.DeleteFileOrDirectory(metaFile);
}
if (!Directory.Exists(dst))
FileUtil.DeleteFileOrDirectory(dst);
var dstDir = Path.GetDirectoryName(dst);
if (!Directory.Exists(dstDir))
Directory.CreateDirectory(dstDir);
if (Directory.Exists(src))
FileUtil.CopyFileOrDirectory(src, dst);
else if (Directory.Exists(srcAlt))
FileUtil.CopyFileOrDirectory(srcAlt, dst);
else
throw new DirectoryNotFoundException(src);
AssetDatabase.Refresh(ImportAssetOptions.ImportRecursive);
}
private static string GetPreviousSamplePath(string displayName, string sampleName)
{
var sampleRoot = string.Format("Assets/Samples/{0}", displayName);
var sampleRootInfo = new DirectoryInfo(sampleRoot);
if (!sampleRootInfo.Exists) return null;
return sampleRootInfo.GetDirectories()
.Select(versionDir => Path.Combine(versionDir.ToString(), sampleName))
.FirstOrDefault(Directory.Exists);
}
}
}
#endif

View File

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

View File

@ -1,4 +1,3 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
@ -6,128 +5,124 @@ using UnityEditor;
using System.Linq;
namespace Coffee.UIExtensions.Editors
namespace Coffee.UISoftMask
{
/// <summary>
/// SoftMask editor.
/// </summary>
[CustomEditor(typeof(SoftMask))]
[CanEditMultipleObjects]
public class SoftMaskEditor : Editor
{
const string k_PrefsPreview = "SoftMaskEditor_Preview";
static readonly List<Graphic> s_Graphics = new List<Graphic> ();
static bool s_Preview;
/// <summary>
/// SoftMask editor.
/// </summary>
[CustomEditor(typeof(SoftMask))]
[CanEditMultipleObjects]
public class SoftMaskEditor : Editor
{
private const int k_PreviewSize = 128;
private const string k_PrefsPreview = "SoftMaskEditor_Preview";
private static readonly List<Graphic> s_Graphics = new List<Graphic>();
private static bool s_Preview;
private void OnEnable ()
{
s_Preview = EditorPrefs.GetBool (k_PrefsPreview, false);
}
private void OnEnable()
{
s_Preview = EditorPrefs.GetBool(k_PrefsPreview, false);
}
public override void OnInspectorGUI ()
{
base.OnInspectorGUI ();
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
var current = target as SoftMask;
current.GetComponentsInChildren<Graphic> (true, s_Graphics);
var fixTargets = s_Graphics.Where (x => x.gameObject != current.gameObject && !x.GetComponent<SoftMaskable> () && (!x.GetComponent<Mask> () || x.GetComponent<Mask> ().showMaskGraphic)).ToList ();
if (0 < fixTargets.Count)
{
GUILayout.BeginHorizontal ();
EditorGUILayout.HelpBox ("There are child Graphicss that does not have a SoftMaskable component.\nAdd SoftMaskable component to them.", MessageType.Warning);
GUILayout.BeginVertical ();
if (GUILayout.Button ("Fix"))
{
foreach (var p in fixTargets)
{
p.gameObject.AddComponent<SoftMaskable> ();
}
}
if (GUILayout.Button ("Ping"))
{
EditorGUIUtility.PingObject (fixTargets[0]);
}
GUILayout.EndVertical ();
GUILayout.EndHorizontal ();
}
var current = target as SoftMask;
current.GetComponentsInChildren<Graphic>(true, s_Graphics);
var fixTargets = s_Graphics
.Where(x => x.gameObject != current.gameObject)
.Where(x => !x.GetComponent<SoftMaskable>() && (!x.GetComponent<Mask>() || x.GetComponent<Mask>().showMaskGraphic))
.ToList();
if (0 < fixTargets.Count)
{
GUILayout.BeginHorizontal();
EditorGUILayout.HelpBox("There are child Graphics that does not have a SoftMaskable component.\nAdd SoftMaskable component to them.", MessageType.Warning);
GUILayout.BeginVertical();
if (GUILayout.Button("Fix"))
{
foreach (var p in fixTargets)
{
p.gameObject.AddComponent<SoftMaskable>();
}
// Preview buffer.
GUILayout.BeginHorizontal (EditorStyles.helpBox);
if (s_Preview != (s_Preview = EditorGUILayout.ToggleLeft ("Preview Buffer", s_Preview, GUILayout.MaxWidth (EditorGUIUtility.labelWidth))))
{
EditorPrefs.SetBool (k_PrefsPreview, s_Preview);
}
if (s_Preview)
{
var tex = current.softMaskBuffer;
var wtdth = tex.width * 64 / tex.height;
EditorGUI.DrawPreviewTexture (GUILayoutUtility.GetRect (wtdth, 64), tex, null, ScaleMode.ScaleToFit);
Repaint ();
}
GUILayout.FlexibleSpace ();
GUILayout.EndHorizontal ();
}
EditorUtils.MarkPrefabDirty();
}
if (GUILayout.Button("Ping"))
{
EditorGUIUtility.PingObject(fixTargets[0]);
}
GUILayout.EndVertical();
GUILayout.EndHorizontal();
}
var currentImage = current.graphic as Image;
if (currentImage && IsMaskUI(currentImage.sprite))
{
GUILayout.BeginHorizontal();
EditorGUILayout.HelpBox("SoftMask does not recommend to use 'UIMask' sprite as a source image.\n(It contains only small alpha pixels.)\nDo you want to use 'UISprite' instead?", MessageType.Warning);
GUILayout.BeginVertical();
if (GUILayout.Button("Fix"))
{
currentImage.sprite = AssetDatabase.GetBuiltinExtraResource<Sprite>("UI/Skin/UISprite.psd");
}
GUILayout.EndVertical();
GUILayout.EndHorizontal();
}
// Preview buffer.
GUILayout.BeginVertical(EditorStyles.helpBox);
if (s_Preview != (s_Preview = EditorGUILayout.ToggleLeft("Preview Soft Mask Buffer", s_Preview)))
{
EditorPrefs.SetBool(k_PrefsPreview, s_Preview);
}
if (s_Preview)
{
var tex = current.softMaskBuffer;
var width = tex.width * k_PreviewSize / tex.height;
EditorGUI.DrawPreviewTexture(GUILayoutUtility.GetRect(width, k_PreviewSize), tex, null, ScaleMode.ScaleToFit);
Repaint();
}
GUILayout.EndVertical();
}
private static bool IsMaskUI(Object obj)
{
return obj
&& obj.name == "UIMask"
&& AssetDatabase.GetAssetPath(obj) == "Resources/unity_builtin_extra";
}
//%%%% Context menu for editor %%%%
[MenuItem("CONTEXT/Mask/Convert To SoftMask", true)]
static bool _ConvertToSoftMask(MenuCommand command)
{
return CanConvertTo<SoftMask>(command.context);
}
//%%%% Context menu for editor %%%%
[MenuItem("CONTEXT/Mask/Convert To SoftMask", true)]
private static bool _ConvertToSoftMask(MenuCommand command)
{
return EditorUtils.CanConvertTo<SoftMask>(command.context);
}
[MenuItem("CONTEXT/Mask/Convert To SoftMask", false)]
static void ConvertToSoftMask(MenuCommand command)
{
ConvertTo<SoftMask>(command.context);
}
[MenuItem("CONTEXT/Mask/Convert To SoftMask", false)]
private static void ConvertToSoftMask(MenuCommand command)
{
EditorUtils.ConvertTo<SoftMask>(command.context);
}
[MenuItem("CONTEXT/Mask/Convert To Mask", true)]
static bool _ConvertToMask(MenuCommand command)
{
return CanConvertTo<Mask>(command.context);
}
[MenuItem("CONTEXT/Mask/Convert To Mask", true)]
private static bool _ConvertToMask(MenuCommand command)
{
return EditorUtils.CanConvertTo<Mask>(command.context);
}
[MenuItem("CONTEXT/Mask/Convert To Mask", false)]
static void ConvertToMask(MenuCommand command)
{
ConvertTo<Mask>(command.context);
}
/// <summary>
/// Verify whether it can be converted to the specified component.
/// </summary>
protected static bool CanConvertTo<T>(Object context)
where T : MonoBehaviour
{
return context && context.GetType() != typeof(T);
}
/// <summary>
/// Convert to the specified component.
/// </summary>
protected static void ConvertTo<T>(Object context) where T : MonoBehaviour
{
var target = context as MonoBehaviour;
var so = new SerializedObject(target);
so.Update();
bool oldEnable = target.enabled;
target.enabled = false;
// Find MonoScript of the specified component.
foreach (var script in Resources.FindObjectsOfTypeAll<MonoScript>())
{
if (script.GetClass() != typeof(T))
continue;
// Set 'm_Script' to convert.
so.FindProperty("m_Script").objectReferenceValue = script;
so.ApplyModifiedProperties();
break;
}
(so.targetObject as MonoBehaviour).enabled = oldEnable;
}
}
}
[MenuItem("CONTEXT/Mask/Convert To Mask", false)]
private static void ConvertToMask(MenuCommand command)
{
EditorUtils.ConvertTo<Mask>(command.context);
}
}
}

View File

@ -1,386 +1,138 @@
using System.Collections.Generic;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEditor;
using System.Linq;
using System;
using System.Reflection;
using Object = UnityEngine.Object;
using MaskIntr = UnityEngine.SpriteMaskInteraction;
using System.IO;
namespace Coffee.UIExtensions.Editors
namespace Coffee.UISoftMask
{
/// <summary>
/// SoftMaskable editor.
/// </summary>
[CustomEditor (typeof (SoftMaskable))]
[CanEditMultipleObjects]
public class SoftMaskableEditor : Editor
{
//################################
// Constant or Static Members.
//################################
public enum MaskInteraction : int
{
VisibleInsideMask = (1 << 0) + (1 << 2) + (1 << 4) + (1 << 6),
VisibleOutsideMask = (2 << 0) + (2 << 2) + (2 << 4) + (2 << 6),
Custom = -1,
}
internal enum MaskInteraction : int
{
VisibleInsideMask = (1 << 0) + (1 << 2) + (1 << 4) + (1 << 6),
VisibleOutsideMask = (2 << 0) + (2 << 2) + (2 << 4) + (2 << 6),
Custom = -1,
}
MaskInteraction maskInteraction
{
get
{
int value = _spMaskInteraction.intValue;
return _custom
? MaskInteraction.Custom
: System.Enum.IsDefined(typeof(MaskInteraction), value)
? (MaskInteraction)value
: MaskInteraction.Custom;
}
set
{
_custom = (value == MaskInteraction.Custom);
if (!_custom)
{
_spMaskInteraction.intValue = (int)value;
}
}
}
bool _custom = false;
/// <summary>
/// SoftMaskable editor.
/// </summary>
[CustomEditor(typeof(SoftMaskable))]
[CanEditMultipleObjects]
public class SoftMaskableEditor : Editor
{
private static readonly List<Mask> s_TmpMasks = new List<Mask>();
private static GUIContent s_MaskWarning;
private SerializedProperty _spMaskInteraction;
private bool _custom;
static readonly Type s_TypeTMPro = AppDomain.CurrentDomain.GetAssemblies ().SelectMany (x => x.GetTypes ()).FirstOrDefault (x => x.Name == "TMP_Text");
static readonly Type s_TypeTMP_SpriteAsset = AppDomain.CurrentDomain.GetAssemblies ().SelectMany (x => x.GetTypes ()).FirstOrDefault (x => x.Name == "TMP_SpriteAsset");
static readonly Type s_TypeTMProSettings = AppDomain.CurrentDomain.GetAssemblies ().SelectMany (x => x.GetTypes ()).FirstOrDefault (x => x.Name == "TMP_Settings");
static readonly Type s_TypeTMP_SubMesh = AppDomain.CurrentDomain.GetAssemblies ().SelectMany (x => x.GetTypes ()).FirstOrDefault (x => x.Name == "TMP_SubMesh");
static readonly Type s_TypeTMP_SubMeshUI = AppDomain.CurrentDomain.GetAssemblies ().SelectMany (x => x.GetTypes ()).FirstOrDefault (x => x.Name == "TMP_SubMeshUI");
static PropertyInfo s_PiFontSharedMaterial;
static PropertyInfo s_PiFontSharedMaterials;
static PropertyInfo s_PiSpriteAsset;
static PropertyInfo s_PiRichText;
static PropertyInfo s_PiText;
static PropertyInfo s_PiDefaultFontAssetPath;
static PropertyInfo s_PiDefaultSpriteAssetPath;
static FieldInfo s_FiMaterial;
static MethodInfo s_miGetSpriteAsset;
static readonly List<Graphic> s_Graphics = new List<Graphic> ();
Shader _shader;
Shader _mobileShader;
Shader _spriteShader;
List<MaterialEditor> _materialEditors = new List<MaterialEditor> ();
SerializedProperty _spMaskInteraction;
private void OnEnable ()
{
_spMaskInteraction = serializedObject.FindProperty("m_MaskInteraction");
_custom = (maskInteraction == MaskInteraction.Custom);
ClearMaterialEditors ();
_shader = Shader.Find ("TextMeshPro/Distance Field (SoftMaskable)");
_mobileShader = Shader.Find ("TextMeshPro/Mobile/Distance Field (SoftMaskable)");
_spriteShader = Shader.Find ("TextMeshPro/Sprite (SoftMaskable)");
if(s_TypeTMPro != null)
{
s_PiFontSharedMaterial = s_TypeTMPro.GetProperty ("fontSharedMaterial");
s_PiSpriteAsset = s_TypeTMPro.GetProperty ("spriteAsset");
s_PiRichText = s_TypeTMPro.GetProperty ("richText");
s_PiText = s_TypeTMPro.GetProperty ("text");
s_FiMaterial = s_TypeTMP_SpriteAsset.GetField ("material");
s_PiFontSharedMaterials = s_TypeTMPro.GetProperty ("fontSharedMaterials");
s_miGetSpriteAsset = s_TypeTMProSettings.GetMethod ("GetSpriteAsset", BindingFlags.Static | BindingFlags.Public);
s_PiDefaultFontAssetPath = s_TypeTMProSettings.GetProperty ("defaultFontAssetPath", BindingFlags.Static | BindingFlags.Public);
s_PiDefaultSpriteAssetPath = s_TypeTMProSettings.GetProperty ("defaultSpriteAssetPath", BindingFlags.Static | BindingFlags.Public);
}
s_MaskWarning = new GUIContent(EditorGUIUtility.FindTexture("console.warnicon.sml"), "This component is not SoftMask. Use SoftMask instead of Mask.");
}
private void OnDisable ()
{
ClearMaterialEditors ();
}
List<Mask> tmpMasks = new List<Mask>();
void DrawMaskInteractions()
{
(target as SoftMaskable).GetComponentsInParent<Mask>(true, tmpMasks);
tmpMasks.RemoveAll(x => !x.enabled);
tmpMasks.Reverse();
maskInteraction = (MaskInteraction)EditorGUILayout.EnumPopup("Mask Interaction", maskInteraction);
if (_custom)
{
var l = EditorGUIUtility.labelWidth;
EditorGUIUtility.labelWidth = 45;
using (var ccs = new EditorGUI.ChangeCheckScope())
{
int intr0 = DrawMaskInteraction(0);
int intr1 = DrawMaskInteraction(1);
int intr2 = DrawMaskInteraction(2);
int intr3 = DrawMaskInteraction(3);
if (ccs.changed) {
_spMaskInteraction.intValue = (intr0 << 0) + (intr1 << 2) + (intr2 << 4) + (intr3 << 6);
}
}
EditorGUIUtility.labelWidth = l;
}
}
static GUIContent s_MaskWarning = new GUIContent();
int DrawMaskInteraction(int layer)
{
Mask mask = layer < tmpMasks.Count ? tmpMasks[layer] : null;
MaskIntr intr = (MaskIntr)((_spMaskInteraction.intValue >> layer * 2) & 0x3);
if (!mask)
{
return (int)intr;
}
using (new EditorGUILayout.HorizontalScope())
{
EditorGUILayout.LabelField(mask is SoftMask ? GUIContent.none : s_MaskWarning, GUILayout.Width(16));
GUILayout.Space(-5);
EditorGUILayout.ObjectField("Mask " + layer, mask, typeof(Mask), false);
GUILayout.Space(-15);
return (int)(MaskIntr)EditorGUILayout.EnumPopup(intr);
}
}
public override void OnInspectorGUI ()
{
base.OnInspectorGUI ();
serializedObject.Update();
DrawMaskInteractions();
// maskInteraction = (MaskInteraction)EditorGUILayout.EnumPopup("Mask Interaction", maskInteraction);
serializedObject.ApplyModifiedProperties();
/*
EditorGUI.indentLevel++;
var l = EditorGUIUtility.labelWidth;
EditorGUIUtility.labelWidth = 60;
using (new EditorGUILayout.HorizontalScope())
{
EditorGUILayout.ObjectField("Mask 0", null, typeof(Mask), false);
EditorGUILayout.EnumPopup (MaskIntr.None);
}
EditorGUIUtility.labelWidth = l;
EditorGUI.indentLevel--;
var spMaskInteraction = serializedObject.FindProperty ("m_MaskInteraction");
MaskIntr intr0 = (MaskIntr)((spMaskInteraction.intValue >> 0) & 0x3);
MaskIntr intr1 = (MaskIntr)((spMaskInteraction.intValue >> 2) & 0x3);
MaskIntr intr2 = (MaskIntr)((spMaskInteraction.intValue >> 4) & 0x3);
MaskIntr intr3 = (MaskIntr)((spMaskInteraction.intValue >> 6) & 0x3);
using (var ccs = new EditorGUI.ChangeCheckScope ()) {
intr0 = (MaskIntr)EditorGUILayout.EnumPopup ("Layer 0", intr0);
intr1 = (MaskIntr)EditorGUILayout.EnumPopup ("Layer 1", intr1);
intr2 = (MaskIntr)EditorGUILayout.EnumPopup ("Layer 2", intr2);
intr3 = (MaskIntr)EditorGUILayout.EnumPopup ("Layer 3", intr3);
if (ccs.changed) {
current.SetMaskInteractions (intr0,intr1,intr2,intr3);
}
}
*/
// spMaskInteraction.intValue = (intr0 << 0) | (intr1 << 2) | (intr2 << 4) | (intr3 << 6);
//
// serializedObject.ApplyModifiedProperties ();
private MaskInteraction maskInteraction
{
get
{
var value = _spMaskInteraction.intValue;
return _custom
? MaskInteraction.Custom
: System.Enum.IsDefined(typeof(MaskInteraction), value)
? (MaskInteraction) value
: MaskInteraction.Custom;
}
set
{
_custom = (value == MaskInteraction.Custom);
if (!_custom)
{
_spMaskInteraction.intValue = (int) value;
}
}
}
private void OnEnable()
{
_spMaskInteraction = serializedObject.FindProperty("m_MaskInteraction");
_custom = (maskInteraction == MaskInteraction.Custom);
if (s_MaskWarning == null)
{
s_MaskWarning = new GUIContent(EditorGUIUtility.FindTexture("console.warnicon.sml"), "This is not a SoftMask component.");
}
}
// var current = target as SoftMaskable;
var current = target as SoftMaskable;
current.GetComponentsInChildren<Graphic> (true, s_Graphics);
var fixTargets = s_Graphics.Where (x => x.gameObject != current.gameObject && !x.GetComponent<SoftMaskable> () && (!x.GetComponent<Mask> () || x.GetComponent<Mask> ().showMaskGraphic)).ToList ();
if (0 < fixTargets.Count)
{
GUILayout.BeginHorizontal ();
EditorGUILayout.HelpBox ("There are child Graphicss that does not have a SoftMaskable component.\nAdd SoftMaskable component to them.", MessageType.Warning);
GUILayout.BeginVertical ();
if (GUILayout.Button ("Fix"))
{
foreach (var p in fixTargets)
{
p.gameObject.AddComponent<SoftMaskable> ();
}
}
if (GUILayout.Button ("Ping"))
{
EditorGUIUtility.PingObject (fixTargets [0]);
}
GUILayout.EndVertical ();
GUILayout.EndHorizontal ();
}
private void DrawMaskInteractions()
{
var softMaskable = target as SoftMaskable;
if (softMaskable == null) return;
if(s_TypeTMPro != null)
{
ShowTMProWarning (_shader, _mobileShader, _spriteShader, m => { });
var textMeshPro = current.GetComponent (s_TypeTMPro);
if (textMeshPro != null)
{
Material [] fontSharedMaterials = s_PiFontSharedMaterials.GetValue (textMeshPro, new object [0]) as Material [];
ShowMaterialEditors (fontSharedMaterials, 1, fontSharedMaterials.Length - 1);
}
}
}
softMaskable.GetComponentsInParent<Mask>(true, s_TmpMasks);
s_TmpMasks.RemoveAll(x => !x.enabled);
s_TmpMasks.Reverse();
void ClearMaterialEditors ()
{
foreach (var e in _materialEditors)
{
if (e)
{
DestroyImmediate (e);
}
}
_materialEditors.Clear ();
}
maskInteraction = (MaskInteraction) EditorGUILayout.EnumPopup("Mask Interaction", maskInteraction);
if (!_custom) return;
protected void ShowMaterialEditors (Material [] materials, int startIndex, int count)
{
for (int i = 0; i < count; i++)
{
if (_materialEditors.Count == i)
{
_materialEditors.Add (null);
}
var l = EditorGUIUtility.labelWidth;
EditorGUIUtility.labelWidth = 45;
var mat = materials [startIndex + i];
var editor = _materialEditors [i];
if (editor && editor.target != mat)
{
DestroyImmediate (editor);
editor = null;
}
using (var ccs = new EditorGUI.ChangeCheckScope())
{
var intr0 = DrawMaskInteraction(0);
var intr1 = DrawMaskInteraction(1);
var intr2 = DrawMaskInteraction(2);
var intr3 = DrawMaskInteraction(3);
if (!editor)
{
editor = _materialEditors [i] = Editor.CreateEditor (mat) as MaterialEditor;
}
if (ccs.changed)
{
_spMaskInteraction.intValue = (intr0 << 0) + (intr1 << 2) + (intr2 << 4) + (intr3 << 6);
}
}
editor.DrawHeader ();
editor.OnInspectorGUI ();
}
}
EditorGUIUtility.labelWidth = l;
}
public void ShowTMProWarning (Shader shader, Shader mobileShader, Shader spriteShader, System.Action<Material> onCreatedMaterial)
{
var current = target as SoftMaskable;
var textMeshPro = current.GetComponent (s_TypeTMPro);
if (textMeshPro == null)
{
return;
}
private int DrawMaskInteraction(int layer)
{
var mask = layer < s_TmpMasks.Count ? s_TmpMasks[layer] : null;
var intr = (MaskIntr) ((_spMaskInteraction.intValue >> layer * 2) & 0x3);
if (!mask)
{
return (int) intr;
}
Material fontSharedMaterial = s_PiFontSharedMaterial.GetValue (textMeshPro, new object [0]) as Material;
if (fontSharedMaterial == null)
{
return;
}
GUILayout.BeginHorizontal();
EditorGUILayout.LabelField(mask is SoftMask ? GUIContent.none : s_MaskWarning, GUILayout.Width(16));
GUILayout.Space(-5);
EditorGUILayout.ObjectField("Mask " + layer, mask, typeof(Mask), false);
GUILayout.Space(-15);
intr = (MaskIntr) EditorGUILayout.EnumPopup(intr);
GUILayout.EndHorizontal();
// Is the material preset for dissolve?
Material m = fontSharedMaterial;
if (m.shader != shader && m.shader != mobileShader)
{
EditorGUILayout.BeginHorizontal ();
EditorGUILayout.HelpBox (string.Format ("{0} requires '{1}' or '{2}' as a shader for material preset.", current.GetType ().Name, shader.name, mobileShader.name), MessageType.Warning);
if (GUILayout.Button ("Fix"))
{
var correctShader = m.shader.name.Contains ("Mobile") ? mobileShader : shader;
m = ModifyTMProMaterialPreset (m, correctShader, onCreatedMaterial);
s_PiFontSharedMaterial.SetValue (textMeshPro, m, new object [0]);
}
EditorGUILayout.EndHorizontal ();
return;
}
return (int) intr;
}
// Is the sprite asset for dissolve?
object spriteAsset = s_PiSpriteAsset.GetValue (textMeshPro, new object [0]) ?? s_miGetSpriteAsset.Invoke (null, new object [0]);
//TMP_SpriteAsset spriteAsset = textMeshPro.spriteAsset ?? TMP_Settings.GetSpriteAsset ();
m = s_FiMaterial.GetValue (spriteAsset) as Material;
bool hasSprite = (bool)s_PiRichText.GetValue (textMeshPro, new object [0]) && (s_PiText.GetValue (textMeshPro, new object [0]) as string).Contains ("<sprite=");
if (m && m.shader != spriteShader && hasSprite)
{
EditorGUILayout.BeginHorizontal ();
EditorGUILayout.HelpBox (string.Format ("{0} requires '{1}' as a shader for sprite asset.", GetType ().Name, spriteShader.name), MessageType.Warning);
if (GUILayout.Button ("Fix"))
{
current.GetComponentsInChildren (s_TypeTMP_SubMesh).Select (x => x.gameObject).ToList ().ForEach (DestroyImmediate);
current.GetComponentsInChildren (s_TypeTMP_SubMeshUI).Select (x => x.gameObject).ToList ().ForEach (DestroyImmediate);
spriteAsset = ModifyTMProSpriteAsset (m, _spriteShader, mat => { });
s_PiSpriteAsset.SetValue (textMeshPro, spriteAsset, new object [0]);
}
EditorGUILayout.EndHorizontal ();
return;
}
}
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
Material ModifyTMProMaterialPreset (Material baseMaterial, Shader shader, System.Action<Material> onCreatedMaterial)
{
string path = AssetDatabase.GetAssetPath (baseMaterial);
string filename = Path.GetFileNameWithoutExtension (path) + " (" + typeof (SoftMaskable).Name + ")";
string defaultAssetPath = s_PiDefaultFontAssetPath.GetValue (null, new object [0]) as string;
Material mat = Resources.Load<Material> (defaultAssetPath + filename);
if (!mat)
{
mat = new Material (baseMaterial)
{
shaderKeywords = baseMaterial.shaderKeywords,
shader = shader,
};
onCreatedMaterial (mat);
AssetDatabase.CreateAsset (mat, Path.GetDirectoryName (path) + "/" + filename + ".mat");
serializedObject.Update();
DrawMaskInteractions();
EditorUtility.FocusProjectWindow ();
EditorGUIUtility.PingObject (mat);
}
else
{
mat.shader = shader;
}
EditorUtility.SetDirty (mat);
return mat;
}
serializedObject.ApplyModifiedProperties();
object ModifyTMProSpriteAsset (Material baseMaterial, Shader shader, System.Action<Material> onCreatedMaterial)
{
string path = AssetDatabase.GetAssetPath (baseMaterial);
string filename = Path.GetFileNameWithoutExtension (path) + " (" + typeof (SoftMaskable).Name + ")";
string defaultAssetPath = s_PiDefaultSpriteAssetPath.GetValue (null, new object [0]) as string;
Object spriteAsset = Resources.Load (defaultAssetPath + filename, s_TypeTMP_SpriteAsset);
if (spriteAsset == null)
{
AssetDatabase.CopyAsset (path, Path.GetDirectoryName (path) + "/" + filename + ".mat");
spriteAsset = Resources.Load (defaultAssetPath + filename, s_TypeTMP_SpriteAsset);
Material m = s_FiMaterial.GetValue (spriteAsset) as Material;
m.shader = shader;
m.name = shader.name;
onCreatedMaterial (m);
var current = target as SoftMaskable;
if (current == null) return;
EditorUtility.FocusProjectWindow ();
EditorGUIUtility.PingObject (spriteAsset);
}
else
{
Material m = s_FiMaterial.GetValue (spriteAsset) as Material;
m.shader = shader;
}
EditorUtility.SetDirty (spriteAsset);
return spriteAsset;
}
}
}
var mask = current.softMask;
if (mask) return;
GUILayout.BeginHorizontal();
EditorGUILayout.HelpBox("This is unnecessary SoftMaskable.\nCan't find any SoftMask components above.", MessageType.Warning);
if (GUILayout.Button("Remove", GUILayout.Height(40)))
{
DestroyImmediate(current);
EditorUtils.MarkPrefabDirty();
}
GUILayout.EndHorizontal();
}
}
}

106
Scripts/GraphicConnector.cs Normal file
View File

@ -0,0 +1,106 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
namespace Coffee.UISoftMask
{
internal static class GraphicConnectorExtension
{
public static void SetVerticesDirtyEx(this Graphic graphic)
{
GraphicConnector.FindConnector(graphic).SetVerticesDirty(graphic);
}
public static void SetMaterialDirtyEx(this Graphic graphic)
{
GraphicConnector.FindConnector(graphic).SetMaterialDirty(graphic);
}
public static T GetComponentInParentEx<T>(this Component component, bool includeInactive = false) where T : MonoBehaviour
{
if (!component) return null;
var trans = component.transform;
while (trans)
{
var c = trans.GetComponent<T>();
if (c && (includeInactive || c.isActiveAndEnabled)) return c;
trans = trans.parent;
}
return null;
}
}
public class GraphicConnector
{
private static readonly List<GraphicConnector> s_Connectors = new List<GraphicConnector>();
private static readonly Dictionary<Type, GraphicConnector> s_ConnectorMap = new Dictionary<Type, GraphicConnector>();
private static readonly GraphicConnector s_EmptyConnector = new GraphicConnector();
#if UNITY_EDITOR
[UnityEditor.InitializeOnLoadMethod]
#endif
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
private static void Init()
{
AddConnector(new GraphicConnector());
}
protected static void AddConnector(GraphicConnector connector)
{
s_Connectors.Add(connector);
s_Connectors.Sort((x, y) => y.priority - x.priority);
}
public static GraphicConnector FindConnector(Graphic graphic)
{
if (!graphic) return s_EmptyConnector;
var type = graphic.GetType();
GraphicConnector connector = null;
if (s_ConnectorMap.TryGetValue(type, out connector)) return connector;
foreach (var c in s_Connectors)
{
if (!c.IsValid(graphic)) continue;
s_ConnectorMap.Add(type, c);
return c;
}
return s_EmptyConnector;
}
/// <summary>
/// Connector priority.
/// </summary>
protected virtual int priority
{
get { return -1; }
}
/// <summary>
/// The connector is valid for the component.
/// </summary>
protected virtual bool IsValid(Graphic graphic)
{
return true;
}
public virtual void SetVerticesDirty(Graphic graphic)
{
if (graphic)
graphic.SetVerticesDirty();
}
public virtual void SetMaterialDirty(Graphic graphic)
{
if (graphic)
graphic.SetMaterialDirty();
}
}
}

View File

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

82
Scripts/MaterialCache.cs Normal file
View File

@ -0,0 +1,82 @@
using System.Collections.Generic;
using System;
using UnityEngine;
namespace Coffee.UISoftMask
{
internal class MaterialEntry
{
public Material material;
public int referenceCount;
public void Release()
{
if (material)
{
#if UNITY_EDITOR
if (!Application.isPlaying)
UnityEngine.Object.DestroyImmediate(material, false);
else
#endif
UnityEngine.Object.Destroy(material);
}
material = null;
}
}
internal static class MaterialCache
{
static readonly Dictionary<Hash128, MaterialEntry> s_MaterialMap = new Dictionary<Hash128, MaterialEntry>();
#if UNITY_EDITOR
[UnityEditor.InitializeOnLoadMethod]
private static void ClearCache()
{
foreach (var entry in s_MaterialMap.Values)
{
entry.Release();
}
s_MaterialMap.Clear();
}
#endif
public static Material Register(Material material, Hash128 hash, Action<Material> onModify)
{
if (!hash.isValid) return null;
MaterialEntry entry;
if (!s_MaterialMap.TryGetValue(hash, out entry))
{
entry = new MaterialEntry()
{
material = new Material(material)
{
hideFlags = HideFlags.HideAndDontSave,
},
};
onModify(entry.material);
s_MaterialMap.Add(hash, entry);
}
entry.referenceCount++;
//Debug.LogFormat("Register: {0}, {1} (Total: {2})", hash, entry.referenceCount, materialMap.Count);
return entry.material;
}
public static void Unregister(Hash128 hash)
{
MaterialEntry entry;
if (!hash.isValid || !s_MaterialMap.TryGetValue(hash, out entry)) return;
//Debug.LogFormat("Unregister: {0}, {1}", hash, entry.referenceCount -1);
if (--entry.referenceCount > 0) return;
entry.Release();
s_MaterialMap.Remove(hash);
//Debug.LogFormat("Unregister: Release Emtry: {0}, {1} (Total: {2})", hash, entry.referenceCount, materialMap.Count);
}
}
}

View File

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

File diff suppressed because it is too large Load Diff

649
Scripts/SoftMaskable.cs Normal file → Executable file
View File

@ -1,333 +1,348 @@
using System.Collections;
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Profiling;
using UnityEngine.Rendering;
using UnityEngine.UI;
using MaskIntr = UnityEngine.SpriteMaskInteraction;
using UnityEngine.Serialization;
namespace Coffee.UIExtensions
namespace Coffee.UISoftMask
{
/// <summary>
/// Soft maskable.
/// Add this component to Graphic under SoftMask for smooth masking.
/// </summary>
/// <summary>
/// Soft maskable.
/// Add this component to Graphic under SoftMask for smooth masking.
/// </summary>
#if UNITY_2018_3_OR_NEWER
[ExecuteAlways]
#else
[ExecuteInEditMode]
public class SoftMaskable : MonoBehaviour, IMaterialModifier, ICanvasRaycastFilter, ISerializationCallbackReceiver
{
//################################
// Constant or Static Members.
//################################
const int kVisibleInside = (1 << 0) + (1 << 2) + (1 << 4) + (1 << 6);
const int kVisibleOutside = (2 << 0) + (2 << 2) + (2 << 4) + (2 << 6);
# endif
[RequireComponent(typeof(Graphic))]
public class SoftMaskable : MonoBehaviour, IMaterialModifier, ICanvasRaycastFilter
#if UNITY_EDITOR
, ISerializationCallbackReceiver
# endif
{
private const int kVisibleInside = (1 << 0) + (1 << 2) + (1 << 4) + (1 << 6);
private const int kVisibleOutside = (2 << 0) + (2 << 2) + (2 << 4) + (2 << 6);
private static readonly Hash128 k_InvalidHash = new Hash128();
private static int s_SoftMaskTexId;
private static int s_StencilCompId;
private static int s_MaskInteractionId;
private static int s_GameVPId;
private static int s_GameTVPId;
private static List<SoftMaskable> s_ActiveSoftMaskables;
private static int[] s_Interactions = new int[4];
[SerializeField, HideInInspector, System.Obsolete]
private bool m_Inverse;
[SerializeField, Tooltip("The interaction for each masks."), HideInInspector]
private int m_MaskInteraction = kVisibleInside;
[SerializeField, Tooltip("Use stencil to mask.")]
private bool m_UseStencil = true;
[SerializeField, Tooltip("Use soft-masked raycast target.\n\nNote: This option is expensive.")]
private bool m_RaycastFilter;
private Graphic _graphic;
private SoftMask _softMask;
private Hash128 _effectMaterialHash;
/// <summary>
/// The graphic will be visible only in areas where no mask is present.
/// </summary>
public bool inverse
{
get { return m_MaskInteraction == kVisibleOutside; }
set
{
var intValue = value ? kVisibleOutside : kVisibleInside;
if (m_MaskInteraction == intValue) return;
m_MaskInteraction = intValue;
graphic.SetMaterialDirtyEx();
}
}
/// <summary>
/// Use soft-masked raycast target. This option is expensive.
/// </summary>
public bool raycastFilter
{
get { return m_RaycastFilter; }
set { m_RaycastFilter = value; }
}
/// <summary>
/// Use stencil to mask.
/// </summary>
public bool useStencil
{
get { return m_UseStencil; }
set
{
if (m_UseStencil == value) return;
m_UseStencil = value;
graphic.SetMaterialDirtyEx();
}
}
/// <summary>
/// The graphic associated with the soft mask.
/// </summary>
public Graphic graphic
{
get { return _graphic ? _graphic : _graphic = GetComponent<Graphic>(); }
}
public SoftMask softMask
{
get { return _softMask ? _softMask : _softMask = this.GetComponentInParentEx<SoftMask>(); }
}
public Material modifiedMaterial { get; private set; }
/// <summary>
/// Perform material modification in this function.
/// </summary>
/// <returns>Modified material.</returns>
/// <param name="baseMaterial">Configured Material.</param>
Material IMaterialModifier.GetModifiedMaterial(Material baseMaterial)
{
_softMask = null;
modifiedMaterial = null;
// If this component is disabled, the material is returned as is.
// If the parents do not have a soft mask component, the material is returned as is.
if (!isActiveAndEnabled || !softMask)
{
MaterialCache.Unregister(_effectMaterialHash);
_effectMaterialHash = k_InvalidHash;
return baseMaterial;
}
// Generate soft maskable material.
var previousHash = _effectMaterialHash;
_effectMaterialHash = new Hash128(
(uint) baseMaterial.GetInstanceID(),
(uint) softMask.GetInstanceID(),
(uint) m_MaskInteraction,
(uint) (m_UseStencil ? 1 : 0)
);
// Generate soft maskable material.
modifiedMaterial = MaterialCache.Register(baseMaterial, _effectMaterialHash, mat =>
{
mat.shader = Shader.Find(string.Format("Hidden/{0} (SoftMaskable)", mat.shader.name));
mat.SetTexture(s_SoftMaskTexId, softMask.softMaskBuffer);
mat.SetInt(s_StencilCompId, m_UseStencil ? (int) CompareFunction.Equal : (int) CompareFunction.Always);
#if UNITY_EDITOR
mat.EnableKeyword("SOFTMASK_EDITOR");
UpdateMaterialForSceneView(mat);
#endif
var root = MaskUtilities.FindRootSortOverrideCanvas(transform);
var stencil = MaskUtilities.GetStencilDepth(transform, root);
mat.SetVector(s_MaskInteractionId, new Vector4(
1 <= stencil ? (m_MaskInteraction >> 0 & 0x3) : 0,
2 <= stencil ? (m_MaskInteraction >> 2 & 0x3) : 0,
3 <= stencil ? (m_MaskInteraction >> 4 & 0x3) : 0,
4 <= stencil ? (m_MaskInteraction >> 6 & 0x3) : 0
));
});
// Unregister the previous material.
MaterialCache.Unregister(previousHash);
return modifiedMaterial;
}
/// <summary>
/// Given a point and a camera is the raycast valid.
/// </summary>
/// <returns>Valid.</returns>
/// <param name="sp">Screen position.</param>
/// <param name="eventCamera">Raycast camera.</param>
bool ICanvasRaycastFilter.IsRaycastLocationValid(Vector2 sp, Camera eventCamera)
{
if (!isActiveAndEnabled || !softMask)
return true;
if (!RectTransformUtility.RectangleContainsScreenPoint(transform as RectTransform, sp, eventCamera))
return false;
if (m_RaycastFilter)
{
var sm = _softMask;
for (var i = 0; i < 4; i++)
{
s_Interactions[i] = sm ? ((m_MaskInteraction >> i * 2) & 0x3) : 0;
sm = sm ? sm.parent : null;
}
return _softMask.IsRaycastLocationValid(sp, eventCamera, graphic, s_Interactions);
}
else
{
var sm = _softMask;
for (var i = 0; i < 4; i++)
{
if (!sm) break;
s_Interactions[i] = sm ? ((m_MaskInteraction >> i * 2) & 0x3) : 0;
var interaction = s_Interactions[i] == 1;
var rt = sm.transform as RectTransform;
var inRect = RectTransformUtility.RectangleContainsScreenPoint(rt, sp, eventCamera);
if (!sm.ignoreSelfGraphic && interaction != inRect) return false;
foreach (var child in sm._children)
{
if (!child) continue;
var childRt = child.transform as RectTransform;
var inRectChild = RectTransformUtility.RectangleContainsScreenPoint(childRt, sp, eventCamera);
if (!child.ignoreSelfGraphic && interaction != inRectChild) return false;
}
sm = sm ? sm.parent : null;
}
return true;
}
}
/// <summary>
/// Set the interaction for each mask.
/// </summary>
public void SetMaskInteraction(MaskIntr intr)
{
SetMaskInteraction(intr, intr, intr, intr);
}
/// <summary>
/// Set the interaction for each mask.
/// </summary>
public void SetMaskInteraction(MaskIntr layer0, MaskIntr layer1, MaskIntr layer2, MaskIntr layer3)
{
m_MaskInteraction = (int) layer0 + ((int) layer1 << 2) + ((int) layer2 << 4) + ((int) layer3 << 6);
graphic.SetMaterialDirtyEx();
}
//################################
// Serialize Members.
//################################
[Tooltip("The graphic will be visible only in areas where no mask is present.")]
[System.Obsolete]
[HideInInspector]
[SerializeField] bool m_Inverse = false;
[Tooltip("The interaction for each masks.")]
[HideInInspector]
[SerializeField] int m_MaskInteraction = kVisibleInside;
[Tooltip("Use stencil for masking.")]
[SerializeField] bool m_UseStencil = false;
/// <summary>
/// This function is called when the object becomes enabled and active.
/// </summary>
private void OnEnable()
{
// Register.
if (s_ActiveSoftMaskables == null)
{
s_ActiveSoftMaskables = new List<SoftMaskable>();
s_SoftMaskTexId = Shader.PropertyToID("_SoftMaskTex");
s_StencilCompId = Shader.PropertyToID("_StencilComp");
s_MaskInteractionId = Shader.PropertyToID("_MaskInteraction");
#if UNITY_EDITOR
s_GameVPId = Shader.PropertyToID("_GameVP");
s_GameTVPId = Shader.PropertyToID("_GameTVP");
#endif
}
s_ActiveSoftMaskables.Add(this);
graphic.SetMaterialDirtyEx();
_softMask = null;
}
/// <summary>
/// This function is called when the behaviour becomes disabled.
/// </summary>
private void OnDisable()
{
s_ActiveSoftMaskables.Remove(this);
graphic.SetMaterialDirtyEx();
_softMask = null;
MaterialCache.Unregister(_effectMaterialHash);
_effectMaterialHash = k_InvalidHash;
}
#if UNITY_EDITOR
private void UpdateMaterialForSceneView(Material mat)
{
if(!mat || !graphic || !graphic.canvas || !mat.shader || !mat.shader.name.EndsWith(" (SoftMaskable)")) return;
// Set view and projection matrices.
Profiler.BeginSample("Set view and projection matrices");
var c = graphic.canvas.rootCanvas;
var cam = c.worldCamera ?? Camera.main;
if (c && c.renderMode != RenderMode.ScreenSpaceOverlay && cam)
{
var p = GL.GetGPUProjectionMatrix(cam.projectionMatrix, false);
var pv = p * cam.worldToCameraMatrix;
mat.SetMatrix(s_GameVPId, pv);
mat.SetMatrix(s_GameTVPId, pv);
}
else
{
var pos = c.transform.position;
var scale = c.transform.localScale.x;
var size = (c.transform as RectTransform).sizeDelta;
var gameVp = Matrix4x4.TRS(new Vector3(0, 0, 0.5f), Quaternion.identity, new Vector3(2 / size.x, 2 / size.y, 0.0005f * scale));
var gameTvp = Matrix4x4.TRS(new Vector3(0, 0, 0), Quaternion.identity, new Vector3(1 / pos.x, 1 / pos.y, -2 / 2000f)) * Matrix4x4.Translate(-pos);
mat.SetMatrix(s_GameVPId, gameVp);
mat.SetMatrix(s_GameTVPId, gameTvp);
}
Profiler.EndSample();
}
private void LateUpdate()
{
UpdateMaterialForSceneView(modifiedMaterial);
}
//################################
// Public Members.
//################################
/// <summary>
/// Perform material modification in this function.
/// </summary>
/// <returns>Modified material.</returns>
/// <param name="baseMaterial">Configured Material.</param>
public Material GetModifiedMaterial(Material baseMaterial)
{
_softMask = null;
if (!isActiveAndEnabled)
{
return baseMaterial;
}
/// <summary>
/// This function is called when the script is loaded or a value is changed in the inspector (Called in the editor only).
/// </summary>
private void OnValidate()
{
graphic.SetMaterialDirtyEx();
}
// Find the nearest parent softmask.
var parentTransform = transform.parent;
while (parentTransform)
{
var sm = parentTransform.GetComponent<SoftMask>();
if (sm && sm.enabled)
{
_softMask = sm;
break;
}
parentTransform = parentTransform.parent;
}
void ISerializationCallbackReceiver.OnBeforeSerialize()
{
}
Material result = baseMaterial;
if (_softMask)
{
result = new Material(baseMaterial);
result.hideFlags = HideFlags.HideAndDontSave;
result.SetTexture(s_SoftMaskTexId, _softMask.softMaskBuffer);
result.SetInt(s_StencilCompId, m_UseStencil ? (int)CompareFunction.Equal : (int)CompareFunction.Always);
result.SetVector(s_MaskInteractionId, new Vector4(
(m_MaskInteraction & 0x3),
((m_MaskInteraction >> 2) & 0x3),
((m_MaskInteraction >> 4) & 0x3),
((m_MaskInteraction >> 6) & 0x3)
));
void ISerializationCallbackReceiver.OnAfterDeserialize()
{
#pragma warning disable 0612
if (m_Inverse)
{
m_Inverse = false;
m_MaskInteraction = kVisibleOutside;
}
#pragma warning restore 0612
StencilMaterial.Remove(baseMaterial);
ReleaseMaterial(ref _maskMaterial);
_maskMaterial = result;
var current = this;
UnityEditor.EditorApplication.delayCall += () =>
{
if (!current) return;
if (!graphic) return;
if (graphic.name.Contains("TMP SubMeshUI")) return;
if (!graphic.material) return;
if (!graphic.material.shader) return;
if (graphic.material.shader.name != "Hidden/UI/Default (SoftMaskable)") return;
#if UNITY_EDITOR
result.EnableKeyword("SOFTMASK_EDITOR");
UpdateSceneViewMatrixForShader();
#endif
}
else
{
baseMaterial.SetTexture(s_SoftMaskTexId, Texture2D.whiteTexture);
}
return result;
}
/// <summary>
/// Given a point and a camera is the raycast valid.
/// </summary>
/// <returns>Valid.</returns>
/// <param name="sp">Screen position.</param>
/// <param name="eventCamera">Raycast camera.</param>
public bool IsRaycastLocationValid(Vector2 sp, Camera eventCamera)
{
if (!isActiveAndEnabled || !_softMask)
return true;
if (!RectTransformUtility.RectangleContainsScreenPoint(transform as RectTransform, sp, eventCamera))
{
return false;
}
var sm = _softMask;
for (int i = 0; i < 4; i++)
{
s_Interactions[i] = sm ? ((m_MaskInteraction >> i * 2) & 0x3) : 0;
sm = sm ? sm.parent : null;
}
return _softMask.IsRaycastLocationValid(sp, eventCamera, graphic, s_Interactions);
}
/// <summary>
/// The graphic will be visible only in areas where no mask is present.
/// </summary>
public bool inverse
{
get { return m_MaskInteraction == kVisibleOutside; }
set
{
int intValue = value ? kVisibleOutside : kVisibleInside;
if (m_MaskInteraction != intValue)
{
m_MaskInteraction = intValue;
graphic.SetMaterialDirty();
}
}
}
/// <summary>
/// The graphic associated with the soft mask.
/// </summary>
public Graphic graphic{ get { return _graphic ? _graphic : _graphic = GetComponent<Graphic>(); } }
/// <summary>
/// Set the interaction for each mask.
/// </summary>
public void SetMaskInteraction(SpriteMaskInteraction intr)
{
SetMaskInteraction(intr, intr, intr, intr);
}
/// <summary>
/// Set the interaction for each mask.
/// </summary>
public void SetMaskInteraction(SpriteMaskInteraction layer0, SpriteMaskInteraction layer1, SpriteMaskInteraction layer2, SpriteMaskInteraction layer3)
{
m_MaskInteraction = (int)layer0 + ((int)layer1 << 2) + ((int)layer2 << 4) + ((int)layer3 << 6);
if (graphic)
{
graphic.SetMaterialDirty();
}
}
//################################
// Private Members.
//################################
Graphic _graphic = null;
SoftMask _softMask = null;
Material _maskMaterial = null;
static int s_SoftMaskTexId;
static int s_StencilCompId;
static int s_MaskInteractionId;
static int s_GameVPId;
static int s_GameTVPId;
static List<SoftMaskable> s_ActiveSoftMaskables;
static int[] s_Interactions = new int[4];
static Material s_DefaultMaterial;
#if UNITY_EDITOR
/// <summary>
/// Update the scene view matrix for shader.
/// </summary>
static void UpdateSceneViewMatrixForShader()
{
UnityEditor.SceneView sceneView = UnityEditor.SceneView.lastActiveSceneView;
if (!sceneView || !sceneView.camera)
{
return;
}
Camera cam = sceneView.camera;
Matrix4x4 w2c = cam.worldToCameraMatrix;
Matrix4x4 prj = cam.projectionMatrix;
s_ActiveSoftMaskables.RemoveAll(x=>!x);
foreach (var sm in s_ActiveSoftMaskables)
{
if (!sm || !sm._maskMaterial || !sm.graphic || !sm.graphic.canvas)
{
continue;
}
Material mat = sm._maskMaterial;
var c = sm.graphic.canvas.rootCanvas;
var wcam = c.worldCamera ?? Camera.main;
if (c.renderMode != RenderMode.ScreenSpaceOverlay && wcam)
{
var pv = GL.GetGPUProjectionMatrix (wcam.projectionMatrix, false) * wcam.worldToCameraMatrix;
mat.SetMatrix(s_GameVPId, pv);
mat.SetMatrix(s_GameTVPId, pv);
}
else
{
var pos = c.transform.localPosition;
var pv = Matrix4x4.TRS(new Vector3(0, 0, 0), Quaternion.identity, new Vector3(1 / pos.x, 1 / pos.y, -2 / 2000f));
mat.SetMatrix(s_GameVPId, pv);
mat.SetMatrix(s_GameTVPId, pv * Matrix4x4.Translate(-pos));
}
}
}
/// <summary>
/// This function is called when the script is loaded or a value is changed in the inspector (Called in the editor only).
/// </summary>
void OnValidate()
{
if (graphic)
{
graphic.SetMaterialDirty();
}
}
#endif
/// <summary>
/// This function is called when the object becomes enabled and active.
/// </summary>
void OnEnable()
{
// Register.
if (s_ActiveSoftMaskables == null)
{
s_ActiveSoftMaskables = new List<SoftMaskable>();
#if UNITY_EDITOR
UnityEditor.EditorApplication.update += UpdateSceneViewMatrixForShader;
s_GameVPId = Shader.PropertyToID("_GameVP");
s_GameTVPId = Shader.PropertyToID("_GameTVP");
#endif
s_SoftMaskTexId = Shader.PropertyToID("_SoftMaskTex");
s_StencilCompId = Shader.PropertyToID("_StencilComp");
s_MaskInteractionId = Shader.PropertyToID("_MaskInteraction");
}
s_ActiveSoftMaskables.Add(this);
var g = graphic;
if (g)
{
if (!g.material || g.material == Graphic.defaultGraphicMaterial)
{
g.material = s_DefaultMaterial ?? (s_DefaultMaterial = new Material(Resources.Load<Shader>("UI-Default-SoftMask")) { hideFlags = HideFlags.HideAndDontSave, });
}
g.SetMaterialDirty();
}
_softMask = null;
}
/// <summary>
/// This function is called when the behaviour becomes disabled.
/// </summary>
void OnDisable()
{
s_ActiveSoftMaskables.Remove(this);
var g = graphic;
if (g)
{
if (g.material == s_DefaultMaterial)
{
g.material = null;
}
g.SetMaterialDirty();
}
ReleaseMaterial(ref _maskMaterial);
_softMask = null;
}
/// <summary>
/// Release the material.
/// </summary>
void ReleaseMaterial(ref Material mat)
{
if (mat)
{
StencilMaterial.Remove(mat);
#if UNITY_EDITOR
if (!Application.isPlaying)
{
DestroyImmediate(mat);
}
else
#endif
{
Destroy(mat);
}
mat = null;
}
}
void ISerializationCallbackReceiver.OnBeforeSerialize()
{
}
void ISerializationCallbackReceiver.OnAfterDeserialize()
{
#pragma warning disable 0612
if (m_Inverse)
{
m_Inverse = false;
m_MaskInteraction = (2 << 0) + (2 << 2) + (2 << 4) + (2 << 6);
}
#pragma warning restore 0612
}
}
}
graphic.material = null;
graphic.SetMaterialDirtyEx();
};
}
#endif
}
}

View File

@ -1,16 +1,16 @@
Shader "Hidden/SoftMask" {
SubShader {
Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}
LOD 100
Cull Off
ZWrite Off
Blend SrcAlpha One
ColorMask [_ColorMask]
SubShader {
Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}
LOD 100
Cull Off
ZWrite Off
Blend SrcAlpha One
ColorMask [_ColorMask]
Pass {
CGPROGRAM
Pass {
CGPROGRAM
#pragma vertex vert_img
#pragma fragment frag
#pragma target 2.0
@ -19,13 +19,15 @@ SubShader {
sampler2D _MainTex;
float _Softness;
float _Alpha;
fixed4 frag (v2f_img i) : SV_Target
{
return saturate(tex2D(_MainTex, i.uv).a/_Softness);
half softness = max(_Softness, 0.0001f);
return saturate(tex2D(_MainTex, i.uv).a/softness) * _Alpha;
}
ENDCG
ENDCG
}
}
}
}

View File

@ -1,4 +1,4 @@
Shader "UI/Default-SoftMask"
Shader "Hidden/UI/Default (SoftMaskable)"
{
Properties
{
@ -46,19 +46,18 @@ Shader "UI/Default-SoftMask"
Pass
{
Name "Default"
CGPROGRAM
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 2.0
#include "UnityCG.cginc"
#include "UnityUI.cginc"
#pragma multi_compile __ UNITY_UI_CLIP_RECT
#pragma multi_compile __ UNITY_UI_ALPHACLIP
#include "./../../SoftMask.cginc" // Add for soft mask
#pragma shader_feature __ SOFTMASK_EDITOR // Add for soft mask
#include "Packages/com.coffee.softmask-for-ugui/Shaders/SoftMask.cginc" // Add for soft mask
#pragma shader_feature __ SOFTMASK_EDITOR // Add for soft mask
struct appdata_t
{
@ -105,14 +104,14 @@ Shader "UI/Default-SoftMask"
color.a *= UnityGet2DClipping(IN.worldPosition.xy, _ClipRect);
#ifdef UNITY_UI_ALPHACLIP
clip (color.a - 0.001);
clip (color.a - 0.001);
#endif
color.a *= SoftMask(IN.vertex, IN.worldPosition); // Add for soft mask
return color;
}
ENDCG
ENDCG
}
}
}

View File

@ -7,22 +7,27 @@ float4x4 _GameVP;
float4x4 _GameTVP;
half4 _MaskInteraction;
float CustomStep(float a, float x)
{
return x >= a;
}
fixed Approximately(float4x4 a, float4x4 b)
{
float4x4 d = abs(a - b);
float4x4 d = a - b;
d = float4x4(
abs(d[0]),
abs(d[1]),
abs(d[2]),
abs(d[3])
);
return step(
max(d._m00,max(d._m01,max(d._m02,max(d._m03,
max(d._m10,max(d._m11,max(d._m12,max(d._m13,
max(d._m20,max(d._m21,max(d._m22,max(d._m23,
max(d._m30,max(d._m31,max(d._m32,d._m33))))))))))))))),
0.01);
}
float GetMaskAlpha(float alpha, int stencilId, float interaction)
{
fixed onStencil = step(stencilId, _Stencil);
alpha = lerp(1, alpha, onStencil * step(1, interaction));
return lerp(alpha, 1 - alpha, onStencil * step(2, interaction));
0.5);
}
#if SOFTMASK_EDITOR
@ -36,30 +41,27 @@ float SoftMaskInternal(float4 clipPos)
fixed isSceneView = 1 - Approximately(UNITY_MATRIX_VP, _GameVP);
float4 cpos = mul(_GameTVP, mul(UNITY_MATRIX_M, wpos));
view = lerp(view, cpos.xy / cpos.w * 0.5 + 0.5, isSceneView);
#endif
#if UNITY_UV_STARTS_AT_TOP && !defined(SHADER_API_D3D11) && !defined(SHADER_API_D3D11_9X) && !defined(SHADER_API_D3D9)
view.y = 1.0 - view.y;
#if UNITY_UV_STARTS_AT_TOP
view.y = lerp(view.y, 1 - view.y, CustomStep(0, _ProjectionParams.x));
#endif
#elif UNITY_UV_STARTS_AT_TOP
view.y = lerp(view.y, 1 - view.y, CustomStep(0, _ProjectionParams.x));
#endif
fixed4 mask = tex2D(_SoftMaskTex, view);
half alpha = GetMaskAlpha(mask.x, 1, _MaskInteraction.x)
* GetMaskAlpha(mask.y, 3, _MaskInteraction.y)
* GetMaskAlpha(mask.z, 7, _MaskInteraction.z)
* GetMaskAlpha(mask.w, 15, _MaskInteraction.w)
half4 alpha = saturate(lerp(fixed4(1, 1, 1, 1), lerp(mask, 1 - mask, _MaskInteraction - 1), _MaskInteraction));
#if SOFTMASK_EDITOR
* step(0, view.x) * step(view.x, 1) * step(0, view.y) * step(view.y, 1)
alpha *= CustomStep(0, view.x) * CustomStep(view.x, 1) * CustomStep(0, view.y) * CustomStep(view.y, 1);
#endif
;
return alpha;
return alpha.x * alpha.y * alpha.z * alpha.w;
}
#if SOFTMASK_EDITOR
#define SOFTMASK_EDITOR_ONLY(x) x
#define SoftMask(clipPos, worldPosition) SoftMaskInternal(clipPos, worldPosition)
#else
#define SOFTMASK_EDITOR_ONLY(x)
#define SOFTMASK_EDITOR_ONLY(x)
#define SoftMask(clipPos, worldPosition) SoftMaskInternal(clipPos)
#endif

Binary file not shown.

View File

@ -1,18 +1,34 @@
{
"name": "com.coffee.softmask-for-ugui",
"displayName": "Soft Mask For uGUI",
"description": "SoftMask is a smooth masking component for uGUI elements in Unity.\nBy using SoftMask instead of default Mask, rounded edges of UI elements can be expressed beautifully.",
"version": "0.7.1",
"unity": "2017.1",
"license": "MIT",
"repository": {
"type": "git",
"url": "git+https://github.com/mob-sakai/SoftMaskForUGUI.git"
},
"src": "Assets/Coffee/UIExtensions/SoftMaskForUGUI",
"author": "mob-sakai <sakai861104@gmail.com> (https://github.com/mob-sakai)",
"editorOnly": false,
"upmSupport": true,
"dependencies": {
}
"name": "com.coffee.softmask-for-ugui",
"displayName": "UI Soft Mask",
"description": "UI Soft Mask is a smooth masking component for Unity UI (uGUI) elements.\nBy using SoftMask instead of the default Mask component, you can beautifully represent the rounded edges of UI elements.",
"version": "1.0.2",
"unity": "2017.1",
"license": "MIT",
"repository": {
"type": "git",
"url": "git+https://github.com/mob-sakai/SoftMaskForUGUI.git"
},
"author": {
"name": "mob-sakai",
"email": "sakai861104@gmail.com",
"url": "https://github.com/mob-sakai"
},
"dependencies": {},
"keywords": [
"ui",
"softmask"
],
"samples": [
{
"displayName": "Demo",
"description": "UI Soft Mask Demo",
"path": "Samples~/Demo"
},
{
"displayName": "TextMeshPro Support",
"description": "TextMeshPro Support",
"path": "Samples~/TextMeshPro Support"
}
]
}