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 ([pull/87/headbf17b19
](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.
parent
b9eb1a9b95
commit
60ce6997e0
23
CHANGELOG.md
23
CHANGELOG.md
|
@ -1,3 +1,26 @@
|
|||
# [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)
|
||||
|
||||
|
||||
|
|
14
README.md
14
README.md
|
@ -155,8 +155,20 @@ Or, add a SoftMaskable components from the inspector of the SoftMask component.
|
|||
<br><br><br><br>
|
||||
## Support soft masks with your custom shaders
|
||||
|
||||
<b>With just three additional lines,</b> you can now support softmasks in your custom shaders!
|
||||
Only a few steps are needed to support soft mask in your custom shaders!
|
||||
|
||||
1. Duplicate your shader file and add the ` (SoftMaskable)` suffix to the file name.
|
||||
```
|
||||
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.
|
||||
```
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 3ad57d818b4f448a190e524e494130b0
|
||||
timeCreated: 1539763439
|
||||
licenseType: Pro
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
serializedVersion: 4
|
||||
externalObjects: {}
|
||||
serializedVersion: 9
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 1
|
||||
|
@ -12,6 +11,8 @@ TextureImporter:
|
|||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
|
@ -20,6 +21,8 @@ TextureImporter:
|
|||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
|
@ -27,10 +30,13 @@ TextureImporter:
|
|||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: -1
|
||||
aniso: 16
|
||||
mipBias: -1
|
||||
wrapMode: -1
|
||||
mipBias: -100
|
||||
wrapU: -1
|
||||
wrapV: -1
|
||||
wrapW: -1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
|
@ -39,62 +45,88 @@ TextureImporter:
|
|||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
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:
|
||||
- buildTarget: DefaultTexturePlatform
|
||||
- serializedVersion: 2
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
- buildTarget: Standalone
|
||||
androidETC2FallbackOverride: 0
|
||||
- serializedVersion: 2
|
||||
buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
- buildTarget: iPhone
|
||||
androidETC2FallbackOverride: 0
|
||||
- serializedVersion: 2
|
||||
buildTarget: iPhone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
- buildTarget: Android
|
||||
androidETC2FallbackOverride: 0
|
||||
- serializedVersion: 2
|
||||
buildTarget: Android
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
- buildTarget: WebGL
|
||||
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:
|
||||
|
|
|
@ -3,7 +3,7 @@ guid: dee1cb6c2ee294c6087ea9d89d368417
|
|||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
externalObjects: {}
|
||||
serializedVersion: 4
|
||||
serializedVersion: 9
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
|
@ -21,6 +21,8 @@ TextureImporter:
|
|||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
|
@ -31,7 +33,7 @@ TextureImporter:
|
|||
serializedVersion: 2
|
||||
filterMode: 1
|
||||
aniso: -1
|
||||
mipBias: -1
|
||||
mipBias: -100
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: -1
|
||||
|
@ -51,11 +53,13 @@ TextureImporter:
|
|||
spriteTessellationDetail: -1
|
||||
textureType: 8
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- buildTarget: DefaultTexturePlatform
|
||||
- serializedVersion: 2
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
|
@ -65,7 +69,8 @@ TextureImporter:
|
|||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: Standalone
|
||||
- serializedVersion: 2
|
||||
buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
|
@ -75,7 +80,8 @@ TextureImporter:
|
|||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: iPhone
|
||||
- serializedVersion: 2
|
||||
buildTarget: iPhone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
|
@ -85,7 +91,8 @@ TextureImporter:
|
|||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: Android
|
||||
- serializedVersion: 2
|
||||
buildTarget: Android
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
|
@ -95,7 +102,8 @@ TextureImporter:
|
|||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: WebGL
|
||||
- serializedVersion: 2
|
||||
buildTarget: WebGL
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
|
@ -110,7 +118,15 @@ TextureImporter:
|
|||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID: 2775f4bfe28684615aa97cccf30fd220
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
spritePackingTag:
|
||||
pSDRemoveMatte: 0
|
||||
pSDShowRemoveMatteOption: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
fileFormatVersion: 2
|
||||
guid: f3749669408984358921fc148ed3aa83
|
||||
timeCreated: 1542628474
|
||||
licenseType: Pro
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
serializedVersion: 4
|
||||
externalObjects: {}
|
||||
serializedVersion: 9
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
|
@ -22,6 +21,8 @@ TextureImporter:
|
|||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
|
@ -32,7 +33,7 @@ TextureImporter:
|
|||
serializedVersion: 2
|
||||
filterMode: -1
|
||||
aniso: -1
|
||||
mipBias: -1
|
||||
mipBias: -100
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: -1
|
||||
|
@ -44,63 +45,88 @@ TextureImporter:
|
|||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spriteBorder: {x: 31, y: 0, z: 31, w: 0}
|
||||
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:
|
||||
- buildTarget: DefaultTexturePlatform
|
||||
- serializedVersion: 2
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
- buildTarget: Standalone
|
||||
androidETC2FallbackOverride: 0
|
||||
- serializedVersion: 2
|
||||
buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
- buildTarget: iPhone
|
||||
androidETC2FallbackOverride: 0
|
||||
- serializedVersion: 2
|
||||
buildTarget: iPhone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
- buildTarget: Android
|
||||
androidETC2FallbackOverride: 0
|
||||
- serializedVersion: 2
|
||||
buildTarget: Android
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
- buildTarget: WebGL
|
||||
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:
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 801e306fcae92475592a6d3511bf58d7
|
||||
timeCreated: 1540708816
|
||||
licenseType: Pro
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
serializedVersion: 4
|
||||
externalObjects: {}
|
||||
serializedVersion: 9
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
|
@ -22,6 +21,8 @@ TextureImporter:
|
|||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
|
@ -32,7 +33,7 @@ TextureImporter:
|
|||
serializedVersion: 2
|
||||
filterMode: 1
|
||||
aniso: -1
|
||||
mipBias: -1
|
||||
mipBias: -100
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: -1
|
||||
|
@ -44,63 +45,88 @@ TextureImporter:
|
|||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
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:
|
||||
- buildTarget: DefaultTexturePlatform
|
||||
- serializedVersion: 2
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
- buildTarget: Standalone
|
||||
androidETC2FallbackOverride: 0
|
||||
- serializedVersion: 2
|
||||
buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
- buildTarget: iPhone
|
||||
androidETC2FallbackOverride: 0
|
||||
- serializedVersion: 2
|
||||
buildTarget: iPhone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
- buildTarget: Android
|
||||
androidETC2FallbackOverride: 0
|
||||
- serializedVersion: 2
|
||||
buildTarget: Android
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
- buildTarget: WebGL
|
||||
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:
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 0f125745ff7d640519fb2300ed8a96c7
|
||||
timeCreated: 1542628487
|
||||
licenseType: Pro
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
serializedVersion: 4
|
||||
externalObjects: {}
|
||||
serializedVersion: 9
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
|
@ -22,6 +21,8 @@ TextureImporter:
|
|||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
|
@ -32,7 +33,7 @@ TextureImporter:
|
|||
serializedVersion: 2
|
||||
filterMode: -1
|
||||
aniso: -1
|
||||
mipBias: -1
|
||||
mipBias: -100
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: -1
|
||||
|
@ -44,63 +45,88 @@ TextureImporter:
|
|||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spriteBorder: {x: 0, y: 31, z: 0, w: 31}
|
||||
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:
|
||||
- buildTarget: DefaultTexturePlatform
|
||||
- serializedVersion: 2
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
- buildTarget: Standalone
|
||||
androidETC2FallbackOverride: 0
|
||||
- serializedVersion: 2
|
||||
buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
- buildTarget: iPhone
|
||||
androidETC2FallbackOverride: 0
|
||||
- serializedVersion: 2
|
||||
buildTarget: iPhone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
- buildTarget: Android
|
||||
androidETC2FallbackOverride: 0
|
||||
- serializedVersion: 2
|
||||
buildTarget: Android
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
- buildTarget: WebGL
|
||||
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:
|
||||
|
|
|
@ -3,18 +3,21 @@ using System.Collections.Generic;
|
|||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Coffee.UIExtensions.Demos
|
||||
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,
|
||||
|
@ -25,38 +28,31 @@ namespace Coffee.UIExtensions.Demos
|
|||
{
|
||||
softMaskBufferViewer[i].texture = softMask[i].softMaskBuffer;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void Update()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void SetWorldSpase(bool flag)
|
||||
{
|
||||
if(flag)
|
||||
if (flag)
|
||||
{
|
||||
GetComponent<Canvas> ().renderMode = RenderMode.ScreenSpaceCamera;
|
||||
GetComponent<Canvas> ().renderMode = RenderMode.WorldSpace;
|
||||
transform.rotation = Quaternion.Euler (new Vector3 (0, 6, 0));
|
||||
GetComponent<Canvas>().renderMode = RenderMode.ScreenSpaceCamera;
|
||||
GetComponent<Canvas>().renderMode = RenderMode.WorldSpace;
|
||||
transform.rotation = Quaternion.Euler(new Vector3(0, 6, 0));
|
||||
}
|
||||
}
|
||||
|
||||
public void SetScreenSpase (bool flag)
|
||||
public void SetScreenSpase(bool flag)
|
||||
{
|
||||
if (flag)
|
||||
{
|
||||
GetComponent<Canvas> ().renderMode = RenderMode.ScreenSpaceCamera;
|
||||
GetComponent<Canvas>().renderMode = RenderMode.ScreenSpaceCamera;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetOverlay (bool flag)
|
||||
public void SetOverlay(bool flag)
|
||||
{
|
||||
if (flag)
|
||||
{
|
||||
GetComponent<Canvas> ().renderMode = RenderMode.ScreenSpaceOverlay;
|
||||
GetComponent<Canvas>().renderMode = RenderMode.ScreenSpaceOverlay;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,10 +1,9 @@
|
|||
fileFormatVersion: 2
|
||||
guid: e5a8e8d861f62472d8f99611cf9d12c5
|
||||
timeCreated: 1539763439
|
||||
licenseType: Pro
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
serializedVersion: 4
|
||||
externalObjects: {}
|
||||
serializedVersion: 9
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 1
|
||||
|
@ -12,6 +11,8 @@ TextureImporter:
|
|||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
|
@ -20,6 +21,8 @@ TextureImporter:
|
|||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
|
@ -27,10 +30,13 @@ TextureImporter:
|
|||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: -1
|
||||
aniso: 16
|
||||
mipBias: -1
|
||||
wrapMode: -1
|
||||
mipBias: -100
|
||||
wrapU: -1
|
||||
wrapV: -1
|
||||
wrapW: -1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
|
@ -39,62 +45,88 @@ TextureImporter:
|
|||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
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:
|
||||
- buildTarget: DefaultTexturePlatform
|
||||
- serializedVersion: 2
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
- buildTarget: Standalone
|
||||
androidETC2FallbackOverride: 0
|
||||
- serializedVersion: 2
|
||||
buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
- buildTarget: iPhone
|
||||
androidETC2FallbackOverride: 0
|
||||
- serializedVersion: 2
|
||||
buildTarget: iPhone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
- buildTarget: Android
|
||||
androidETC2FallbackOverride: 0
|
||||
- serializedVersion: 2
|
||||
buildTarget: Android
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
- buildTarget: WebGL
|
||||
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:
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
#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();
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,9 +4,9 @@ using System.Linq;
|
|||
using System.Text.RegularExpressions;
|
||||
using UnityEditor;
|
||||
|
||||
namespace Coffee.UIExtensions
|
||||
namespace Coffee.UISoftMask
|
||||
{
|
||||
public static class ImportSampleMenu_UISoftMask
|
||||
public static class ImportSampleMenu
|
||||
{
|
||||
[MenuItem("Assets/Samples/Import UISoftMask Sample")]
|
||||
private static void ImportSample()
|
||||
|
|
|
@ -5,7 +5,7 @@ using UnityEditor;
|
|||
using System.Linq;
|
||||
|
||||
|
||||
namespace Coffee.UIExtensions.Editors
|
||||
namespace Coffee.UISoftMask
|
||||
{
|
||||
/// <summary>
|
||||
/// SoftMask editor.
|
||||
|
@ -15,58 +15,67 @@ namespace Coffee.UIExtensions.Editors
|
|||
public class SoftMaskEditor : Editor
|
||||
{
|
||||
const string k_PrefsPreview = "SoftMaskEditor_Preview";
|
||||
static readonly List<Graphic> s_Graphics = new List<Graphic> ();
|
||||
static readonly List<Graphic> s_Graphics = new List<Graphic>();
|
||||
static bool s_Preview;
|
||||
|
||||
private void OnEnable ()
|
||||
private void OnEnable()
|
||||
{
|
||||
s_Preview = EditorPrefs.GetBool (k_PrefsPreview, false);
|
||||
s_Preview = EditorPrefs.GetBool(k_PrefsPreview, false);
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI ()
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
base.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 ();
|
||||
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 Graphics that does not have a SoftMaskable component.\nAdd SoftMaskable component to them.", MessageType.Warning);
|
||||
GUILayout.BeginVertical ();
|
||||
if (GUILayout.Button ("Fix"))
|
||||
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> ();
|
||||
p.gameObject.AddComponent<SoftMaskable>();
|
||||
}
|
||||
|
||||
Utils.MarkPrefabDirty ();
|
||||
EditorUtils.MarkPrefabDirty();
|
||||
}
|
||||
if (GUILayout.Button ("Ping"))
|
||||
|
||||
if (GUILayout.Button("Ping"))
|
||||
{
|
||||
EditorGUIUtility.PingObject (fixTargets[0]);
|
||||
EditorGUIUtility.PingObject(fixTargets[0]);
|
||||
}
|
||||
GUILayout.EndVertical ();
|
||||
GUILayout.EndHorizontal ();
|
||||
|
||||
GUILayout.EndVertical();
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
// Preview buffer.
|
||||
GUILayout.BeginHorizontal (EditorStyles.helpBox);
|
||||
if (s_Preview != (s_Preview = EditorGUILayout.ToggleLeft ("Preview Buffer", s_Preview, GUILayout.MaxWidth (EditorGUIUtility.labelWidth))))
|
||||
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);
|
||||
EditorPrefs.SetBool(k_PrefsPreview, s_Preview);
|
||||
}
|
||||
|
||||
if (s_Preview)
|
||||
{
|
||||
var tex = current.softMaskBuffer;
|
||||
var width = tex.width * 64 / tex.height;
|
||||
EditorGUI.DrawPreviewTexture (GUILayoutUtility.GetRect (width, 64), tex, null, ScaleMode.ScaleToFit);
|
||||
Repaint ();
|
||||
EditorGUI.DrawPreviewTexture(GUILayoutUtility.GetRect(width, 64), tex, null, ScaleMode.ScaleToFit);
|
||||
Repaint();
|
||||
}
|
||||
GUILayout.FlexibleSpace ();
|
||||
GUILayout.EndHorizontal ();
|
||||
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
|
||||
|
@ -74,61 +83,25 @@ namespace Coffee.UIExtensions.Editors
|
|||
[MenuItem("CONTEXT/Mask/Convert To SoftMask", true)]
|
||||
static bool _ConvertToSoftMask(MenuCommand command)
|
||||
{
|
||||
return CanConvertTo<SoftMask>(command.context);
|
||||
return EditorUtils.CanConvertTo<SoftMask>(command.context);
|
||||
}
|
||||
|
||||
[MenuItem("CONTEXT/Mask/Convert To SoftMask", false)]
|
||||
static void ConvertToSoftMask(MenuCommand command)
|
||||
{
|
||||
ConvertTo<SoftMask>(command.context);
|
||||
EditorUtils.ConvertTo<SoftMask>(command.context);
|
||||
}
|
||||
|
||||
[MenuItem("CONTEXT/Mask/Convert To Mask", true)]
|
||||
static bool _ConvertToMask(MenuCommand command)
|
||||
{
|
||||
return CanConvertTo<Mask>(command.context);
|
||||
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;
|
||||
EditorUtils.ConvertTo<Mask>(command.context);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -9,18 +9,15 @@ 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))]
|
||||
[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),
|
||||
|
@ -36,7 +33,7 @@ namespace Coffee.UIExtensions.Editors
|
|||
return _custom
|
||||
? MaskInteraction.Custom
|
||||
: System.Enum.IsDefined(typeof(MaskInteraction), value)
|
||||
? (MaskInteraction)value
|
||||
? (MaskInteraction) value
|
||||
: MaskInteraction.Custom;
|
||||
}
|
||||
set
|
||||
|
@ -44,77 +41,40 @@ namespace Coffee.UIExtensions.Editors
|
|||
_custom = (value == MaskInteraction.Custom);
|
||||
if (!_custom)
|
||||
{
|
||||
_spMaskInteraction.intValue = (int)value;
|
||||
_spMaskInteraction.intValue = (int) value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool _custom = false;
|
||||
|
||||
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> ();
|
||||
static readonly List<Graphic> s_Graphics = new List<Graphic>();
|
||||
SerializedProperty _spMaskInteraction;
|
||||
List<Mask> tmpMasks = new List<Mask>();
|
||||
static GUIContent s_MaskWarning;
|
||||
|
||||
void OnEnable ()
|
||||
|
||||
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 is not a SoftMask component.");
|
||||
}
|
||||
|
||||
s_MaskWarning = new GUIContent(EditorGUIUtility.FindTexture("console.warnicon.sml"), "This component is not SoftMask. Use SoftMask instead of Mask.");
|
||||
}
|
||||
|
||||
void OnDisable ()
|
||||
private void DrawMaskInteractions()
|
||||
{
|
||||
ClearMaterialEditors ();
|
||||
}
|
||||
var softMaskable = target as SoftMaskable;
|
||||
if (softMaskable == null) return;
|
||||
|
||||
List<Mask> tmpMasks = new List<Mask>();
|
||||
|
||||
void DrawMaskInteractions()
|
||||
{
|
||||
(target as SoftMaskable).GetComponentsInParent<Mask>(true, tmpMasks);
|
||||
softMaskable.GetComponentsInParent<Mask>(true, tmpMasks);
|
||||
tmpMasks.RemoveAll(x => !x.enabled);
|
||||
tmpMasks.Reverse();
|
||||
|
||||
maskInteraction = (MaskInteraction)EditorGUILayout.EnumPopup("Mask Interaction", maskInteraction);
|
||||
if (_custom)
|
||||
{
|
||||
maskInteraction = (MaskInteraction) EditorGUILayout.EnumPopup("Mask Interaction", maskInteraction);
|
||||
if (!_custom) return;
|
||||
|
||||
var l = EditorGUIUtility.labelWidth;
|
||||
EditorGUIUtility.labelWidth = 45;
|
||||
|
||||
|
@ -125,24 +85,23 @@ namespace Coffee.UIExtensions.Editors
|
|||
int intr2 = DrawMaskInteraction(2);
|
||||
int intr3 = DrawMaskInteraction(3);
|
||||
|
||||
if (ccs.changed) {
|
||||
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)
|
||||
private int DrawMaskInteraction(int layer)
|
||||
{
|
||||
Mask mask = layer < tmpMasks.Count ? tmpMasks[layer] : null;
|
||||
MaskIntr intr = (MaskIntr)((_spMaskInteraction.intValue >> layer * 2) & 0x3);
|
||||
MaskIntr intr = (MaskIntr) ((_spMaskInteraction.intValue >> layer * 2) & 0x3);
|
||||
if (!mask)
|
||||
{
|
||||
return (int)intr;
|
||||
return (int) intr;
|
||||
}
|
||||
|
||||
using (new EditorGUILayout.HorizontalScope())
|
||||
|
@ -151,263 +110,75 @@ namespace Coffee.UIExtensions.Editors
|
|||
GUILayout.Space(-5);
|
||||
EditorGUILayout.ObjectField("Mask " + layer, mask, typeof(Mask), false);
|
||||
GUILayout.Space(-15);
|
||||
return (int)(MaskIntr)EditorGUILayout.EnumPopup(intr);
|
||||
return (int) (MaskIntr) EditorGUILayout.EnumPopup(intr);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI ()
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
base.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 ();
|
||||
|
||||
|
||||
|
||||
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 ();
|
||||
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 Graphics that does not have a SoftMaskable component.\nAdd SoftMaskable component to them.", MessageType.Warning);
|
||||
GUILayout.BeginVertical ();
|
||||
if (GUILayout.Button ("Fix"))
|
||||
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> ();
|
||||
}
|
||||
}
|
||||
if (GUILayout.Button ("Ping"))
|
||||
{
|
||||
EditorGUIUtility.PingObject (fixTargets [0]);
|
||||
}
|
||||
GUILayout.EndVertical ();
|
||||
GUILayout.EndHorizontal ();
|
||||
}
|
||||
|
||||
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);
|
||||
p.gameObject.AddComponent<SoftMaskable>();
|
||||
}
|
||||
}
|
||||
|
||||
if (!DetectMask (current.transform.parent))
|
||||
if (GUILayout.Button("Ping"))
|
||||
{
|
||||
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);
|
||||
|
||||
Utils.MarkPrefabDirty ();
|
||||
EditorGUIUtility.PingObject(fixTargets[0]);
|
||||
}
|
||||
GUILayout.EndHorizontal ();
|
||||
|
||||
GUILayout.EndVertical();
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
if (!DetectMask(current.transform.parent))
|
||||
{
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
static bool DetectMask (Transform transform)
|
||||
static bool DetectMask(Transform transform)
|
||||
{
|
||||
if (transform == null)
|
||||
while (transform)
|
||||
{
|
||||
if (transform.GetComponent<SoftMask>()) return true;
|
||||
|
||||
transform = transform.parent;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (transform.GetComponent<SoftMask> () != null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return DetectMask (transform.parent);
|
||||
}
|
||||
|
||||
void ClearMaterialEditors ()
|
||||
{
|
||||
foreach (var e in _materialEditors)
|
||||
{
|
||||
if (e)
|
||||
{
|
||||
DestroyImmediate (e);
|
||||
}
|
||||
}
|
||||
_materialEditors.Clear ();
|
||||
}
|
||||
|
||||
protected void ShowMaterialEditors (Material [] materials, int startIndex, int count)
|
||||
{
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
if (_materialEditors.Count == i)
|
||||
{
|
||||
_materialEditors.Add (null);
|
||||
}
|
||||
|
||||
var mat = materials [startIndex + i];
|
||||
var editor = _materialEditors [i];
|
||||
if (editor && editor.target != mat)
|
||||
{
|
||||
DestroyImmediate (editor);
|
||||
editor = null;
|
||||
}
|
||||
|
||||
if (!editor)
|
||||
{
|
||||
editor = _materialEditors [i] = Editor.CreateEditor (mat) as MaterialEditor;
|
||||
}
|
||||
|
||||
editor.DrawHeader ();
|
||||
editor.OnInspectorGUI ();
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
Material fontSharedMaterial = s_PiFontSharedMaterial.GetValue (textMeshPro, new object [0]) as Material;
|
||||
if (fontSharedMaterial == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
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");
|
||||
|
||||
EditorUtility.FocusProjectWindow ();
|
||||
EditorGUIUtility.PingObject (mat);
|
||||
}
|
||||
else
|
||||
{
|
||||
mat.shader = shader;
|
||||
}
|
||||
EditorUtility.SetDirty (mat);
|
||||
return mat;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
EditorUtility.FocusProjectWindow ();
|
||||
EditorGUIUtility.PingObject (spriteAsset);
|
||||
}
|
||||
else
|
||||
{
|
||||
Material m = s_FiMaterial.GetValue (spriteAsset) as Material;
|
||||
m.shader = shader;
|
||||
}
|
||||
EditorUtility.SetDirty (spriteAsset);
|
||||
return spriteAsset;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
#if UNITY_2018_3_OR_NEWER
|
||||
using UnityEditor.Experimental.SceneManagement;
|
||||
#endif
|
||||
using UnityEditor.SceneManagement;
|
||||
|
||||
|
||||
namespace Coffee.UIExtensions.Editors
|
||||
{
|
||||
public static class Utils
|
||||
{
|
||||
public static void MarkPrefabDirty ()
|
||||
{
|
||||
#if UNITY_2018_3_OR_NEWER
|
||||
var prefabStage = PrefabStageUtility.GetCurrentPrefabStage ();
|
||||
if (prefabStage != null)
|
||||
{
|
||||
EditorSceneManager.MarkSceneDirty (prefabStage.scene);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,107 @@
|
|||
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 Shader FindEffectShader(this Graphic graphic)
|
||||
{
|
||||
return GraphicConnector.FindConnector(graphic).FindEffectShader(graphic);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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>
|
||||
/// Find effect shader.
|
||||
/// </summary>
|
||||
public virtual Shader FindEffectShader(Graphic graphic)
|
||||
{
|
||||
return Shader.Find("Hidden/UI/SoftMaskable");
|
||||
}
|
||||
|
||||
/// <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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 0e702140c28f4425fac896f9394a31b1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,80 @@
|
|||
using System.Collections.Generic;
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Coffee.UISoftMask
|
||||
{
|
||||
internal class MaterialCache
|
||||
{
|
||||
public delegate void ModifyAction(Material material, Graphic graphic);
|
||||
|
||||
static Dictionary<Hash128, MaterialEntry> materialMap = new Dictionary<Hash128, MaterialEntry>();
|
||||
|
||||
private class MaterialEntry
|
||||
{
|
||||
public Material material;
|
||||
public int referenceCount;
|
||||
|
||||
public void Release()
|
||||
{
|
||||
if (material)
|
||||
{
|
||||
UnityEngine.Object.DestroyImmediate(material, false);
|
||||
}
|
||||
|
||||
material = null;
|
||||
}
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
[UnityEditor.InitializeOnLoadMethod]
|
||||
private static void ClearCache()
|
||||
{
|
||||
foreach (var entry in materialMap.Values)
|
||||
{
|
||||
entry.Release();
|
||||
}
|
||||
|
||||
materialMap.Clear();
|
||||
}
|
||||
#endif
|
||||
|
||||
public static Material Register(Material material, Hash128 hash, Action<Material> onModify)
|
||||
{
|
||||
if (!hash.isValid) return null;
|
||||
|
||||
MaterialEntry entry;
|
||||
if (!materialMap.TryGetValue(hash, out entry))
|
||||
{
|
||||
entry = new MaterialEntry()
|
||||
{
|
||||
material = new Material(material)
|
||||
{
|
||||
hideFlags = HideFlags.HideAndDontSave,
|
||||
},
|
||||
};
|
||||
|
||||
onModify(entry.material);
|
||||
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 || !materialMap.TryGetValue(hash, out entry)) return;
|
||||
//Debug.LogFormat("Unregister: {0}, {1}", hash, entry.referenceCount -1);
|
||||
|
||||
if (--entry.referenceCount > 0) return;
|
||||
|
||||
entry.Release();
|
||||
materialMap.Remove(hash);
|
||||
//Debug.LogFormat("Unregister: Release Emtry: {0}, {1} (Total: {2})", hash, entry.referenceCount, materialMap.Count);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: be6c8de8d4ec241fdbfad99aca2497d8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -1,12 +1,11 @@
|
|||
using System.Collections;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
using UnityEngine.UI;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace Coffee.UIExtensions
|
||||
namespace Coffee.UISoftMask
|
||||
{
|
||||
/// <summary>
|
||||
/// Soft mask.
|
||||
|
@ -14,9 +13,6 @@ namespace Coffee.UIExtensions
|
|||
/// </summary>
|
||||
public class SoftMask : Mask, IMeshModifier
|
||||
{
|
||||
//################################
|
||||
// Constant or Static Members.
|
||||
//################################
|
||||
/// <summary>
|
||||
/// Desampling rate.
|
||||
/// </summary>
|
||||
|
@ -47,25 +43,50 @@ namespace Coffee.UIExtensions
|
|||
|
||||
static bool s_UVStartsAtTop;
|
||||
|
||||
|
||||
//################################
|
||||
// Serialize Members.
|
||||
//################################
|
||||
[Tooltip("The desampling rate for soft mask buffer.")]
|
||||
[SerializeField] DesamplingRate m_DesamplingRate = DesamplingRate.None;
|
||||
[Tooltip("The value used by the soft mask to select the area of influence defined over the soft mask's graphic.")]
|
||||
[SerializeField][Range(0.01f, 1)] float m_Softness = 1;
|
||||
[Tooltip("The transparency of the whole masked graphic.")]
|
||||
[SerializeField][Range(0f, 1f)] float m_Alpha = 1;
|
||||
[Tooltip("Should the soft mask ignore parent soft masks?")]
|
||||
[SerializeField] bool m_IgnoreParent = false;
|
||||
[Tooltip("Is the soft mask a part of parent soft mask?")]
|
||||
[SerializeField] bool m_PartOfParent = false;
|
||||
static Shader s_SoftMaskShader;
|
||||
static Texture2D s_ReadTexture;
|
||||
static readonly List<SoftMask> s_ActiveSoftMasks = new List<SoftMask>();
|
||||
static readonly List<SoftMask> s_TempRelatables = new List<SoftMask>();
|
||||
static readonly Dictionary<int, Matrix4x4> s_previousViewProjectionMatrices = new Dictionary<int, Matrix4x4>();
|
||||
static readonly Dictionary<int, Matrix4x4> s_nowViewProjectionMatrices = new Dictionary<int, Matrix4x4>();
|
||||
static int s_StencilCompId;
|
||||
static int s_ColorMaskId;
|
||||
static int s_MainTexId;
|
||||
static int s_SoftnessId;
|
||||
static int s_GameVPId;
|
||||
static int s_GameTVPId;
|
||||
static int s_Alpha;
|
||||
MaterialPropertyBlock _mpb;
|
||||
CommandBuffer _cb;
|
||||
Material _material;
|
||||
RenderTexture _softMaskBuffer;
|
||||
int _stencilDepth;
|
||||
Mesh _mesh;
|
||||
SoftMask _parent;
|
||||
readonly List<SoftMask> _children = new List<SoftMask>();
|
||||
bool _hasChanged = false;
|
||||
bool _hasStencilStateChanged = false;
|
||||
|
||||
|
||||
[Tooltip("The desampling rate for soft mask buffer.")] [SerializeField]
|
||||
DesamplingRate m_DesamplingRate = DesamplingRate.None;
|
||||
|
||||
[Tooltip(
|
||||
"The value used by the soft mask to select the area of influence defined over the soft mask's graphic.")]
|
||||
[SerializeField]
|
||||
[Range(0.01f, 1)]
|
||||
float m_Softness = 1;
|
||||
|
||||
[Tooltip("The transparency of the whole masked graphic.")] [SerializeField] [Range(0f, 1f)]
|
||||
float m_Alpha = 1;
|
||||
|
||||
[Tooltip("Should the soft mask ignore parent soft masks?")] [SerializeField]
|
||||
bool m_IgnoreParent = false;
|
||||
|
||||
[Tooltip("Is the soft mask a part of parent soft mask?")] [SerializeField]
|
||||
bool m_PartOfParent = false;
|
||||
|
||||
|
||||
//################################
|
||||
// Public Members.
|
||||
//################################
|
||||
/// <summary>
|
||||
/// The desampling rate for soft mask buffer.
|
||||
/// </summary>
|
||||
|
@ -74,13 +95,11 @@ namespace Coffee.UIExtensions
|
|||
get { return m_DesamplingRate; }
|
||||
set
|
||||
{
|
||||
if (m_DesamplingRate != value)
|
||||
{
|
||||
if (m_DesamplingRate == value) return;
|
||||
m_DesamplingRate = value;
|
||||
hasChanged = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The value used by the soft mask to select the area of influence defined over the soft mask's graphic.
|
||||
|
@ -91,13 +110,11 @@ namespace Coffee.UIExtensions
|
|||
set
|
||||
{
|
||||
value = Mathf.Clamp01(value);
|
||||
if (m_Softness != value)
|
||||
{
|
||||
if (Mathf.Approximately(m_Softness, value)) return;
|
||||
m_Softness = value;
|
||||
hasChanged = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The transparency of the whole masked graphic.
|
||||
|
@ -108,13 +125,11 @@ namespace Coffee.UIExtensions
|
|||
set
|
||||
{
|
||||
value = Mathf.Clamp01(value);
|
||||
if (m_Alpha != value)
|
||||
{
|
||||
if (Mathf.Approximately(m_Alpha, value)) return;
|
||||
m_Alpha = value;
|
||||
hasChanged = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Should the soft mask ignore parent soft masks?
|
||||
|
@ -125,14 +140,12 @@ namespace Coffee.UIExtensions
|
|||
get { return m_IgnoreParent; }
|
||||
set
|
||||
{
|
||||
if (m_IgnoreParent != value)
|
||||
{
|
||||
if (m_IgnoreParent == value) return;
|
||||
m_IgnoreParent = value;
|
||||
hasChanged = true;
|
||||
OnTransformParentChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is the soft mask a part of parent soft mask?
|
||||
|
@ -142,14 +155,12 @@ namespace Coffee.UIExtensions
|
|||
get { return m_PartOfParent; }
|
||||
set
|
||||
{
|
||||
if (m_PartOfParent != value)
|
||||
{
|
||||
if (m_PartOfParent == value) return;
|
||||
m_PartOfParent = value;
|
||||
hasChanged = true;
|
||||
OnTransformParentChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The soft mask buffer.
|
||||
|
@ -160,7 +171,7 @@ namespace Coffee.UIExtensions
|
|||
{
|
||||
if (_parent)
|
||||
{
|
||||
ReleaseRT(ref _softMaskBuffer);
|
||||
ReleaseRt(ref _softMaskBuffer);
|
||||
return _parent.softMaskBuffer;
|
||||
}
|
||||
|
||||
|
@ -169,12 +180,13 @@ namespace Coffee.UIExtensions
|
|||
GetDesamplingSize(m_DesamplingRate, out w, out h);
|
||||
if (_softMaskBuffer && (_softMaskBuffer.width != w || _softMaskBuffer.height != h))
|
||||
{
|
||||
ReleaseRT(ref _softMaskBuffer);
|
||||
ReleaseRt(ref _softMaskBuffer);
|
||||
}
|
||||
|
||||
if (!_softMaskBuffer)
|
||||
{
|
||||
_softMaskBuffer = RenderTexture.GetTemporary(w, h, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Default);
|
||||
_softMaskBuffer = RenderTexture.GetTemporary(w, h, 0, RenderTextureFormat.ARGB32,
|
||||
RenderTextureReadWrite.Default);
|
||||
hasChanged = true;
|
||||
_hasStencilStateChanged = true;
|
||||
}
|
||||
|
@ -185,28 +197,42 @@ namespace Coffee.UIExtensions
|
|||
|
||||
public bool hasChanged
|
||||
{
|
||||
get
|
||||
{
|
||||
return _parent ? _parent.hasChanged : _hasChanged;
|
||||
}
|
||||
get { return _parent ? _parent.hasChanged : _hasChanged; }
|
||||
private set
|
||||
{
|
||||
if (_parent)
|
||||
{
|
||||
_parent.hasChanged = value;
|
||||
}
|
||||
|
||||
_hasChanged = value;
|
||||
}
|
||||
}
|
||||
|
||||
public SoftMask parent
|
||||
{
|
||||
get { return _parent; }
|
||||
}
|
||||
|
||||
Material material
|
||||
{
|
||||
get
|
||||
{
|
||||
return _parent;
|
||||
return _material
|
||||
? _material
|
||||
: _material =
|
||||
new Material(s_SoftMaskShader
|
||||
? s_SoftMaskShader
|
||||
: s_SoftMaskShader = Resources.Load<Shader>("SoftMask"))
|
||||
{hideFlags = HideFlags.HideAndDontSave};
|
||||
}
|
||||
}
|
||||
|
||||
Mesh mesh
|
||||
{
|
||||
get { return _mesh ? _mesh : _mesh = new Mesh() {hideFlags = HideFlags.HideAndDontSave}; }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Perform material modification in this function.
|
||||
|
@ -219,8 +245,9 @@ namespace Coffee.UIExtensions
|
|||
var result = base.GetModifiedMaterial(baseMaterial);
|
||||
if (m_IgnoreParent && result != baseMaterial)
|
||||
{
|
||||
result.SetInt(s_StencilCompId, (int)CompareFunction.Always);
|
||||
result.SetInt(s_StencilCompId, (int) CompareFunction.Always);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -240,9 +267,7 @@ namespace Coffee.UIExtensions
|
|||
void IMeshModifier.ModifyMesh(VertexHelper verts)
|
||||
{
|
||||
if (isActiveAndEnabled)
|
||||
{
|
||||
verts.FillMesh(mesh);
|
||||
}
|
||||
hasChanged = true;
|
||||
}
|
||||
|
||||
|
@ -255,15 +280,12 @@ namespace Coffee.UIExtensions
|
|||
/// <param name="g">Target graphic.</param>
|
||||
public bool IsRaycastLocationValid(Vector2 sp, Camera eventCamera, Graphic g, int[] interactions)
|
||||
{
|
||||
if (!isActiveAndEnabled || (g == graphic && !g.raycastTarget))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (!isActiveAndEnabled || (g == graphic && !g.raycastTarget)) return true;
|
||||
|
||||
int x = (int)((softMaskBuffer.width - 1) * Mathf.Clamp01(sp.x / Screen.width));
|
||||
int x = (int) ((softMaskBuffer.width - 1) * Mathf.Clamp01(sp.x / Screen.width));
|
||||
int y = s_UVStartsAtTop
|
||||
? (int)((softMaskBuffer.height - 1) * (1 - Mathf.Clamp01(sp.y / Screen.height)))
|
||||
: (int)((softMaskBuffer.height - 1) * Mathf.Clamp01(sp.y / Screen.height));
|
||||
? (int) ((softMaskBuffer.height - 1) * (1 - Mathf.Clamp01(sp.y / Screen.height)))
|
||||
: (int) ((softMaskBuffer.height - 1) * Mathf.Clamp01(sp.y / Screen.height));
|
||||
return 0.5f < GetPixelValue(x, y, interactions);
|
||||
}
|
||||
|
||||
|
@ -272,10 +294,6 @@ namespace Coffee.UIExtensions
|
|||
return true;
|
||||
}
|
||||
|
||||
//################################
|
||||
// Protected Members.
|
||||
//################################
|
||||
|
||||
/// <summary>
|
||||
/// This function is called when the object becomes enabled and active.
|
||||
/// </summary>
|
||||
|
@ -302,6 +320,7 @@ namespace Coffee.UIExtensions
|
|||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
s_ActiveSoftMasks.Add(this);
|
||||
|
||||
// Reset the parent-child relation.
|
||||
|
@ -310,6 +329,7 @@ namespace Coffee.UIExtensions
|
|||
{
|
||||
s_TempRelatables[i].OnTransformParentChanged();
|
||||
}
|
||||
|
||||
s_TempRelatables.Clear();
|
||||
|
||||
// Create objects.
|
||||
|
@ -339,6 +359,7 @@ namespace Coffee.UIExtensions
|
|||
{
|
||||
_children[i].SetParent(_parent);
|
||||
}
|
||||
|
||||
_children.Clear();
|
||||
SetParent(null);
|
||||
|
||||
|
@ -352,7 +373,7 @@ namespace Coffee.UIExtensions
|
|||
_mesh = null;
|
||||
ReleaseObject(_material);
|
||||
_material = null;
|
||||
ReleaseRT(ref _softMaskBuffer);
|
||||
ReleaseRt(ref _softMaskBuffer);
|
||||
|
||||
base.OnDisable();
|
||||
_hasStencilStateChanged = false;
|
||||
|
@ -374,6 +395,7 @@ namespace Coffee.UIExtensions
|
|||
parentTransform = parentTransform.parent;
|
||||
}
|
||||
}
|
||||
|
||||
SetParent(newParent);
|
||||
hasChanged = true;
|
||||
}
|
||||
|
@ -384,10 +406,6 @@ namespace Coffee.UIExtensions
|
|||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
/// <summary>
|
||||
/// Update the scene view matrix for shader.
|
||||
/// </summary>
|
||||
|
||||
/// <summary>
|
||||
/// This function is called when the script is loaded or a value is changed in the inspector (Called in the editor only).
|
||||
/// </summary>
|
||||
|
@ -400,37 +418,6 @@ namespace Coffee.UIExtensions
|
|||
}
|
||||
#endif
|
||||
|
||||
//################################
|
||||
// Private Members.
|
||||
//################################
|
||||
static Shader s_SoftMaskShader;
|
||||
static Texture2D s_ReadTexture;
|
||||
static List<SoftMask> s_ActiveSoftMasks = new List<SoftMask>();
|
||||
static List<SoftMask> s_TempRelatables = new List<SoftMask>();
|
||||
static int s_StencilCompId;
|
||||
static int s_ColorMaskId;
|
||||
static int s_MainTexId;
|
||||
static int s_SoftnessId;
|
||||
static int s_GameVPId;
|
||||
static int s_GameTVPId;
|
||||
static int s_Alpha;
|
||||
MaterialPropertyBlock _mpb;
|
||||
CommandBuffer _cb;
|
||||
Material _material;
|
||||
RenderTexture _softMaskBuffer;
|
||||
int _stencilDepth;
|
||||
Mesh _mesh;
|
||||
SoftMask _parent;
|
||||
List<SoftMask> _children = new List<SoftMask>();
|
||||
bool _hasChanged = false;
|
||||
bool _hasStencilStateChanged = false;
|
||||
static readonly Dictionary<int, Matrix4x4> s_previousViewProjectionMatrices = new Dictionary<int, Matrix4x4> ();
|
||||
static readonly Dictionary<int, Matrix4x4> s_nowViewProjectionMatrices = new Dictionary<int, Matrix4x4> ();
|
||||
|
||||
Material material { get { return _material ? _material : _material = new Material(s_SoftMaskShader ? s_SoftMaskShader : s_SoftMaskShader = Resources.Load<Shader>("SoftMask")){ hideFlags = HideFlags.HideAndDontSave }; } }
|
||||
|
||||
Mesh mesh { get { return _mesh ? _mesh : _mesh = new Mesh(){ hideFlags = HideFlags.HideAndDontSave }; } }
|
||||
|
||||
/// <summary>
|
||||
/// Update all soft mask textures.
|
||||
/// </summary>
|
||||
|
@ -442,20 +429,19 @@ namespace Coffee.UIExtensions
|
|||
continue;
|
||||
|
||||
var canvas = sm.graphic.canvas;
|
||||
if(!canvas)
|
||||
if (!canvas)
|
||||
continue;
|
||||
|
||||
if (canvas.renderMode == RenderMode.WorldSpace)
|
||||
{
|
||||
var cam = canvas.worldCamera;
|
||||
if(!cam)
|
||||
if (!cam)
|
||||
continue;
|
||||
|
||||
Matrix4x4 nowVP = cam.projectionMatrix * cam.worldToCameraMatrix;
|
||||
|
||||
Matrix4x4 previousVP = default(Matrix4x4);
|
||||
int id = cam.GetInstanceID ();
|
||||
s_previousViewProjectionMatrices.TryGetValue (id, out previousVP);
|
||||
var nowVP = cam.projectionMatrix * cam.worldToCameraMatrix;
|
||||
var previousVP = default(Matrix4x4);
|
||||
var id = cam.GetInstanceID();
|
||||
s_previousViewProjectionMatrices.TryGetValue(id, out previousVP);
|
||||
s_nowViewProjectionMatrices[id] = nowVP;
|
||||
|
||||
if (previousVP != nowVP)
|
||||
|
@ -484,55 +470,51 @@ namespace Coffee.UIExtensions
|
|||
continue;
|
||||
|
||||
sm._hasChanged = false;
|
||||
if (!sm._parent)
|
||||
{
|
||||
if (sm._parent) continue;
|
||||
sm.UpdateMaskTexture();
|
||||
if (sm._hasStencilStateChanged)
|
||||
{
|
||||
|
||||
if (!sm._hasStencilStateChanged) continue;
|
||||
sm._hasStencilStateChanged = false;
|
||||
MaskUtilities.NotifyStencilStateChanged (sm);
|
||||
}
|
||||
}
|
||||
MaskUtilities.NotifyStencilStateChanged(sm);
|
||||
}
|
||||
|
||||
s_previousViewProjectionMatrices.Clear ();
|
||||
foreach (int id in s_nowViewProjectionMatrices.Keys)
|
||||
s_previousViewProjectionMatrices.Clear();
|
||||
foreach (var id in s_nowViewProjectionMatrices.Keys)
|
||||
{
|
||||
s_previousViewProjectionMatrices [id] = s_nowViewProjectionMatrices [id];
|
||||
s_previousViewProjectionMatrices[id] = s_nowViewProjectionMatrices[id];
|
||||
}
|
||||
s_nowViewProjectionMatrices.Clear ();
|
||||
|
||||
s_nowViewProjectionMatrices.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update the mask texture.
|
||||
/// </summary>
|
||||
void UpdateMaskTexture()
|
||||
private void UpdateMaskTexture()
|
||||
{
|
||||
if (!graphic || !graphic.canvas)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!graphic || !graphic.canvas) return;
|
||||
|
||||
_stencilDepth = MaskUtilities.GetStencilDepth(transform, MaskUtilities.FindRootSortOverrideCanvas(transform));
|
||||
_stencilDepth =
|
||||
MaskUtilities.GetStencilDepth(transform, MaskUtilities.FindRootSortOverrideCanvas(transform));
|
||||
|
||||
// Collect children soft masks.
|
||||
int depth = 0;
|
||||
var depth = 0;
|
||||
s_TmpSoftMasks[0].Add(this);
|
||||
while (_stencilDepth + depth < 3)
|
||||
{
|
||||
int count = s_TmpSoftMasks[depth].Count;
|
||||
for (int i = 0; i < count; i++)
|
||||
var count = s_TmpSoftMasks[depth].Count;
|
||||
for (var i = 0; i < count; i++)
|
||||
{
|
||||
List<SoftMask> children = s_TmpSoftMasks[depth][i]._children;
|
||||
int childCount = children.Count;
|
||||
for (int j = 0; j < childCount; j++)
|
||||
var childCount = children.Count;
|
||||
for (var j = 0; j < childCount; j++)
|
||||
{
|
||||
var child = children[j];
|
||||
var childDepth = child.m_PartOfParent ? depth : depth + 1;
|
||||
s_TmpSoftMasks[childDepth].Add(child);
|
||||
}
|
||||
}
|
||||
|
||||
depth++;
|
||||
}
|
||||
|
||||
|
@ -546,7 +528,8 @@ namespace Coffee.UIExtensions
|
|||
var cam = c.worldCamera ?? Camera.main;
|
||||
if (c && c.renderMode != RenderMode.ScreenSpaceOverlay && cam)
|
||||
{
|
||||
_cb.SetViewProjectionMatrices(cam.worldToCameraMatrix, GL.GetGPUProjectionMatrix(cam.projectionMatrix, false));
|
||||
_cb.SetViewProjectionMatrices(cam.worldToCameraMatrix,
|
||||
GL.GetGPUProjectionMatrix(cam.projectionMatrix, false));
|
||||
|
||||
#if UNITY_EDITOR
|
||||
var pv = GL.GetGPUProjectionMatrix(cam.projectionMatrix, false) * cam.worldToCameraMatrix;
|
||||
|
@ -558,32 +541,38 @@ namespace Coffee.UIExtensions
|
|||
{
|
||||
var pos = c.transform.position;
|
||||
var vm = Matrix4x4.TRS(new Vector3(-pos.x, -pos.y, -1000), Quaternion.identity, new Vector3(1, 1, -1f));
|
||||
var pm = Matrix4x4.TRS(new Vector3(0, 0, -1), Quaternion.identity, new Vector3(1 / pos.x, 1 / pos.y, -2 / 10000f));
|
||||
var pm = Matrix4x4.TRS(new Vector3(0, 0, -1), Quaternion.identity,
|
||||
new Vector3(1 / pos.x, 1 / pos.y, -2 / 10000f));
|
||||
_cb.SetViewProjectionMatrices(vm, pm);
|
||||
|
||||
#if UNITY_EDITOR
|
||||
var scale = c.transform.localScale.x;
|
||||
var size = (c.transform as RectTransform).sizeDelta;
|
||||
_cb.SetGlobalMatrix(s_GameVPId, Matrix4x4.TRS(new Vector3(0, 0, 0.5f), Quaternion.identity, new Vector3(2 / size.x, 2 / size.y, 0.0005f * scale)));
|
||||
_cb.SetGlobalMatrix(s_GameTVPId, Matrix4x4.TRS(new Vector3(0, 0, 0), Quaternion.identity, new Vector3(1 / pos.x, 1 / pos.y, -2 / 2000f)) * Matrix4x4.Translate(-pos));
|
||||
_cb.SetGlobalMatrix(s_GameVPId,
|
||||
Matrix4x4.TRS(new Vector3(0, 0, 0.5f), Quaternion.identity,
|
||||
new Vector3(2 / size.x, 2 / size.y, 0.0005f * scale)));
|
||||
_cb.SetGlobalMatrix(s_GameTVPId,
|
||||
Matrix4x4.TRS(new Vector3(0, 0, 0), Quaternion.identity,
|
||||
new Vector3(1 / pos.x, 1 / pos.y, -2 / 2000f)) * Matrix4x4.Translate(-pos));
|
||||
#endif
|
||||
}
|
||||
|
||||
// Draw soft masks.
|
||||
for (int i = 0; i < s_TmpSoftMasks.Length; i++)
|
||||
for (var i = 0; i < s_TmpSoftMasks.Length; i++)
|
||||
{
|
||||
int count = s_TmpSoftMasks[i].Count;
|
||||
for (int j = 0; j < count; j++)
|
||||
var count = s_TmpSoftMasks[i].Count;
|
||||
for (var j = 0; j < count; j++)
|
||||
{
|
||||
var sm = s_TmpSoftMasks[i][j];
|
||||
|
||||
if (i != 0)
|
||||
{
|
||||
sm._stencilDepth = MaskUtilities.GetStencilDepth(sm.transform, MaskUtilities.FindRootSortOverrideCanvas(sm.transform));
|
||||
sm._stencilDepth = MaskUtilities.GetStencilDepth(sm.transform,
|
||||
MaskUtilities.FindRootSortOverrideCanvas(sm.transform));
|
||||
}
|
||||
|
||||
// Set material property.
|
||||
sm.material.SetInt(s_ColorMaskId, (int)1 << (3 - _stencilDepth - i));
|
||||
sm.material.SetInt(s_ColorMaskId, (int) 1 << (3 - _stencilDepth - i));
|
||||
sm._mpb.SetTexture(s_MainTexId, sm.graphic.mainTexture);
|
||||
sm._mpb.SetFloat(s_SoftnessId, sm.m_Softness);
|
||||
sm._mpb.SetFloat(s_Alpha, sm.m_Alpha);
|
||||
|
@ -591,6 +580,7 @@ namespace Coffee.UIExtensions
|
|||
// Draw mesh.
|
||||
_cb.DrawMesh(sm.mesh, sm.transform.localToWorldMatrix, sm.material, 0, 0, sm._mpb);
|
||||
}
|
||||
|
||||
s_TmpSoftMasks[i].Clear();
|
||||
}
|
||||
|
||||
|
@ -600,7 +590,7 @@ namespace Coffee.UIExtensions
|
|||
/// <summary>
|
||||
/// Gets the size of the desampling.
|
||||
/// </summary>
|
||||
void GetDesamplingSize(DesamplingRate rate, out int w, out int h)
|
||||
private static void GetDesamplingSize(DesamplingRate rate, out int w, out int h)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
var res = UnityEditor.UnityStats.screenRes.Split('x');
|
||||
|
@ -614,15 +604,15 @@ namespace Coffee.UIExtensions
|
|||
if (rate == DesamplingRate.None)
|
||||
return;
|
||||
|
||||
float aspect = (float)w / h;
|
||||
var aspect = (float) w / h;
|
||||
if (w < h)
|
||||
{
|
||||
h = Mathf.ClosestPowerOfTwo(h / (int)rate);
|
||||
h = Mathf.ClosestPowerOfTwo(h / (int) rate);
|
||||
w = Mathf.CeilToInt(h * aspect);
|
||||
}
|
||||
else
|
||||
{
|
||||
w = Mathf.ClosestPowerOfTwo(w / (int)rate);
|
||||
w = Mathf.ClosestPowerOfTwo(w / (int) rate);
|
||||
h = Mathf.CeilToInt(w / aspect);
|
||||
}
|
||||
}
|
||||
|
@ -631,40 +621,36 @@ namespace Coffee.UIExtensions
|
|||
/// Release the specified obj.
|
||||
/// </summary>
|
||||
/// <param name="obj">Object.</param>
|
||||
void ReleaseRT(ref RenderTexture tmpRT)
|
||||
{
|
||||
if (tmpRT)
|
||||
private static void ReleaseRt(ref RenderTexture tmpRT)
|
||||
{
|
||||
if (!tmpRT) return;
|
||||
tmpRT.Release();
|
||||
RenderTexture.ReleaseTemporary(tmpRT);
|
||||
tmpRT = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Release the specified obj.
|
||||
/// </summary>
|
||||
/// <param name="obj">Object.</param>
|
||||
void ReleaseObject(Object obj)
|
||||
private static void ReleaseObject(Object obj)
|
||||
{
|
||||
if (obj)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (!obj) return;
|
||||
#if UNITY_EDITOR
|
||||
if (!Application.isPlaying)
|
||||
DestroyImmediate(obj);
|
||||
else
|
||||
#endif
|
||||
#endif
|
||||
Destroy(obj);
|
||||
obj = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Set the parent of the soft mask.
|
||||
/// </summary>
|
||||
/// <param name="newParent">The parent soft mask to use.</param>
|
||||
void SetParent(SoftMask newParent)
|
||||
private void SetParent(SoftMask newParent)
|
||||
{
|
||||
if (_parent != newParent && this != newParent)
|
||||
{
|
||||
|
@ -673,6 +659,7 @@ namespace Coffee.UIExtensions
|
|||
_parent._children.Remove(this);
|
||||
_parent._children.RemoveAll(x => x == null);
|
||||
}
|
||||
|
||||
_parent = newParent;
|
||||
}
|
||||
|
||||
|
@ -685,27 +672,32 @@ namespace Coffee.UIExtensions
|
|||
/// <summary>
|
||||
/// Gets the pixel value.
|
||||
/// </summary>
|
||||
float GetPixelValue(int x, int y, int[] interactions)
|
||||
private float GetPixelValue(int x, int y, int[] interactions)
|
||||
{
|
||||
if (!s_ReadTexture)
|
||||
{
|
||||
s_ReadTexture = new Texture2D(1, 1, TextureFormat.ARGB32, false);
|
||||
}
|
||||
var currentRT = RenderTexture.active;
|
||||
|
||||
var currentRt = RenderTexture.active;
|
||||
|
||||
RenderTexture.active = softMaskBuffer;
|
||||
s_ReadTexture.ReadPixels(new Rect(x, y, 1, 1), 0, 0);
|
||||
s_ReadTexture.Apply(false, false);
|
||||
RenderTexture.active = currentRT;
|
||||
RenderTexture.active = currentRt;
|
||||
|
||||
var colors = s_ReadTexture.GetRawTextureData();
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
switch (interactions[(i + 3)%4])
|
||||
switch (interactions[(i + 3) % 4])
|
||||
{
|
||||
case 0: colors[i] = 255; break;
|
||||
case 2: colors[i] = (byte)(255 - colors[i]); break;
|
||||
case 0:
|
||||
colors[i] = 255;
|
||||
break;
|
||||
case 2:
|
||||
colors[i] = (byte) (255 - colors[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
using UnityEngine.UI;
|
||||
using MaskIntr = UnityEngine.SpriteMaskInteraction;
|
||||
using UnityEngine.Serialization;
|
||||
|
||||
namespace Coffee.UIExtensions
|
||||
namespace Coffee.UISoftMask
|
||||
{
|
||||
/// <summary>
|
||||
/// Soft maskable.
|
||||
|
@ -17,120 +15,40 @@ namespace Coffee.UIExtensions
|
|||
#else
|
||||
[ExecuteInEditMode]
|
||||
# endif
|
||||
public class SoftMaskable : MonoBehaviour, IMaterialModifier, ICanvasRaycastFilter, ISerializationCallbackReceiver
|
||||
public class SoftMaskable : MonoBehaviour, IMaterialModifier, ICanvasRaycastFilter
|
||||
#if UNITY_EDITOR
|
||||
, ISerializationCallbackReceiver
|
||||
# endif
|
||||
{
|
||||
//################################
|
||||
// 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);
|
||||
static readonly Hash128 k_InvalidHash = new Hash128();
|
||||
|
||||
static int s_SoftMaskTexId;
|
||||
static int s_StencilCompId;
|
||||
static int s_MaskInteractionId;
|
||||
static List<SoftMaskable> s_ActiveSoftMaskables;
|
||||
static int[] s_Interactions = new int[4];
|
||||
|
||||
//################################
|
||||
// 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 to mask.")]
|
||||
[SerializeField] bool m_UseStencil = false;
|
||||
[Tooltip("Use soft-masked raycast target.\n\nNote: This option is expensive.")]
|
||||
[SerializeField] bool m_RaycastFilter = false;
|
||||
[SerializeField]
|
||||
bool m_Inverse = false;
|
||||
|
||||
[Tooltip("The interaction for each masks.")] [HideInInspector] [SerializeField]
|
||||
int m_MaskInteraction = kVisibleInside;
|
||||
|
||||
//################################
|
||||
// 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;
|
||||
}
|
||||
[Tooltip("Use stencil to mask.")] [SerializeField]
|
||||
bool m_UseStencil = false;
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
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)
|
||||
));
|
||||
|
||||
StencilMaterial.Remove(baseMaterial);
|
||||
ReleaseMaterial(ref _maskMaterial);
|
||||
_maskMaterial = result;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
result.EnableKeyword("SOFTMASK_EDITOR");
|
||||
#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;
|
||||
}
|
||||
else if (!m_RaycastFilter)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
[Tooltip("Use soft-masked raycast target.\n\nNote: This option is expensive.")] [SerializeField]
|
||||
bool m_RaycastFilter = false;
|
||||
|
||||
Graphic _graphic = null;
|
||||
SoftMask _softMask = null;
|
||||
Material _maskMaterial = null;
|
||||
Hash128 _effectMaterialHash;
|
||||
|
||||
/// <summary>
|
||||
/// The graphic will be visible only in areas where no mask is present.
|
||||
|
@ -140,12 +58,10 @@ namespace Coffee.UIExtensions
|
|||
get { return m_MaskInteraction == kVisibleOutside; }
|
||||
set
|
||||
{
|
||||
int intValue = value ? kVisibleOutside : kVisibleInside;
|
||||
if (m_MaskInteraction != intValue)
|
||||
{
|
||||
var intValue = value ? kVisibleOutside : kVisibleInside;
|
||||
if (m_MaskInteraction == intValue) return;
|
||||
m_MaskInteraction = intValue;
|
||||
graphic.SetMaterialDirty();
|
||||
}
|
||||
graphic.SetMaterialDirtyEx();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -161,7 +77,98 @@ namespace Coffee.UIExtensions
|
|||
/// <summary>
|
||||
/// The graphic associated with the soft mask.
|
||||
/// </summary>
|
||||
public Graphic graphic{ get { return _graphic ? _graphic : _graphic = GetComponent<Graphic>(); } }
|
||||
public Graphic graphic
|
||||
{
|
||||
get { return _graphic ? _graphic : _graphic = GetComponent<Graphic>(); }
|
||||
}
|
||||
|
||||
/// <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;
|
||||
|
||||
// Unregister the previous material
|
||||
MaterialCache.Unregister(_effectMaterialHash);
|
||||
_effectMaterialHash = k_InvalidHash;
|
||||
|
||||
// If this component is disabled, the material is returned as is.
|
||||
if (!isActiveAndEnabled) return baseMaterial;
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
// If the parents do not have a soft mask component, the material is returned as is.
|
||||
if (!_softMask) return baseMaterial;
|
||||
|
||||
// Generate soft maskable material.
|
||||
_effectMaterialHash = new Hash128(
|
||||
(uint) baseMaterial.GetInstanceID(),
|
||||
(uint) _softMask.GetInstanceID(),
|
||||
(uint) m_MaskInteraction,
|
||||
(uint) (m_UseStencil ? 1 : 0)
|
||||
);
|
||||
|
||||
// Generate soft maskable material.
|
||||
var modifiedMaterial = MaterialCache.Register(baseMaterial, _effectMaterialHash, mat =>
|
||||
{
|
||||
mat.shader = Shader.Find(string.Format("Hidden/{0} (SoftMaskable)", mat.shader.name));
|
||||
#if UNITY_EDITOR
|
||||
mat.EnableKeyword("SOFTMASK_EDITOR");
|
||||
#endif
|
||||
mat.SetTexture(s_SoftMaskTexId, _softMask.softMaskBuffer);
|
||||
mat.SetInt(s_StencilCompId,
|
||||
m_UseStencil ? (int) CompareFunction.Equal : (int) CompareFunction.Always);
|
||||
mat.SetVector(s_MaskInteractionId, new Vector4(
|
||||
(m_MaskInteraction & 0x3),
|
||||
((m_MaskInteraction >> 2) & 0x3),
|
||||
((m_MaskInteraction >> 4) & 0x3),
|
||||
((m_MaskInteraction >> 6) & 0x3)
|
||||
));
|
||||
});
|
||||
_maskMaterial = modifiedMaterial;
|
||||
|
||||
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)
|
||||
return true;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the interaction for each mask.
|
||||
|
@ -174,45 +181,18 @@ namespace Coffee.UIExtensions
|
|||
/// <summary>
|
||||
/// Set the interaction for each mask.
|
||||
/// </summary>
|
||||
public void SetMaskInteraction(SpriteMaskInteraction layer0, SpriteMaskInteraction layer1, SpriteMaskInteraction layer2, SpriteMaskInteraction layer3)
|
||||
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();
|
||||
}
|
||||
m_MaskInteraction = (int) layer0 + ((int) layer1 << 2) + ((int) layer2 << 4) + ((int) layer3 << 6);
|
||||
graphic.SetMaterialDirtyEx();
|
||||
}
|
||||
|
||||
//################################
|
||||
// Private Members.
|
||||
//################################
|
||||
Graphic _graphic = null;
|
||||
SoftMask _softMask = null;
|
||||
Material _maskMaterial = null;
|
||||
static int s_SoftMaskTexId;
|
||||
static int s_StencilCompId;
|
||||
static int s_MaskInteractionId;
|
||||
static List<SoftMaskable> s_ActiveSoftMaskables;
|
||||
static int[] s_Interactions = new int[4];
|
||||
static Material s_DefaultMaterial;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
/// <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()
|
||||
private void OnEnable()
|
||||
{
|
||||
// Register.
|
||||
if (s_ActiveSoftMaskables == null)
|
||||
|
@ -223,65 +203,35 @@ namespace Coffee.UIExtensions
|
|||
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();
|
||||
}
|
||||
graphic.SetMaterialDirtyEx();
|
||||
_softMask = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function is called when the behaviour becomes disabled.
|
||||
/// </summary>
|
||||
void OnDisable()
|
||||
private void OnDisable()
|
||||
{
|
||||
s_ActiveSoftMaskables.Remove(this);
|
||||
|
||||
var g = graphic;
|
||||
if (g)
|
||||
{
|
||||
if (g.material == s_DefaultMaterial)
|
||||
{
|
||||
g.material = null;
|
||||
}
|
||||
g.SetMaterialDirty();
|
||||
}
|
||||
ReleaseMaterial(ref _maskMaterial);
|
||||
|
||||
graphic.SetMaterialDirtyEx();
|
||||
_softMask = null;
|
||||
|
||||
MaterialCache.Unregister(_effectMaterialHash);
|
||||
_effectMaterialHash = k_InvalidHash;
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
/// <summary>
|
||||
/// Release the material.
|
||||
/// This function is called when the script is loaded or a value is changed in the inspector (Called in the editor only).
|
||||
/// </summary>
|
||||
void ReleaseMaterial(ref Material mat)
|
||||
private void OnValidate()
|
||||
{
|
||||
if (mat)
|
||||
{
|
||||
StencilMaterial.Remove(mat);
|
||||
|
||||
#if UNITY_EDITOR
|
||||
if (!Application.isPlaying)
|
||||
{
|
||||
DestroyImmediate(mat);
|
||||
graphic.SetMaterialDirtyEx();
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
Destroy(mat);
|
||||
}
|
||||
mat = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ISerializationCallbackReceiver.OnBeforeSerialize()
|
||||
{
|
||||
|
@ -289,13 +239,25 @@ namespace Coffee.UIExtensions
|
|||
|
||||
void ISerializationCallbackReceiver.OnAfterDeserialize()
|
||||
{
|
||||
#pragma warning disable 0612
|
||||
#pragma warning disable 0612
|
||||
if (m_Inverse)
|
||||
{
|
||||
m_Inverse = false;
|
||||
m_MaskInteraction = (2 << 0) + (2 << 2) + (2 << 4) + (2 << 6);
|
||||
}
|
||||
#pragma warning restore 0612
|
||||
#pragma warning restore 0612
|
||||
|
||||
var current = this;
|
||||
UnityEditor.EditorApplication.delayCall += () =>
|
||||
{
|
||||
if (current && graphic && graphic.material && graphic.material.shader &&
|
||||
graphic.material.shader.name == "Hidden/UI/Default (SoftMaskable)")
|
||||
{
|
||||
graphic.material = null;
|
||||
graphic.SetMaterialDirtyEx();
|
||||
}
|
||||
};
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
Shader "UI/Default-SoftMask"
|
||||
Shader "Hidden/UI/Default (SoftMaskable)"
|
||||
{
|
||||
Properties
|
||||
{
|
|
@ -1,4 +1,4 @@
|
|||
Shader "TextMeshPro/Distance Field (SoftMaskable)" {
|
||||
Shader "Hidden/TextMeshPro/Distance Field (SoftMaskable)" {
|
||||
|
||||
Properties {
|
||||
_FaceTex ("Face Texture", 2D) = "white" {}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
Shader "TextMeshPro/Sprite (SoftMaskable)"
|
||||
Shader "Hidden/TextMeshPro/Sprite (SoftMaskable)"
|
||||
{
|
||||
Properties
|
||||
{
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"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": "0.10.0-preview.3",
|
||||
"version": "1.0.0-preview.1",
|
||||
"unity": "2017.1",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
|
|
Loading…
Reference in New Issue