This commit is contained in:
2024-10-16 00:03:41 +08:00
commit 897058435c
5033 changed files with 1009728 additions and 0 deletions

12
Assets/3rd/UIEffect/.github/FUNDING.yml vendored Normal file
View File

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

View File

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

View File

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

View File

@@ -0,0 +1,25 @@
---
name: Question
about: Ask a question about this project
title: ''
labels: question
assignees: mob-sakai
---
NOTE: Your issue may already be reported! Please search on the [issue tracker](../) before creating one.
**Describe what help do you need**
A description of the question.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Environment (please complete the following information):**
- Version [e.g. 4.0.0]
- Platform: [e.g. Editor(Windows/Mac), Standalone(Windows/Mac), iOS, Android, WebGL]
- Unity version: [e.g. 2018.2.8f1]
- Build options: [e.g. IL2CPP, .Net 4.x, LWRP]
**Additional context**
Add any other context or screenshots about the question here.

View File

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@@ -0,0 +1,100 @@
fileFormatVersion: 2
guid: 3e04c247fb2604af186173fce0bc62de
timeCreated: 1524468976
licenseType: Pro
TextureImporter:
fileIDToRecycleName: {}
serializedVersion: 4
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 0
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
filterMode: 1
aniso: -1
mipBias: -1
wrapMode: 1
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spritePixelsToUnits: 100
alphaUsage: 2
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 10
textureShape: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- buildTarget: DefaultTexturePlatform
maxTextureSize: 256
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
- buildTarget: Standalone
maxTextureSize: 256
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
- buildTarget: iPhone
maxTextureSize: 256
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
- buildTarget: Android
maxTextureSize: 256
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
- buildTarget: WebGL
maxTextureSize: 256
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
spritePackingTag:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,87 @@
Shader "Hidden/UI/Default (UIDissolve)"
{
Properties
{
[PerRendererData] _MainTex ("Main Texture", 2D) = "white" {}
_Color ("Tint", Color) = (1,1,1,1)
_StencilComp ("Stencil Comparison", Float) = 8
_Stencil ("Stencil ID", Float) = 0
_StencilOp ("Stencil Operation", Float) = 0
_StencilWriteMask ("Stencil Write Mask", Float) = 255
_StencilReadMask ("Stencil Read Mask", Float) = 255
_ColorMask ("Color Mask", Float) = 15
[Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0
[Header(Dissolve)]
_TransitionTex ("Transition Texture (A)", 2D) = "white" {}
_ParamTex ("Parameter Texture", 2D) = "white" {}
}
SubShader
{
Tags
{
"Queue"="Transparent"
"IgnoreProjector"="True"
"RenderType"="Transparent"
"PreviewType"="Plane"
"CanUseSpriteAtlas"="True"
}
Stencil
{
Ref [_Stencil]
Comp [_StencilComp]
Pass [_StencilOp]
ReadMask [_StencilReadMask]
WriteMask [_StencilWriteMask]
}
Cull Off
Lighting Off
ZWrite Off
ZTest [unity_GUIZTestMode]
Blend SrcAlpha OneMinusSrcAlpha
ColorMask [_ColorMask]
Pass
{
Name "Default"
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 2.0
#define DISSOLVE 1
#pragma multi_compile __ UNITY_UI_ALPHACLIP
#pragma multi_compile __ ADD SUBTRACT FILL
#include "UnityCG.cginc"
#include "UnityUI.cginc"
#define UI_DISSOLVE 1
#include "UIEffect.cginc"
#include "UIEffectSprite.cginc"
fixed4 frag(v2f IN) : SV_Target
{
half4 color = (tex2D(_MainTex, IN.texcoord) + _TextureSampleAdd) * IN.color;
color.a *= UnityGet2DClipping(IN.worldPosition.xy, _ClipRect);
// Dissolve
color = ApplyTransitionEffect(color, IN.eParam);
#ifdef UNITY_UI_ALPHACLIP
clip (color.a - 0.001);
#endif
return color;
}
ENDCG
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: e1b48dc831eb147e9886c049033213bf
ShaderImporter:
externalObjects: {}
defaultTextures:
- _MainTex: {instanceID: 0}
- _TransitionTex: {instanceID: 0}
- _ParamTex: {instanceID: 0}
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,309 @@
#ifndef UI_EFFECT_INCLUDED
#define UI_EFFECT_INCLUDED
sampler2D _TransitionTex;
sampler2D _ParamTex;
#if GRAYSCALE | SEPIA | NEGA | PIXEL | MONO | CUTOFF | HUE
#define UI_TONE
#endif
#if ADD | SUBTRACT | FILL
#define UI_COLOR
#endif
#if FASTBLUR | MEDIUMBLUR | DETAILBLUR
#define UI_BLUR
#endif
// Unpack float to low-precision [0-1] fixed4.
fixed4 UnpackToVec4(float value)
{
const int PACKER_STEP = 64;
const int PRECISION = PACKER_STEP - 1;
fixed4 unpacked;
unpacked.x = (value % PACKER_STEP) / PRECISION;
value = floor(value / PACKER_STEP);
unpacked.y = (value % PACKER_STEP) / PRECISION;
value = floor(value / PACKER_STEP);
unpacked.z = (value % PACKER_STEP) / PRECISION;
value = floor(value / PACKER_STEP);
unpacked.w = (value % PACKER_STEP) / PRECISION;
return unpacked;
}
// Unpack float to low-precision [0-1] fixed3.
fixed3 UnpackToVec3(float value)
{
const int PACKER_STEP = 256;
const int PRECISION = PACKER_STEP - 1;
fixed3 unpacked;
unpacked.x = (value % (PACKER_STEP)) / (PACKER_STEP - 1);
value = floor(value / (PACKER_STEP));
unpacked.y = (value % PACKER_STEP) / (PACKER_STEP - 1);
value = floor(value / PACKER_STEP);
unpacked.z = (value % PACKER_STEP) / (PACKER_STEP - 1);
return unpacked;
}
// Unpack float to low-precision [0-1] half2.
half2 UnpackToVec2(float value)
{
const int PACKER_STEP = 4096;
const int PRECISION = PACKER_STEP - 1;
half2 unpacked;
unpacked.x = (value % (PACKER_STEP)) / (PACKER_STEP - 1);
value = floor(value / (PACKER_STEP));
unpacked.y = (value % PACKER_STEP) / (PACKER_STEP - 1);
return unpacked;
}
// Sample texture with blurring.
// * Fast: Sample texture with 3x3 kernel.
// * Medium: Sample texture with 5x5 kernel.
// * Detail: Sample texture with 7x7 kernel.
fixed4 Tex2DBlurring (sampler2D tex, half2 texcood, half2 blur, half4 mask)
{
#if FASTBLUR && EX
const int KERNEL_SIZE = 5;
const float KERNEL_[5] = { 0.2486, 0.7046, 1.0, 0.7046, 0.2486};
#elif MEDIUMBLUR && EX
const int KERNEL_SIZE = 9;
const float KERNEL_[9] = { 0.0438, 0.1719, 0.4566, 0.8204, 1.0, 0.8204, 0.4566, 0.1719, 0.0438};
#elif DETAILBLUR && EX
const int KERNEL_SIZE = 13;
const float KERNEL_[13] = { 0.0438, 0.1138, 0.2486, 0.4566, 0.7046, 0.9141, 1.0, 0.9141, 0.7046, 0.4566, 0.2486, 0.1138, 0.0438};
#elif FASTBLUR
const int KERNEL_SIZE = 3;
const float KERNEL_[3] = { 0.4566, 1.0, 0.4566};
#elif MEDIUMBLUR
const int KERNEL_SIZE = 5;
const float KERNEL_[5] = { 0.2486, 0.7046, 1.0, 0.7046, 0.2486};
#elif DETAILBLUR
const int KERNEL_SIZE = 7;
const float KERNEL_[7] = { 0.1719, 0.4566, 0.8204, 1.0, 0.8204, 0.4566, 0.1719};
#else
const int KERNEL_SIZE = 1;
const float KERNEL_[1] = { 1.0 };
#endif
float4 o = 0;
float sum = 0;
float2 shift = 0;
for(int x = 0; x < KERNEL_SIZE; x++)
{
shift.x = blur.x * (float(x) - KERNEL_SIZE/2);
for(int y = 0; y < KERNEL_SIZE; y++)
{
shift.y = blur.y * (float(y) - KERNEL_SIZE/2);
float2 uv = texcood + shift;
float weight = KERNEL_[x] * KERNEL_[y];
sum += weight;
#if EX
fixed masked = min(mask.x <= uv.x, uv.x <= mask.z) * min(mask.y <= uv.y, uv.y <= mask.w);
o += lerp(fixed4(0.5, 0.5, 0.5, 0), tex2D(tex, uv), masked) * weight;
#else
o += tex2D(tex, uv) * weight;
#endif
}
}
return o / sum;
}
// Sample texture with blurring.
// * Fast: Sample texture with 3x3 kernel.
// * Medium: Sample texture with 5x5 kernel.
// * Detail: Sample texture with 7x7 kernel.
fixed4 Tex2DBlurring (sampler2D tex, half2 texcood, half2 blur)
{
return Tex2DBlurring(tex, texcood, blur, half4(0,0,1,1));
}
// Sample texture with blurring.
// * Fast: Sample texture with 3x1 kernel.
// * Medium: Sample texture with 5x1 kernel.
// * Detail: Sample texture with 7x1 kernel.
fixed4 Tex2DBlurring1D (sampler2D tex, half2 uv, half2 blur)
{
#if FASTBLUR
const int KERNEL_SIZE = 3;
#elif MEDIUMBLUR
const int KERNEL_SIZE = 5;
#elif DETAILBLUR
const int KERNEL_SIZE = 7;
#else
const int KERNEL_SIZE = 1;
#endif
float4 o = 0;
float sum = 0;
float weight;
half2 texcood;
for(int i = -KERNEL_SIZE/2; i <= KERNEL_SIZE/2; i++)
{
texcood = uv;
texcood.x += blur.x * i;
texcood.y += blur.y * i;
weight = 1.0/(abs(i)+2);
o += tex2D(tex, texcood)*weight;
sum += weight;
}
return o / sum;
}
fixed3 shift_hue(fixed3 RGB, half VSU, half VSW)
{
fixed3 result;
result.x = (0.299 + 0.701*VSU + 0.168*VSW)*RGB.x
+ (0.587 - 0.587*VSU + 0.330*VSW)*RGB.y
+ (0.114 - 0.114*VSU - 0.497*VSW)*RGB.z;
result.y = (0.299 - 0.299*VSU - 0.328*VSW)*RGB.x
+ (0.587 + 0.413*VSU + 0.035*VSW)*RGB.y
+ (0.114 - 0.114*VSU + 0.292*VSW)*RGB.z;
result.z = (0.299 - 0.3*VSU + 1.25*VSW)*RGB.x
+ (0.587 - 0.588*VSU - 1.05*VSW)*RGB.y
+ (0.114 + 0.886*VSU - 0.203*VSW)*RGB.z;
return result;
}
// Apply tone effect.
fixed4 ApplyToneEffect(fixed4 color, fixed factor)
{
#ifdef GRAYSCALE
color.rgb = lerp(color.rgb, Luminance(color.rgb), factor);
#elif SEPIA
color.rgb = lerp(color.rgb, Luminance(color.rgb) * half3(1.07, 0.74, 0.43), factor);
#elif NEGA
color.rgb = lerp(color.rgb, 1 - color.rgb, factor);
#endif
return color;
}
// Apply color effect.
fixed4 ApplyColorEffect(half4 color, half4 factor)
{
#if FILL
color.rgb = lerp(color.rgb, factor.rgb, factor.a);
#elif ADD
color.rgb += factor.rgb * factor.a;
#elif SUBTRACT
color.rgb -= factor.rgb * factor.a;
#else
color.rgb = lerp(color.rgb, color.rgb * factor.rgb, factor.a);
#endif
#if CUTOFF
color.a = factor.a;
#endif
return color;
}
// Apply transition effect.
fixed4 ApplyTransitionEffect(half4 color, half3 transParam)
{
fixed4 param = tex2D(_ParamTex, float2(0.25, transParam.z));
float alpha = tex2D(_TransitionTex, transParam.xy).a;
#if REVERSE
fixed effectFactor = 1 - param.x;
#else
fixed effectFactor = param.x;
#endif
#if FADE
color.a *= saturate(alpha + (1 - effectFactor * 2));
#elif CUTOFF
color.a *= step(0.001, color.a * alpha - effectFactor);
#elif DISSOLVE
fixed width = param.y/4;
fixed softness = param.z;
fixed3 dissolveColor = tex2D(_ParamTex, float2(0.75, transParam.z)).rgb;
float factor = alpha - effectFactor * ( 1 + width ) + width;
fixed edgeLerp = step(factor, color.a) * saturate((width - factor)*16/ softness);
color = ApplyColorEffect(color, fixed4(dissolveColor, edgeLerp));
color.a *= saturate((factor)*32/ softness);
#endif
return color;
}
// Apply shiny effect.
half4 ApplyShinyEffect(half4 color, half2 shinyParam)
{
fixed nomalizedPos = shinyParam.x;
fixed4 param1 = tex2D(_ParamTex, float2(0.25, shinyParam.y));
fixed4 param2 = tex2D(_ParamTex, float2(0.75, shinyParam.y));
half location = param1.x * 2 - 0.5;
fixed width = param1.y;
fixed soft = param1.z;
fixed brightness = param1.w;
fixed gloss = param2.x;
half normalized = 1 - saturate(abs((nomalizedPos - location) / width));
half shinePower = smoothstep(0, soft, normalized);
half3 reflectColor = lerp(fixed3(1,1,1), color.rgb * 7, gloss);
color.rgb += color.a * (shinePower / 2) * brightness * reflectColor;
return color;
}
half3 RgbToHsv(half3 c) {
half4 K = half4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
half4 p = lerp(half4(c.bg, K.wz), half4(c.gb, K.xy), step(c.b, c.g));
half4 q = lerp(half4(p.xyw, c.r), half4(c.r, p.yzx), step(p.x, c.r));
half d = q.x - min(q.w, q.y);
half e = 1.0e-10;
return half3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
}
half3 HsvToRgb(half3 c) {
c = half3(c.x, clamp(c.yz, 0.0, 1.0));
half4 K = half4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
half3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);
return c.z * lerp(K.xxx, clamp(p.xyz - K.xxx, 0.0, 1.0), c.y);
}
// Apply Hsv effect.
half4 ApplyHsvEffect(half4 color, half param)
{
fixed4 param1 = tex2D(_ParamTex, float2(0.25, param));
fixed4 param2 = tex2D(_ParamTex, float2(0.75, param));
fixed3 targetHsv = param1.rgb;
fixed3 targetRange = param1.w;
fixed3 hsvShift = param2.xyz - 0.5;
half3 hsv = RgbToHsv(color.rgb);
half3 range = abs(hsv - targetHsv);
half diff = max(max(min(1-range.x, range.x), min(1-range.y, range.y)/10), min(1-range.z, range.z)/10);
fixed masked = step(diff, targetRange);
color.rgb = HsvToRgb(hsv + hsvShift * masked);
return color;
}
#endif // UI_EFFECT_INCLUDED

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 7467061e9f5514f2c80e30817ee2458b
timeCreated: 1487915863
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,113 @@
Shader "Hidden/UI/Default (UIEffect)"
{
Properties
{
[PerRendererData] _MainTex ("Main Texture", 2D) = "white" {}
_Color ("Tint", Color) = (1,1,1,1)
_StencilComp ("Stencil Comparison", Float) = 8
_Stencil ("Stencil ID", Float) = 0
_StencilOp ("Stencil Operation", Float) = 0
_StencilWriteMask ("Stencil Write Mask", Float) = 255
_StencilReadMask ("Stencil Read Mask", Float) = 255
_ColorMask ("Color Mask", Float) = 15
[Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0
_ParamTex ("Parameter Texture", 2D) = "white" {}
}
SubShader
{
Tags
{
"Queue"="Transparent"
"IgnoreProjector"="True"
"RenderType"="Transparent"
"PreviewType"="Plane"
"CanUseSpriteAtlas"="True"
}
Stencil
{
Ref [_Stencil]
Comp [_StencilComp]
Pass [_StencilOp]
ReadMask [_StencilReadMask]
WriteMask [_StencilWriteMask]
}
Cull Off
Lighting Off
ZWrite Off
ZTest [unity_GUIZTestMode]
Blend SrcAlpha OneMinusSrcAlpha
ColorMask [_ColorMask]
Pass
{
Name "Default"
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#if !defined(SHADER_API_D3D11_9X) && !defined(SHADER_API_D3D9)
#pragma target 2.0
#else
#pragma target 3.0
#endif
#pragma multi_compile __ UNITY_UI_ALPHACLIP
#pragma multi_compile __ GRAYSCALE SEPIA NEGA PIXEL
#pragma multi_compile __ ADD SUBTRACT FILL
#pragma multi_compile __ FASTBLUR MEDIUMBLUR DETAILBLUR
#pragma multi_compile __ EX
#include "UnityCG.cginc"
#include "UnityUI.cginc"
#define UI_EFFECT 1
#include "UIEffect.cginc"
#include "UIEffectSprite.cginc"
fixed4 frag(v2f IN) : SV_Target
{
fixed4 param = tex2D(_ParamTex, float2(0.25, IN.eParam));
fixed effectFactor = param.x;
fixed colorFactor = param.y;
fixed blurFactor = param.z;
#if PIXEL
half2 pixelSize = max(2, (1-effectFactor*0.95) * _MainTex_TexelSize.zw);
IN.texcoord = round(IN.texcoord * pixelSize) / pixelSize;
#endif
#if defined(UI_BLUR) && EX
half4 color = (Tex2DBlurring(_MainTex, IN.texcoord, blurFactor * _MainTex_TexelSize.xy * 2, IN.uvMask) + _TextureSampleAdd);
#elif defined(UI_BLUR)
half4 color = (Tex2DBlurring(_MainTex, IN.texcoord, blurFactor * _MainTex_TexelSize.xy * 2) + _TextureSampleAdd);
#else
half4 color = (tex2D(_MainTex, IN.texcoord) + _TextureSampleAdd);
#endif
color.a *= UnityGet2DClipping(IN.worldPosition.xy, _ClipRect);
#if UNITY_UI_ALPHACLIP
clip (color.a - 0.001);
#endif
#if defined (UI_TONE)
color = ApplyToneEffect(color, effectFactor);
#endif
color = ApplyColorEffect(color, fixed4(IN.color.rgb, colorFactor));
color.a *= IN.color.a;
return color;
}
ENDCG
}
}
}

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: b868e81d0156245e08c8646b4fb68d7a
timeCreated: 1482973535
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,75 @@
#ifndef UI_EFFECT_SPRITE_INCLUDED
#define UI_EFFECT_SPRITE_INCLUDED
fixed4 _Color;
fixed4 _TextureSampleAdd;
float4 _ClipRect;
sampler2D _MainTex;
float4 _MainTex_TexelSize;
struct appdata_t
{
float4 vertex : POSITION;
float4 color : COLOR;
float2 texcoord : TEXCOORD0;
#if EX
float2 uvMask : TEXCOORD1;
#endif
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct v2f
{
float4 vertex : SV_POSITION;
fixed4 color : COLOR;
half2 texcoord : TEXCOORD0;
float4 worldPosition : TEXCOORD1;
#if UI_DISSOLVE || UI_TRANSITION
half3 eParam : TEXCOORD2;
#elif UI_SHINY
half2 eParam : TEXCOORD2;
#else
half eParam : TEXCOORD2;
#endif
#if EX
half4 uvMask : TEXCOORD3;
#endif
UNITY_VERTEX_OUTPUT_STEREO
};
v2f vert(appdata_t IN)
{
v2f OUT;
UNITY_SETUP_INSTANCE_ID(IN);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT);
OUT.worldPosition = IN.vertex;
OUT.vertex = UnityObjectToClipPos(OUT.worldPosition);
#if UI_EFFECT
OUT.texcoord = UnpackToVec2(IN.texcoord.x) * 2 - 0.5;
#else
OUT.texcoord = UnpackToVec2(IN.texcoord.x);
#endif
#ifdef UNITY_HALF_TEXEL_OFFSET
OUT.vertex.xy += (_ScreenParams.zw-1.0)*float2(-1,1);
#endif
OUT.color = IN.color * _Color;
#if UI_DISSOLVE || UI_TRANSITION
OUT.eParam = UnpackToVec3(IN.texcoord.y);
#elif UI_SHINY
OUT.eParam = UnpackToVec2(IN.texcoord.y);
#else
OUT.eParam = IN.texcoord.y;
#endif
#if EX
OUT.uvMask = half4(UnpackToVec2(IN.uvMask.x), UnpackToVec2(IN.uvMask.y));
#endif
return OUT;
}
#endif // UI_EFFECT_SPRITE_INCLUDED

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: dd60a36b172cf49e2b82258a68799ce3
timeCreated: 1487915863
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,79 @@
Shader "Hidden/UI/Default (UIHsvModifier)"
{
Properties
{
[PerRendererData] _MainTex ("Main Texture", 2D) = "white" {}
_Color ("Tint", Color) = (1,1,1,1)
_StencilComp ("Stencil Comparison", Float) = 8
_Stencil ("Stencil ID", Float) = 0
_StencilOp ("Stencil Operation", Float) = 0
_StencilWriteMask ("Stencil Write Mask", Float) = 255
_StencilReadMask ("Stencil Read Mask", Float) = 255
_ColorMask ("Color Mask", Float) = 15
[Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0
_ParamTex ("Parameter Texture", 2D) = "white" {}
}
SubShader
{
Tags
{
"Queue"="Transparent"
"IgnoreProjector"="True"
"RenderType"="Transparent"
"PreviewType"="Plane"
"CanUseSpriteAtlas"="True"
}
Stencil
{
Ref [_Stencil]
Comp [_StencilComp]
Pass [_StencilOp]
ReadMask [_StencilReadMask]
WriteMask [_StencilWriteMask]
}
Cull Off
Lighting Off
ZWrite Off
ZTest [unity_GUIZTestMode]
Blend SrcAlpha OneMinusSrcAlpha
ColorMask [_ColorMask]
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile __ UNITY_UI_ALPHACLIP
#include "UnityCG.cginc"
#include "UnityUI.cginc"
#define UI_HSV_MODIFIER 1
#include "UIEffect.cginc"
#include "UIEffectSprite.cginc"
fixed4 frag(v2f IN) : COLOR
{
half4 color = tex2D(_MainTex, IN.texcoord);// + _TextureSampleAdd) * IN.color;
color.a *= UnityGet2DClipping(IN.worldPosition.xy, _ClipRect);
#ifdef UNITY_UI_ALPHACLIP
clip (color.a - 0.001);
#endif
color = ApplyHsvEffect(color, IN.eParam);
return (color + _TextureSampleAdd) * IN.color;
}
ENDCG
}
}
}

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 7fc74090480c84f8b977cfcd55cdfe82
timeCreated: 1531882595
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,82 @@
Shader "Hidden/UI/Default (UIShiny)"
{
Properties
{
[PerRendererData] _MainTex ("Main Texture", 2D) = "white" {}
_Color ("Tint", Color) = (1,1,1,1)
_StencilComp ("Stencil Comparison", Float) = 8
_Stencil ("Stencil ID", Float) = 0
_StencilOp ("Stencil Operation", Float) = 0
_StencilWriteMask ("Stencil Write Mask", Float) = 255
_StencilReadMask ("Stencil Read Mask", Float) = 255
_ColorMask ("Color Mask", Float) = 15
[Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0
_ParamTex ("Parameter Texture", 2D) = "white" {}
}
SubShader
{
Tags
{
"Queue"="Transparent"
"IgnoreProjector"="True"
"RenderType"="Transparent"
"PreviewType"="Plane"
"CanUseSpriteAtlas"="True"
}
Stencil
{
Ref [_Stencil]
Comp [_StencilComp]
Pass [_StencilOp]
ReadMask [_StencilReadMask]
WriteMask [_StencilWriteMask]
}
Cull Off
Lighting Off
ZWrite Off
ZTest [unity_GUIZTestMode]
Blend SrcAlpha OneMinusSrcAlpha
ColorMask [_ColorMask]
Pass
{
Name "Default"
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 2.0
#pragma multi_compile __ UNITY_UI_ALPHACLIP
#include "UnityCG.cginc"
#include "UnityUI.cginc"
#define UI_SHINY 1
#include "UIEffect.cginc"
#include "UIEffectSprite.cginc"
fixed4 frag(v2f IN) : SV_Target
{
half4 color = (tex2D(_MainTex, IN.texcoord) + _TextureSampleAdd) * IN.color;
color.a *= UnityGet2DClipping(IN.worldPosition.xy, _ClipRect);
color = ApplyShinyEffect(color, IN.eParam);
#ifdef UNITY_UI_ALPHACLIP
clip (color.a - 0.001);
#endif
return color;
}
ENDCG
}
}
}

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 20ffe76c2439c403aabdd25bd94bf011
timeCreated: 1523859834
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,87 @@
Shader "Hidden/UI/Default (UITransition)"
{
Properties
{
[PerRendererData] _MainTex ("Main Texture", 2D) = "white" {}
_Color ("Tint", Color) = (1,1,1,1)
_StencilComp ("Stencil Comparison", Float) = 8
_Stencil ("Stencil ID", Float) = 0
_StencilOp ("Stencil Operation", Float) = 0
_StencilWriteMask ("Stencil Write Mask", Float) = 255
_StencilReadMask ("Stencil Read Mask", Float) = 255
_ColorMask ("Color Mask", Float) = 15
[Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0
[Header(Transition)]
_TransitionTex ("Transition Texture (A)", 2D) = "white" {}
_ParamTex ("Parameter Texture", 2D) = "white" {}
}
SubShader
{
Tags
{
"Queue"="Transparent"
"IgnoreProjector"="True"
"RenderType"="Transparent"
"PreviewType"="Plane"
"CanUseSpriteAtlas"="True"
}
Stencil
{
Ref [_Stencil]
Comp [_StencilComp]
Pass [_StencilOp]
ReadMask [_StencilReadMask]
WriteMask [_StencilWriteMask]
}
Cull Off
Lighting Off
ZWrite Off
ZTest [unity_GUIZTestMode]
Blend SrcAlpha OneMinusSrcAlpha
ColorMask [_ColorMask]
Pass
{
Name "Default"
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 2.0
#define REVERSE 1
#define ADD 1
#pragma multi_compile __ UNITY_UI_ALPHACLIP
#pragma multi_compile __ FADE CUTOFF DISSOLVE
#include "UnityCG.cginc"
#include "UnityUI.cginc"
#define UI_TRANSITION 1
#include "UIEffect.cginc"
#include "UIEffectSprite.cginc"
fixed4 frag(v2f IN) : SV_Target
{
half4 color = (tex2D(_MainTex, IN.texcoord) + _TextureSampleAdd);
color.a *= UnityGet2DClipping(IN.worldPosition.xy, _ClipRect);
color = ApplyTransitionEffect(color, IN.eParam) * IN.color;
#if UNITY_UI_ALPHACLIP
clip (color.a - 0.001);
#endif
return color;
}
ENDCG
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 85ad24dd0759947ddb117625e108d49c
timeCreated: 1548078121
licenseType: Pro
ShaderImporter:
defaultTextures:
- _MainTex: {instanceID: 0}
- _NoiseTex: {fileID: 2800000, guid: 3e04c247fb2604af186173fce0bc62de, type: 3}
- _ParamTex: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 04feaefc7cdee4c13abcd553a1a6e3a9
folderAsset: yes
timeCreated: 1528368324
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,192 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine.UI;
namespace Coffee.UIEffects
{
/// <summary>
/// Abstract effect base for UI.
/// </summary>
[DisallowMultipleComponent]
public abstract class BaseMaterialEffect : BaseMeshEffect, IParameterTexture, IMaterialModifier
{
protected static readonly Hash128 k_InvalidHash = new Hash128();
protected static readonly List<UIVertex> s_TempVerts = new List<UIVertex>();
private static readonly StringBuilder s_StringBuilder = new StringBuilder();
Hash128 _effectMaterialHash;
/// <summary>
/// Gets or sets the parameter index.
/// </summary>
public int parameterIndex { get; set; }
/// <summary>
/// Gets the parameter texture.
/// </summary>
public virtual ParameterTexture paramTex
{
get { return null; }
}
/// <summary>
/// Mark the vertices as dirty.
/// </summary>
public void SetMaterialDirty()
{
this.connector.SetMaterialDirty(this.graphic);
foreach (var effect in this.syncEffects)
{
effect.SetMaterialDirty();
}
}
public virtual Hash128 GetMaterialHash(Material baseMaterial)
{
return k_InvalidHash;
}
public Material GetModifiedMaterial(Material baseMaterial)
{
return GetModifiedMaterial(baseMaterial, this.graphic);
}
public virtual Material GetModifiedMaterial(Material baseMaterial, Graphic graphic)
{
if (!this.isActiveAndEnabled) return baseMaterial;
var oldHash = this._effectMaterialHash;
this._effectMaterialHash = GetMaterialHash(baseMaterial);
var modifiedMaterial = baseMaterial;
if (this._effectMaterialHash.isValid)
{
modifiedMaterial = MaterialCache.Register(baseMaterial, this._effectMaterialHash, ModifyMaterial, graphic);
}
MaterialCache.Unregister(oldHash);
return modifiedMaterial;
}
// protected bool isTMProMobile (Material material)
// {
// return material && material.shader && material.shader.name.StartsWith ("TextMeshPro/Mobile/", StringComparison.Ordinal);
// }
public virtual void ModifyMaterial(Material newMaterial, Graphic graphic)
{
if (this.isActiveAndEnabled && this.paramTex != null) this.paramTex.RegisterMaterial(newMaterial);
}
protected void SetShaderVariants(Material newMaterial, params object[] variants)
{
// Set shader keywords as variants
var keywords = variants.Where(x => 0 < (int) x)
.Select(x => x.ToString().ToUpper())
.Concat(newMaterial.shaderKeywords)
.Distinct()
.ToArray();
newMaterial.shaderKeywords = keywords;
// Add variant name
s_StringBuilder.Length = 0;
s_StringBuilder.Append(Path.GetFileName(newMaterial.shader.name));
foreach (var keyword in keywords)
{
s_StringBuilder.Append("-");
s_StringBuilder.Append(keyword);
}
newMaterial.name = s_StringBuilder.ToString();
}
#if UNITY_EDITOR
protected override void Reset()
{
if (!this.isActiveAndEnabled) return;
SetMaterialDirty();
SetVerticesDirty();
SetEffectParamsDirty();
}
protected override void OnValidate()
{
if (!this.isActiveAndEnabled) return;
SetVerticesDirty();
SetEffectParamsDirty();
}
#endif
/// <summary>
/// This function is called when the object becomes enabled and active.
/// </summary>
protected override void OnEnable()
{
base.OnEnable();
if (this.paramTex != null)
{
this.paramTex.Register(this);
}
SetMaterialDirty();
SetEffectParamsDirty();
// foreach (var mr in GetComponentsInChildren<UIEffectMaterialResolver> ())
// {
// mr.GetComponent<Graphic> ().SetMaterialDirty ();
// mr.GetComponent<Graphic> ().SetVerticesDirty ();
// }
}
/// <summary>
/// This function is called when the behaviour becomes disabled () or inactive.
/// </summary>
protected override void OnDisable()
{
base.OnDisable();
SetMaterialDirty();
if (this.paramTex != null)
{
this.paramTex.Unregister(this);
}
MaterialCache.Unregister(this._effectMaterialHash);
this._effectMaterialHash = k_InvalidHash;
}
// protected override void OnDidApplyAnimationProperties()
// {
// SetEffectParamsDirty();
// }
// protected override void OnTextChanged (UnityEngine.Object obj)
// {
// base.OnTextChanged (obj);
//
//
// foreach (var sm in GetComponentsInChildren<TMPro.TMP_SubMeshUI> ())
// {
// if(!sm.GetComponent<UIEffectMaterialResolver>())
// {
// var mr = sm.gameObject.AddComponent<UIEffectMaterialResolver> ();
//
// targetGraphic.SetAllDirty ();
// //targetGraphic.SetVerticesDirty ();
//
// //mr.GetComponent<Graphic> ().SetMaterialDirty ();
// //mr.GetComponent<Graphic> ().SetVerticesDirty ();
//
//
// }
// }
// }
}
}

View File

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

View File

@@ -0,0 +1,229 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
namespace Coffee.UIEffects
{
/// <summary>
/// Base class for effects that modify the generated Mesh.
/// It works well not only for standard Graphic components (Image, RawImage, Text, etc.) but also for TextMeshPro and TextMeshProUGUI.
/// </summary>
[RequireComponent(typeof(Graphic))]
[RequireComponent(typeof(RectTransform))]
[ExecuteInEditMode]
public abstract class BaseMeshEffect : UIBehaviour, IMeshModifier
{
RectTransform _rectTransform;
Graphic _graphic;
GraphicConnector _connector;
/// <summary>
/// The Graphic attached to this GameObject.
/// </summary>
protected GraphicConnector connector
{
get { return this._connector ?? (this._connector = GraphicConnector.FindConnector(this.graphic)); }
}
/// <summary>
/// The Graphic attached to this GameObject.
/// </summary>
public Graphic graphic
{
get { return this._graphic ? this._graphic : this._graphic = GetComponent<Graphic>(); }
}
/// <summary>
/// The RectTransform attached to this GameObject.
/// </summary>
protected RectTransform rectTransform
{
get { return this._rectTransform ? this._rectTransform : this._rectTransform = GetComponent<RectTransform>(); }
}
internal readonly List<UISyncEffect> syncEffects = new List<UISyncEffect>(0);
/// <summary>
/// Call used to modify mesh. (legacy)
/// </summary>
/// <param name="mesh">Mesh.</param>
public virtual void ModifyMesh(Mesh mesh)
{
}
/// <summary>
/// Call used to modify mesh.
/// </summary>
/// <param name="vh">VertexHelper.</param>
public virtual void ModifyMesh(VertexHelper vh)
{
ModifyMesh(vh, this.graphic);
}
public virtual void ModifyMesh(VertexHelper vh, Graphic graphic)
{
}
/// <summary>
/// Mark the vertices as dirty.
/// </summary>
protected virtual void SetVerticesDirty()
{
this.connector.SetVerticesDirty(this.graphic);
foreach (var effect in this.syncEffects)
{
effect.SetVerticesDirty();
}
// #if TMP_PRESENT
// if (textMeshPro)
// {
// foreach (var info in textMeshPro.textInfo.meshInfo)
// {
// var mesh = info.mesh;
// if (mesh)
// {
// mesh.Clear();
// mesh.vertices = info.vertices;
// mesh.uv = info.uvs0;
// mesh.uv2 = info.uvs2;
// mesh.colors32 = info.colors32;
// mesh.normals = info.normals;
// mesh.tangents = info.tangents;
// mesh.triangles = info.triangles;
// }
// }
//
// if (canvasRenderer)
// {
// canvasRenderer.SetMesh(textMeshPro.mesh);
//
// GetComponentsInChildren(false, s_SubMeshUIs);
// foreach (var sm in s_SubMeshUIs)
// {
// sm.canvasRenderer.SetMesh(sm.mesh);
// }
//
// s_SubMeshUIs.Clear();
// }
//
// textMeshPro.havePropertiesChanged = true;
// }
// else
// #endif
// if (graphic)
// {
// graphic.SetVerticesDirty();
// }
}
//################################
// Protected Members.
//################################
/// <summary>
/// Should the effect modify the mesh directly for TMPro?
/// </summary>
// protected virtual bool isLegacyMeshModifier
// {
// get { return false; }
// }
// protected virtual void Initialize()
// {
// if (_initialized) return;
//
// _initialized = true;
// _graphic = _graphic ? _graphic : GetComponent<Graphic>();
//
// _connector = GraphicConnector.FindConnector(_graphic);
//
// // _canvasRenderer = _canvasRenderer ?? GetComponent<CanvasRenderer> ();
// _rectTransform = _rectTransform ? _rectTransform : GetComponent<RectTransform>();
// // #if TMP_PRESENT
// // _textMeshPro = _textMeshPro ?? GetComponent<TMP_Text> ();
// // #endif
// }
/// <summary>
/// This function is called when the object becomes enabled and active.
/// </summary>
protected override void OnEnable()
{
this.connector.OnEnable(this.graphic);
SetVerticesDirty();
// SetVerticesDirty();
// #if TMP_PRESENT
// if (textMeshPro)
// {
// TMPro_EventManager.TEXT_CHANGED_EVENT.Add (OnTextChanged);
// }
// #endif
//
// #if UNITY_EDITOR && TMP_PRESENT
// if (graphic && textMeshPro)
// {
// GraphicRebuildTracker.TrackGraphic (graphic);
// }
// #endif
//
// #if UNITY_5_6_OR_NEWER
// if (graphic)
// {
// AdditionalCanvasShaderChannels channels = requiredChannels;
// var canvas = graphic.canvas;
// if (canvas && (canvas.additionalShaderChannels & channels) != channels)
// {
// Debug.LogWarningFormat (this, "Enable {1} of Canvas.additionalShaderChannels to use {0}.", GetType ().Name, channels);
// }
// }
// #endif
}
/// <summary>
/// This function is called when the behaviour becomes disabled () or inactive.
/// </summary>
protected override void OnDisable()
{
this.connector.OnDisable(this.graphic);
SetVerticesDirty();
}
/// <summary>
/// Mark the effect parameters as dirty.
/// </summary>
protected virtual void SetEffectParamsDirty()
{
if (!this.isActiveAndEnabled) return;
SetVerticesDirty();
}
/// <summary>
/// Callback for when properties have been changed by animation.
/// </summary>
protected override void OnDidApplyAnimationProperties()
{
if (!this.isActiveAndEnabled) return;
SetEffectParamsDirty();
}
#if UNITY_EDITOR
protected override void Reset()
{
if (!this.isActiveAndEnabled) return;
SetVerticesDirty();
}
/// <summary>
/// This function is called when the script is loaded or a value is changed in the inspector (Called in the editor only).
/// </summary>
protected override void OnValidate()
{
if (!this.isActiveAndEnabled) return;
SetEffectParamsDirty();
}
#endif
}
}

View File

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

View File

@@ -0,0 +1,154 @@
using UnityEngine;
using System;
using System.Collections.Generic;
namespace Coffee.UIEffects
{
/// <summary>
/// Effect player.
/// </summary>
[Serializable]
public class EffectPlayer
{
//################################
// Public Members.
//################################
/// <summary>
/// Gets or sets a value indicating whether is playing.
/// </summary>
[Header("Effect Player")] [Tooltip("Playing.")]
public bool play = false;
/// <summary>
/// Gets or sets the delay before looping.
/// </summary>
[Tooltip("Initial play delay.")] [Range(0f, 10f)]
public float initialPlayDelay = 0;
/// <summary>
/// Gets or sets the duration.
/// </summary>
[Tooltip("Duration.")] [Range(0.01f, 10f)]
public float duration = 1;
/// <summary>
/// Gets or sets a value indicating whether can loop.
/// </summary>
[Tooltip("Loop.")] public bool loop = false;
/// <summary>
/// Gets or sets the delay before looping.
/// </summary>
[Tooltip("Delay before looping.")] [Range(0f, 10f)]
public float loopDelay = 0;
/// <summary>
/// Gets or sets the update mode.
/// </summary>
[Tooltip("Update mode")] public AnimatorUpdateMode updateMode = AnimatorUpdateMode.Normal;
static List<Action> s_UpdateActions;
/// <summary>
/// Register player.
/// </summary>
public void OnEnable(Action<float> callback = null)
{
if (s_UpdateActions == null)
{
s_UpdateActions = new List<Action>();
Canvas.willRenderCanvases += () =>
{
var count = s_UpdateActions.Count;
for (int i = 0; i < count; i++)
{
s_UpdateActions[i].Invoke();
}
};
}
s_UpdateActions.Add(OnWillRenderCanvases);
if (this.play)
{
this._time = -this.initialPlayDelay;
}
else
{
this._time = 0;
}
this._callback = callback;
}
/// <summary>
/// Unregister player.
/// </summary>
public void OnDisable()
{
this._callback = null;
s_UpdateActions.Remove(OnWillRenderCanvases);
}
/// <summary>
/// Start playing.
/// </summary>
public void Play(bool reset, Action<float> callback = null)
{
if (reset)
{
this._time = 0;
}
this.play = true;
if (callback != null)
{
this._callback = callback;
}
}
/// <summary>
/// Stop playing.
/// </summary>
public void Stop(bool reset)
{
if (reset)
{
this._time = 0;
if (this._callback != null)
{
this._callback(this._time);
}
}
this.play = false;
}
//################################
// Private Members.
//################################
float _time = 0;
Action<float> _callback;
void OnWillRenderCanvases()
{
if (!this.play || !Application.isPlaying || this._callback == null)
{
return;
}
this._time += this.updateMode == AnimatorUpdateMode.UnscaledTime
? Time.unscaledDeltaTime
: Time.deltaTime;
var current = this._time / this.duration;
if (this.duration <= this._time)
{
this.play = this.loop;
this._time = this.loop ? -this.loopDelay : 0;
}
this._callback(current);
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 1656fb67110cd44298010d95c324e87a
timeCreated: 1528296875
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,151 @@
using UnityEngine;
using UnityEngine.UI;
using System;
using System.Collections.Generic;
namespace Coffee.UIEffects
{
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>
/// Extra channel.
/// </summary>
public virtual AdditionalCanvasShaderChannels extraChannel
{
get { return AdditionalCanvasShaderChannels.TexCoord1; }
}
/// <summary>
/// The connector is valid for the component.
/// </summary>
protected virtual bool IsValid(Graphic graphic)
{
return true;
}
/// <summary>
/// Find effect shader.
/// </summary>
public virtual Shader FindShader(string shaderName)
{
return Shader.Find("Hidden/" + shaderName);
}
/// <summary>
/// This function is called when the object becomes enabled and active.
/// </summary>
public virtual void OnEnable(Graphic graphic)
{
}
/// <summary>
/// This function is called when the behaviour becomes disabled () or inactive.
/// </summary>
public virtual void OnDisable(Graphic graphic)
{
}
/// <summary>
/// Mark the vertices as dirty.
/// </summary>
public virtual void SetVerticesDirty(Graphic graphic)
{
if (graphic)
graphic.SetVerticesDirty();
}
/// <summary>
/// Mark the material as dirty.
/// </summary>
public virtual void SetMaterialDirty(Graphic graphic)
{
if (graphic)
graphic.SetMaterialDirty();
}
/// <summary>
/// Gets position factor for area.
/// </summary>
public virtual void GetPositionFactor(EffectArea area, int index, Rect rect, Vector2 position, out float x, out float y)
{
if (area == EffectArea.Fit)
{
x = Mathf.Clamp01((position.x - rect.xMin) / rect.width);
y = Mathf.Clamp01((position.y - rect.yMin) / rect.height);
}
else
{
x = Mathf.Clamp01(position.x / rect.width + 0.5f);
y = Mathf.Clamp01(position.y / rect.height + 0.5f);
}
}
public virtual bool IsText(Graphic graphic)
{
return graphic && graphic is Text;
}
public virtual void SetExtraChannel(ref UIVertex vertex, Vector2 value)
{
vertex.uv1 = value;
}
/// <summary>
/// Normalize vertex position by local matrix.
/// </summary>
public virtual void GetNormalizedFactor(EffectArea area, int index, Matrix2x3 matrix, Vector2 position,
out Vector2 normalizedPos)
{
normalizedPos = matrix * position;
}
}
}

View File

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

View File

@@ -0,0 +1,77 @@
using System.Collections.Generic;
using System.Linq;
using System;
using UnityEngine;
using System.Text;
using UnityEngine.UI;
namespace Coffee.UIEffects
{
public class MaterialCache
{
static Dictionary<Hash128, MaterialEntry> materialMap = new Dictionary<Hash128, MaterialEntry>();
private class MaterialEntry
{
public Material material;
public int referenceCount;
public void Release()
{
if (this.material)
{
UnityEngine.Object.DestroyImmediate(this.material, false);
}
this.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 baseMaterial, Hash128 hash,
Action<Material, Graphic> onModifyMaterial, Graphic graphic)
{
if (!hash.isValid) return null;
MaterialEntry entry;
if (!materialMap.TryGetValue(hash, out entry))
{
entry = new MaterialEntry()
{
material = new Material(baseMaterial)
{
hideFlags = HideFlags.HideAndDontSave,
},
};
onModifyMaterial(entry.material, graphic);
materialMap.Add(hash, entry);
}
entry.referenceCount++;
return entry.material;
}
public static void Unregister(Hash128 hash)
{
MaterialEntry entry;
if (!hash.isValid || !materialMap.TryGetValue(hash, out entry)) return;
if (--entry.referenceCount > 0) return;
entry.Release();
materialMap.Remove(hash);
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 2160d2c55a6100642b6c7ba09df935da
timeCreated: 1528509206
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,33 @@
using UnityEngine;
namespace Coffee.UIEffects
{
/// <summary>
/// Matrix2x3.
/// </summary>
public struct Matrix2x3
{
public float m00, m01, m02, m10, m11, m12;
public Matrix2x3(Rect rect, float cos, float sin)
{
const float center = 0.5f;
float dx = -rect.xMin / rect.width - center;
float dy = -rect.yMin / rect.height - center;
this.m00 = cos / rect.width;
this.m01 = -sin / rect.height;
this.m02 = dx * cos - dy * sin + center;
this.m10 = sin / rect.width;
this.m11 = cos / rect.height;
this.m12 = dx * sin + dy * cos + center;
}
public static Vector2 operator *(Matrix2x3 m, Vector2 v)
{
return new Vector2(
(m.m00 * v.x) + (m.m01 * v.y) + m.m02,
(m.m10 * v.x) + (m.m11 * v.y) + m.m12
);
}
}
}

View File

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

View File

@@ -0,0 +1,61 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public static class Packer
{
/// <summary>
/// Pack 4 low-precision [0-1] floats values to a float.
/// Each value [0-1] has 64 steps(6 bits).
/// </summary>
public static float ToFloat(float x, float y, float z, float w)
{
x = x < 0 ? 0 : 1 < x ? 1 : x;
y = y < 0 ? 0 : 1 < y ? 1 : y;
z = z < 0 ? 0 : 1 < z ? 1 : z;
w = w < 0 ? 0 : 1 < w ? 1 : w;
const int PRECISION = (1 << 6) - 1;
return (Mathf.FloorToInt(w * PRECISION) << 18)
+ (Mathf.FloorToInt(z * PRECISION) << 12)
+ (Mathf.FloorToInt(y * PRECISION) << 6)
+ Mathf.FloorToInt(x * PRECISION);
}
/// <summary>
/// Pack 4 low-precision [0-1] floats values to a float.
/// Each value [0-1] has 64 steps(6 bits).
/// </summary>
public static float ToFloat(Vector4 factor)
{
return ToFloat(Mathf.Clamp01(factor.x), Mathf.Clamp01(factor.y), Mathf.Clamp01(factor.z),
Mathf.Clamp01(factor.w));
}
/// <summary>
/// Pack 1 middle-precision & 2 low-precision [0-1] floats values to a float.
/// z value [0-1] has 4096 steps(12 bits) and xy value [0-1] has 64 steps(6 bits).
/// </summary>
public static float ToFloat(float x, float y, float z)
{
x = x < 0 ? 0 : 1 < x ? 1 : x;
y = y < 0 ? 0 : 1 < y ? 1 : y;
z = z < 0 ? 0 : 1 < z ? 1 : z;
const int PRECISION = (1 << 8) - 1;
return (Mathf.FloorToInt(z * PRECISION) << 16)
+ (Mathf.FloorToInt(y * PRECISION) << 8)
+ Mathf.FloorToInt(x * PRECISION);
}
/// <summary>
/// Pack 2 low-precision [0-1] floats values to a float.
/// Each value [0-1] has 4096 steps(12 bits).
/// </summary>
public static float ToFloat(float x, float y)
{
x = x < 0 ? 0 : 1 < x ? 1 : x;
y = y < 0 ? 0 : 1 < y ? 1 : y;
const int PRECISION = (1 << 12) - 1;
return (Mathf.FloorToInt(y * PRECISION) << 12)
+ Mathf.FloorToInt(x * PRECISION);
}
}

View File

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

View File

@@ -0,0 +1,190 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
using System;
namespace Coffee.UIEffects
{
public interface IParameterTexture
{
int parameterIndex { get; set; }
ParameterTexture paramTex { get; }
}
/// <summary>
/// Parameter texture.
/// </summary>
[Serializable]
public class ParameterTexture
{
//################################
// Public Members.
//################################
/// <summary>
/// Initializes a new instance of the <see cref="Coffee.UIEffects.ParameterTexture"/> class.
/// </summary>
/// <param name="channels">Channels.</param>
/// <param name="instanceLimit">Instance limit.</param>
/// <param name="propertyName">Property name.</param>
public ParameterTexture(int channels, int instanceLimit, string propertyName)
{
this._propertyName = propertyName;
this._channels = ((channels - 1) / 4 + 1) * 4;
this._instanceLimit = ((instanceLimit - 1) / 2 + 1) * 2;
this._data = new byte[this._channels * this._instanceLimit];
this._stack = new Stack<int>(this._instanceLimit);
for (int i = 1; i < this._instanceLimit + 1; i++)
{
this._stack.Push(i);
}
}
/// <summary>
/// Register the specified target.
/// </summary>
/// <param name="target">Target.</param>
public void Register(IParameterTexture target)
{
Initialize();
if (target.parameterIndex <= 0 && 0 < this._stack.Count)
{
target.parameterIndex = this._stack.Pop();
// Debug.LogFormat("<color=green>@@@ Register {0} : {1}</color>", target, target.parameterIndex);
}
}
/// <summary>
/// Unregister the specified target.
/// </summary>
/// <param name="target">Target.</param>
public void Unregister(IParameterTexture target)
{
if (0 < target.parameterIndex)
{
// Debug.LogFormat("<color=red>@@@ Unregister {0} : {1}</color>", target, target.parameterIndex);
this._stack.Push(target.parameterIndex);
target.parameterIndex = 0;
}
}
/// <summary>
/// Sets the data.
/// </summary>
/// <param name="target">Target.</param>
/// <param name="channelId">Channel identifier.</param>
/// <param name="value">Value.</param>
public void SetData(IParameterTexture target, int channelId, byte value)
{
int index = (target.parameterIndex - 1) * this._channels + channelId;
if (0 < target.parameterIndex && this._data[index] != value)
{
this._data[index] = value;
this._needUpload = true;
}
}
/// <summary>
/// Sets the data.
/// </summary>
/// <param name="target">Target.</param>
/// <param name="channelId">Channel identifier.</param>
/// <param name="value">Value.</param>
public void SetData(IParameterTexture target, int channelId, float value)
{
SetData(target, channelId, (byte) (Mathf.Clamp01(value) * 255));
}
/// <summary>
/// Registers the material.
/// </summary>
/// <param name="mat">Mat.</param>
public void RegisterMaterial(Material mat)
{
if (this._propertyId == 0)
{
this._propertyId = Shader.PropertyToID(this._propertyName);
}
if (mat)
{
mat.SetTexture(this._propertyId, this._texture);
}
}
/// <summary>
/// Gets the index of the normalized.
/// </summary>
/// <returns>The normalized index.</returns>
/// <param name="target">Target.</param>
public float GetNormalizedIndex(IParameterTexture target)
{
return ((float) target.parameterIndex - 0.5f) / this._instanceLimit;
}
//################################
// Private Members.
//################################
Texture2D _texture;
bool _needUpload;
int _propertyId;
readonly string _propertyName;
readonly int _channels;
readonly int _instanceLimit;
readonly byte[] _data;
readonly Stack<int> _stack;
static List<Action> updates;
/// <summary>
/// Initialize this instance.
/// </summary>
void Initialize()
{
#if UNITY_EDITOR
if (!UnityEditor.EditorApplication.isPlaying && UnityEditor.EditorApplication.isPlayingOrWillChangePlaymode)
{
return;
}
#endif
if (updates == null)
{
updates = new List<Action>();
Canvas.willRenderCanvases += () =>
{
var count = updates.Count;
for (int i = 0; i < count; i++)
{
updates[i].Invoke();
}
};
}
if (!this._texture)
{
bool isLinear = QualitySettings.activeColorSpace == ColorSpace.Linear;
this._texture = new Texture2D(this._channels / 4, this._instanceLimit, TextureFormat.RGBA32, false, isLinear);
this._texture.filterMode = FilterMode.Point;
this._texture.wrapMode = TextureWrapMode.Clamp;
updates.Add(UpdateParameterTexture);
this._needUpload = true;
}
}
void UpdateParameterTexture()
{
if (this._needUpload && this._texture)
{
this._needUpload = false;
this._texture.LoadRawTextureData(this._data);
this._texture.Apply(false, false);
}
}
}
}

View File

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

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,33 @@
using System.Linq;
using UnityEditor;
using UnityEngine;
namespace Coffee.UIEffects.Editors
{
/// <summary>
/// Changes in this scope cause the graphic's material to be dirty.
/// When you change a property, it marks the material as dirty.
/// </summary>
internal class MaterialDirtyScope : EditorGUI.ChangeCheckScope
{
readonly Object[] targets;
public MaterialDirtyScope(Object[] targets)
{
this.targets = targets;
}
protected override void CloseScope()
{
if (changed)
{
foreach (var effect in targets.OfType<BaseMaterialEffect>())
{
effect.SetMaterialDirty();
}
}
base.CloseScope();
}
}
}

View File

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

View File

@@ -0,0 +1,121 @@
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;
using System.Linq;
using System.Collections.Generic;
using UnityEngine.UI;
namespace Coffee.UIEffects.Editors
{
/// <summary>
/// UIEffect editor.
/// </summary>
[CustomEditor(typeof(UIDissolve))]
[CanEditMultipleObjects]
public class UIDissolveEditor : UnityEditor.Editor
{
SerializedProperty _spEffectFactor;
SerializedProperty _spWidth;
SerializedProperty _spColor;
SerializedProperty _spSoftness;
SerializedProperty _spColorMode;
SerializedProperty _spTransitionTexture;
SerializedProperty _spEffectArea;
SerializedProperty _spKeepAspectRatio;
SerializedProperty _spReverse;
SerializedProperty _spPlay;
SerializedProperty _spLoop;
SerializedProperty _spLoopDelay;
SerializedProperty _spDuration;
SerializedProperty _spInitialPlayDelay;
SerializedProperty _spUpdateMode;
//################################
// Public/Protected Members.
//################################
/// <summary>
/// This function is called when the object becomes enabled and active.
/// </summary>
protected void OnEnable()
{
_spEffectFactor = serializedObject.FindProperty("m_EffectFactor");
_spEffectArea = serializedObject.FindProperty("m_EffectArea");
_spKeepAspectRatio = serializedObject.FindProperty("m_KeepAspectRatio");
_spWidth = serializedObject.FindProperty("m_Width");
_spColor = serializedObject.FindProperty("m_Color");
_spSoftness = serializedObject.FindProperty("m_Softness");
_spColorMode = serializedObject.FindProperty("m_ColorMode");
_spTransitionTexture = serializedObject.FindProperty("m_TransitionTexture");
_spKeepAspectRatio = serializedObject.FindProperty("m_KeepAspectRatio");
_spReverse = serializedObject.FindProperty("m_Reverse");
var player = serializedObject.FindProperty("m_Player");
_spPlay = player.FindPropertyRelative("play");
_spDuration = player.FindPropertyRelative("duration");
_spInitialPlayDelay = player.FindPropertyRelative("initialPlayDelay");
_spLoop = player.FindPropertyRelative("loop");
_spLoopDelay = player.FindPropertyRelative("loopDelay");
_spUpdateMode = player.FindPropertyRelative("updateMode");
}
/// <summary>
/// Implement this function to make a custom inspector.
/// </summary>
public override void OnInspectorGUI()
{
serializedObject.Update();
//================
// Effect setting.
//================
EditorGUILayout.PropertyField(_spEffectFactor);
EditorGUILayout.PropertyField(_spWidth);
EditorGUILayout.PropertyField(_spSoftness);
EditorGUILayout.PropertyField(_spColor);
using (new MaterialDirtyScope(targets))
{
EditorGUILayout.PropertyField(_spColorMode);
EditorGUILayout.PropertyField(_spTransitionTexture);
}
//================
// Advanced option.
//================
EditorGUILayout.PropertyField(_spEffectArea);
EditorGUILayout.PropertyField(_spKeepAspectRatio);
//================
// Effect player.
//================
EditorGUILayout.PropertyField(_spPlay);
EditorGUILayout.PropertyField(_spDuration);
EditorGUILayout.PropertyField(_spInitialPlayDelay);
EditorGUILayout.PropertyField(_spLoop);
EditorGUILayout.PropertyField(_spLoopDelay);
EditorGUILayout.PropertyField(_spUpdateMode);
EditorGUILayout.PropertyField(_spReverse);
// Debug.
using (new EditorGUI.DisabledGroupScope(!Application.isPlaying))
using (new EditorGUILayout.HorizontalScope(EditorStyles.helpBox))
{
GUILayout.Label("Debug");
if (GUILayout.Button("Play", "ButtonLeft"))
{
(target as UIDissolve).Play();
}
if (GUILayout.Button("Stop", "ButtonRight"))
{
(target as UIDissolve).Stop();
}
}
serializedObject.ApplyModifiedProperties();
}
}
}

View File

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

View File

@@ -0,0 +1,114 @@
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;
using System.Linq;
using System;
namespace Coffee.UIEffects.Editors
{
/// <summary>
/// UIEffect editor.
/// </summary>
[CustomEditor(typeof(UIEffect))]
[CanEditMultipleObjects]
public class UIEffectEditor : UnityEditor.Editor
{
SerializedProperty _spEffectMode;
SerializedProperty _spEffectFactor;
SerializedProperty _spColorMode;
SerializedProperty _spColorFactor;
SerializedProperty _spBlurMode;
SerializedProperty _spBlurFactor;
SerializedProperty _spAdvancedBlur;
protected void OnEnable()
{
_spEffectMode = serializedObject.FindProperty("m_EffectMode");
_spEffectFactor = serializedObject.FindProperty("m_EffectFactor");
_spColorMode = serializedObject.FindProperty("m_ColorMode");
_spColorFactor = serializedObject.FindProperty("m_ColorFactor");
_spBlurMode = serializedObject.FindProperty("m_BlurMode");
_spBlurFactor = serializedObject.FindProperty("m_BlurFactor");
_spAdvancedBlur = serializedObject.FindProperty("m_AdvancedBlur");
}
public override void OnInspectorGUI()
{
//================
// Effect setting.
//================
using (new MaterialDirtyScope(targets))
EditorGUILayout.PropertyField(_spEffectMode);
// When effect is enable, show parameters.
if (_spEffectMode.intValue != (int) EffectMode.None)
{
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(_spEffectFactor);
EditorGUI.indentLevel--;
}
//================
// Color setting.
//================
using (new MaterialDirtyScope(targets))
EditorGUILayout.PropertyField(_spColorMode);
// When color is enable, show parameters.
{
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(_spColorFactor);
EditorGUI.indentLevel--;
}
//================
// Blur setting.
//================
using (new MaterialDirtyScope(targets))
EditorGUILayout.PropertyField(_spBlurMode);
// When blur is enable, show parameters.
if (_spBlurMode.intValue != (int) BlurMode.None)
{
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(_spBlurFactor);
// When you change a property, it marks the material as dirty.
using (new MaterialDirtyScope(targets))
EditorGUILayout.PropertyField(_spAdvancedBlur);
EditorGUI.indentLevel--;
// Advanced blur requires uv2 channel.
if (_spAdvancedBlur.boolValue)
{
ShowCanvasChannelsWarning();
}
}
serializedObject.ApplyModifiedProperties();
}
void ShowCanvasChannelsWarning()
{
var effect = target as UIEffect;
if (effect == null || !effect.graphic) return;
var channel = effect.uvMaskChannel;
var canvas = effect.graphic.canvas;
if (canvas == null || (canvas.additionalShaderChannels & channel) == channel) return;
EditorGUILayout.BeginHorizontal();
{
var msg = string.Format("Enable '{0}' of Canvas.additionalShaderChannels to use 'UIEffect'.", channel);
EditorGUILayout.HelpBox(msg, MessageType.Warning);
if (GUILayout.Button("Fix"))
{
canvas.additionalShaderChannels |= channel;
}
}
EditorGUILayout.EndHorizontal();
}
}
}

View File

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

View File

@@ -0,0 +1,140 @@
using UnityEditor;
using UnityEngine;
using UnityEngine.UI;
namespace Coffee.UIEffects.Editors
{
/// <summary>
/// UIEffect editor.
/// </summary>
[CustomEditor(typeof(UIGradient))]
[CanEditMultipleObjects]
public class UIGradientEditor : UnityEditor.Editor
{
private static readonly GUIContent k_TextVerticalOffset = new GUIContent("Vertical Offset");
private static readonly GUIContent k_TextHorizontalOffset = new GUIContent("Horizontal Offset");
private static readonly GUIContent k_TextOffset = new GUIContent("Offset");
private static readonly GUIContent k_TextLeft = new GUIContent("Left");
private static readonly GUIContent k_TextRight = new GUIContent("Right");
private static readonly GUIContent k_TextTop = new GUIContent("Top");
private static readonly GUIContent k_TextBottom = new GUIContent("Bottom");
private static readonly GUIContent k_TextColor1 = new GUIContent("Color 1");
private static readonly GUIContent k_TextColor2 = new GUIContent("Color 2");
private static readonly GUIContent k_TextDiagonalColor = new GUIContent("Diagonal Color");
SerializedProperty _spDirection;
SerializedProperty _spColor1;
SerializedProperty _spColor2;
SerializedProperty _spColor3;
SerializedProperty _spColor4;
SerializedProperty _spRotation;
SerializedProperty _spOffset1;
SerializedProperty _spOffset2;
SerializedProperty _spIgnoreAspectRatio;
SerializedProperty _spGradientStyle;
SerializedProperty _spColorSpace;
//################################
// Public/Protected Members.
//################################
/// <summary>
/// This function is called when the object becomes enabled and active.
/// </summary>
protected void OnEnable()
{
_spIgnoreAspectRatio = serializedObject.FindProperty("m_IgnoreAspectRatio");
_spDirection = serializedObject.FindProperty("m_Direction");
_spColor1 = serializedObject.FindProperty("m_Color1");
_spColor2 = serializedObject.FindProperty("m_Color2");
_spColor3 = serializedObject.FindProperty("m_Color3");
_spColor4 = serializedObject.FindProperty("m_Color4");
_spRotation = serializedObject.FindProperty("m_Rotation");
_spOffset1 = serializedObject.FindProperty("m_Offset1");
_spOffset2 = serializedObject.FindProperty("m_Offset2");
_spGradientStyle = serializedObject.FindProperty("m_GradientStyle");
_spColorSpace = serializedObject.FindProperty("m_ColorSpace");
}
public override void OnInspectorGUI()
{
serializedObject.Update();
//================
// Direction.
//================
EditorGUILayout.PropertyField(_spDirection);
//================
// Color.
//================
switch ((UIGradient.Direction) _spDirection.intValue)
{
case UIGradient.Direction.Horizontal:
EditorGUILayout.PropertyField(_spColor1, k_TextLeft);
EditorGUILayout.PropertyField(_spColor2, k_TextRight);
break;
case UIGradient.Direction.Vertical:
EditorGUILayout.PropertyField(_spColor1, k_TextTop);
EditorGUILayout.PropertyField(_spColor2, k_TextBottom);
break;
case UIGradient.Direction.Angle:
EditorGUILayout.PropertyField(_spColor1, k_TextColor1);
EditorGUILayout.PropertyField(_spColor2, k_TextColor2);
break;
case UIGradient.Direction.Diagonal:
Rect r = EditorGUILayout.GetControlRect(false, 34);
r = EditorGUI.PrefixLabel(r, k_TextDiagonalColor);
float w = r.width / 2;
EditorGUI.PropertyField(new Rect(r.x, r.y, w, 16), _spColor3, GUIContent.none);
EditorGUI.PropertyField(new Rect(r.x + w, r.y, w, 16), _spColor4, GUIContent.none);
EditorGUI.PropertyField(new Rect(r.x, r.y + 18, w, 16), _spColor1, GUIContent.none);
EditorGUI.PropertyField(new Rect(r.x + w, r.y + 18, w, 16), _spColor2, GUIContent.none);
break;
}
//================
// Angle.
//================
if ((int) UIGradient.Direction.Angle <= _spDirection.intValue)
{
EditorGUILayout.PropertyField(_spRotation);
}
//================
// Offset.
//================
if ((int) UIGradient.Direction.Diagonal == _spDirection.intValue)
{
EditorGUILayout.PropertyField(_spOffset1, k_TextVerticalOffset);
EditorGUILayout.PropertyField(_spOffset2, k_TextHorizontalOffset);
}
else
{
EditorGUILayout.PropertyField(_spOffset1, k_TextOffset);
}
//================
// Advanced options.
//================
EditorGUILayout.Space();
EditorGUILayout.LabelField("Advanced Options", EditorStyles.boldLabel);
EditorGUI.indentLevel++;
{
//if ((target as UIGradient).targetGraphic is Text)
EditorGUILayout.PropertyField(_spGradientStyle);
EditorGUILayout.PropertyField(_spColorSpace);
EditorGUILayout.PropertyField(_spIgnoreAspectRatio);
}
EditorGUI.indentLevel--;
serializedObject.ApplyModifiedProperties();
}
}
}

View File

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

View File

@@ -0,0 +1,53 @@
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;
using System.Linq;
namespace Coffee.UIEffects.Editors
{
/// <summary>
/// UIEffect editor.
/// </summary>
[CustomEditor(typeof(UIHsvModifier))]
[CanEditMultipleObjects]
public class UIHsvModifierEditor : UnityEditor.Editor
{
SerializedProperty _spTargetColor;
SerializedProperty _spRange;
SerializedProperty _spHue;
SerializedProperty _spSaturation;
SerializedProperty _spValue;
/// <summary>
/// This function is called when the object becomes enabled and active.
/// </summary>
protected void OnEnable()
{
_spTargetColor = serializedObject.FindProperty("m_TargetColor");
_spRange = serializedObject.FindProperty("m_Range");
_spHue = serializedObject.FindProperty("m_Hue");
_spSaturation = serializedObject.FindProperty("m_Saturation");
_spValue = serializedObject.FindProperty("m_Value");
}
/// <summary>
/// Implement this function to make a custom inspector.
/// </summary>
public override void OnInspectorGUI()
{
serializedObject.Update();
//================
// Effect setting.
//================
EditorGUILayout.PropertyField(_spTargetColor);
EditorGUILayout.PropertyField(_spRange);
EditorGUILayout.PropertyField(_spHue);
EditorGUILayout.PropertyField(_spSaturation);
EditorGUILayout.PropertyField(_spValue);
serializedObject.ApplyModifiedProperties();
}
}
}

View File

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

View File

@@ -0,0 +1,62 @@
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;
namespace Coffee.UIEffects.Editors
{
/// <summary>
/// UIShadow editor.
/// </summary>
[CustomEditor(typeof(UIShadow))]
[CanEditMultipleObjects]
public class UIShadowEditor : UnityEditor.Editor
{
UIEffect uiEffect;
SerializedProperty _spStyle;
SerializedProperty _spEffectDistance;
SerializedProperty _spEffectColor;
SerializedProperty _spUseGraphicAlpha;
SerializedProperty _spBlurFactor;
void OnEnable()
{
uiEffect = (target as UIShadow).GetComponent<UIEffect>();
_spStyle = serializedObject.FindProperty("m_Style");
_spEffectDistance = serializedObject.FindProperty("m_EffectDistance");
_spEffectColor = serializedObject.FindProperty("m_EffectColor");
_spUseGraphicAlpha = serializedObject.FindProperty("m_UseGraphicAlpha");
_spBlurFactor = serializedObject.FindProperty("m_BlurFactor");
}
/// <summary>
/// Implement this function to make a custom inspector.
/// </summary>
public override void OnInspectorGUI()
{
serializedObject.Update();
//================
// Shadow setting.
//================
EditorGUILayout.PropertyField(_spStyle);
// When shadow is enable, show parameters.
if (_spStyle.intValue != (int) ShadowStyle.None)
{
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(_spEffectDistance);
EditorGUILayout.PropertyField(_spEffectColor);
EditorGUILayout.PropertyField(_spUseGraphicAlpha);
if (uiEffect && uiEffect.blurMode != BlurMode.None)
{
EditorGUILayout.PropertyField(_spBlurFactor);
}
EditorGUI.indentLevel--;
}
serializedObject.ApplyModifiedProperties();
}
}
}

View File

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

View File

@@ -0,0 +1,102 @@
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;
using System.Linq;
namespace Coffee.UIEffects.Editors
{
/// <summary>
/// UIEffect editor.
/// </summary>
[CustomEditor(typeof(UIShiny))]
[CanEditMultipleObjects]
public class UIShinyEditor : UnityEditor.Editor
{
SerializedProperty _spEffectFactor;
SerializedProperty _spWidth;
SerializedProperty _spRotation;
SerializedProperty _spSoftness;
SerializedProperty _spBrightness;
SerializedProperty _spGloss;
SerializedProperty _spEffectArea;
SerializedProperty _spPlay;
SerializedProperty _spLoop;
SerializedProperty _spLoopDelay;
SerializedProperty _spDuration;
SerializedProperty _spInitialPlayDelay;
SerializedProperty _spUpdateMode;
/// <summary>
/// This function is called when the object becomes enabled and active.
/// </summary>
protected void OnEnable()
{
_spEffectFactor = serializedObject.FindProperty("m_EffectFactor");
_spEffectArea = serializedObject.FindProperty("m_EffectArea");
_spWidth = serializedObject.FindProperty("m_Width");
_spRotation = serializedObject.FindProperty("m_Rotation");
_spSoftness = serializedObject.FindProperty("m_Softness");
_spBrightness = serializedObject.FindProperty("m_Brightness");
_spGloss = serializedObject.FindProperty("m_Gloss");
var player = serializedObject.FindProperty("m_Player");
_spPlay = player.FindPropertyRelative("play");
_spDuration = player.FindPropertyRelative("duration");
_spInitialPlayDelay = player.FindPropertyRelative("initialPlayDelay");
_spLoop = player.FindPropertyRelative("loop");
_spLoopDelay = player.FindPropertyRelative("loopDelay");
_spUpdateMode = player.FindPropertyRelative("updateMode");
}
/// <summary>
/// Implement this function to make a custom inspector.
/// </summary>
public override void OnInspectorGUI()
{
serializedObject.Update();
//================
// Effect setting.
//================
EditorGUILayout.PropertyField(_spEffectFactor);
EditorGUILayout.PropertyField(_spWidth);
EditorGUILayout.PropertyField(_spRotation);
EditorGUILayout.PropertyField(_spSoftness);
EditorGUILayout.PropertyField(_spBrightness);
EditorGUILayout.PropertyField(_spGloss);
//================
// Advanced option.
//================
EditorGUILayout.PropertyField(_spEffectArea);
//================
// Effect player.
//================
EditorGUILayout.PropertyField(_spPlay);
EditorGUILayout.PropertyField(_spDuration);
EditorGUILayout.PropertyField(_spInitialPlayDelay);
EditorGUILayout.PropertyField(_spLoop);
EditorGUILayout.PropertyField(_spLoopDelay);
EditorGUILayout.PropertyField(_spUpdateMode);
// Debug.
using (new EditorGUI.DisabledGroupScope(!Application.isPlaying))
using (new EditorGUILayout.HorizontalScope(EditorStyles.helpBox))
{
GUILayout.Label("Debug");
if (GUILayout.Button("Play", "ButtonLeft"))
{
(target as UIShiny).Play();
}
if (GUILayout.Button("Stop", "ButtonRight"))
{
(target as UIShiny).Stop();
}
}
serializedObject.ApplyModifiedProperties();
}
}
}

View File

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

View File

@@ -0,0 +1,115 @@
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;
using System.Linq;
namespace Coffee.UIEffects.Editors
{
/// <summary>
/// UIEffect editor.
/// </summary>
[CustomEditor(typeof(UITransitionEffect))]
[CanEditMultipleObjects]
public class UITransitionEffectEditor : UnityEditor.Editor
{
SerializedProperty _spEffectMode;
SerializedProperty _spEffectFactor;
SerializedProperty _spEffectArea;
SerializedProperty _spKeepAspectRatio;
SerializedProperty _spDissolveWidth;
SerializedProperty _spDissolveSoftness;
SerializedProperty _spDissolveColor;
SerializedProperty _spTransitionTexture;
SerializedProperty _spPlay;
SerializedProperty _spLoop;
SerializedProperty _spLoopDelay;
SerializedProperty _spDuration;
SerializedProperty _spInitialPlayDelay;
SerializedProperty _spUpdateMode;
SerializedProperty _spPassRayOnHidden;
/// <summary>
/// This function is called when the object becomes enabled and active.
/// </summary>
protected void OnEnable()
{
_spEffectMode = serializedObject.FindProperty("m_EffectMode");
_spEffectFactor = serializedObject.FindProperty("m_EffectFactor");
_spEffectArea = serializedObject.FindProperty("m_EffectArea");
_spKeepAspectRatio = serializedObject.FindProperty("m_KeepAspectRatio");
_spDissolveWidth = serializedObject.FindProperty("m_DissolveWidth");
_spDissolveSoftness = serializedObject.FindProperty("m_DissolveSoftness");
_spDissolveColor = serializedObject.FindProperty("m_DissolveColor");
_spTransitionTexture = serializedObject.FindProperty("m_TransitionTexture");
var player = serializedObject.FindProperty("m_Player");
_spPlay = player.FindPropertyRelative("play");
_spDuration = player.FindPropertyRelative("duration");
_spInitialPlayDelay = player.FindPropertyRelative("initialPlayDelay");
_spLoop = player.FindPropertyRelative("loop");
_spLoopDelay = player.FindPropertyRelative("loopDelay");
_spUpdateMode = player.FindPropertyRelative("updateMode");
_spPassRayOnHidden = serializedObject.FindProperty("m_PassRayOnHidden");
}
/// <summary>
/// Implement this function to make a custom inspector.
/// </summary>
public override void OnInspectorGUI()
{
//================
// Effect setting.
//================
using (new MaterialDirtyScope(targets))
EditorGUILayout.PropertyField(_spEffectMode);
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(_spEffectFactor);
if (_spEffectMode.intValue == (int) UITransitionEffect.EffectMode.Dissolve)
{
EditorGUILayout.PropertyField(_spDissolveWidth);
EditorGUILayout.PropertyField(_spDissolveSoftness);
EditorGUILayout.PropertyField(_spDissolveColor);
}
EditorGUI.indentLevel--;
//================
// Advanced option.
//================
EditorGUILayout.PropertyField(_spEffectArea);
using (new MaterialDirtyScope(targets))
EditorGUILayout.PropertyField(_spTransitionTexture);
EditorGUILayout.PropertyField(_spKeepAspectRatio);
EditorGUILayout.PropertyField(_spPassRayOnHidden);
//================
// Effect player.
//================
EditorGUILayout.PropertyField(_spPlay);
EditorGUILayout.PropertyField(_spDuration);
EditorGUILayout.PropertyField(_spInitialPlayDelay);
EditorGUILayout.PropertyField(_spLoop);
EditorGUILayout.PropertyField(_spLoopDelay);
EditorGUILayout.PropertyField(_spUpdateMode);
// Debug.
using (new EditorGUI.DisabledGroupScope(!Application.isPlaying))
using (new EditorGUILayout.HorizontalScope(EditorStyles.helpBox))
{
GUILayout.Label("Debug");
if (GUILayout.Button("Show", "ButtonLeft"))
{
(target as UITransitionEffect).Show();
}
if (GUILayout.Button("Hide", "ButtonRight"))
{
(target as UITransitionEffect).Hide();
}
}
serializedObject.ApplyModifiedProperties();
}
}
}

View File

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

View File

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

View File

@@ -0,0 +1,13 @@
namespace Coffee.UIEffects
{
/// <summary>
/// Blur effect mode.
/// </summary>
public enum BlurMode
{
None = 0,
FastBlur = 1,
MediumBlur = 2,
DetailBlur = 3,
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 5645838b01af8764d8f381f04b62b9a2
timeCreated: 1528296875
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,13 @@
namespace Coffee.UIEffects
{
/// <summary>
/// Color effect mode.
/// </summary>
public enum ColorMode
{
Multiply = 0,
Fill = 1,
Add = 2,
Subtract = 3,
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: e6ba1e487e0a19644afde2bd5531bd04
timeCreated: 1528296875
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,116 @@
using UnityEngine;
using UnityEngine.UI;
namespace Coffee.UIEffects
{
/// <summary>
/// Area for effect.
/// </summary>
public enum EffectArea
{
RectTransform,
Fit,
Character,
}
public static class EffectAreaExtensions
{
static readonly Rect rectForCharacter = new Rect(0, 0, 1, 1);
static readonly Vector2[] splitedCharacterPosition = {Vector2.up, Vector2.one, Vector2.right, Vector2.zero};
/// <summary>
/// Gets effect for area.
/// </summary>
public static Rect GetEffectArea(this EffectArea area, VertexHelper vh, Rect rectangle, float aspectRatio = -1)
{
Rect rect = default(Rect);
switch (area)
{
case EffectArea.RectTransform:
rect = rectangle;
break;
case EffectArea.Character:
rect = rectForCharacter;
break;
case EffectArea.Fit:
// Fit to contents.
UIVertex vertex = default(UIVertex);
float xMin = float.MaxValue;
float yMin = float.MaxValue;
float xMax = float.MinValue;
float yMax = float.MinValue;
for (int i = 0; i < vh.currentVertCount; i++)
{
vh.PopulateUIVertex(ref vertex, i);
float x = vertex.position.x;
float y = vertex.position.y;
xMin = Mathf.Min(xMin, x);
yMin = Mathf.Min(yMin, y);
xMax = Mathf.Max(xMax, x);
yMax = Mathf.Max(yMax, y);
}
rect.Set(xMin, yMin, xMax - xMin, yMax - yMin);
break;
default:
rect = rectangle;
break;
}
if (0 < aspectRatio)
{
if (rect.width < rect.height)
{
rect.width = rect.height * aspectRatio;
}
else
{
rect.height = rect.width / aspectRatio;
}
}
return rect;
}
/// <summary>
/// Gets position factor for area.
/// </summary>
public static void GetPositionFactor(this EffectArea area, int index, Rect rect, Vector2 position, bool isText,
bool isTMPro, out float x, out float y)
{
if (isText && area == EffectArea.Character)
{
index = isTMPro ? (index + 3) % 4 : index % 4;
x = splitedCharacterPosition[index].x;
y = splitedCharacterPosition[index].y;
}
else if (area == EffectArea.Fit)
{
x = Mathf.Clamp01((position.x - rect.xMin) / rect.width);
y = Mathf.Clamp01((position.y - rect.yMin) / rect.height);
}
else
{
x = Mathf.Clamp01(position.x / rect.width + 0.5f);
y = Mathf.Clamp01(position.y / rect.height + 0.5f);
}
}
/// <summary>
/// Normalize vertex position by local matrix.
/// </summary>
public static void GetNormalizedFactor(this EffectArea area, int index, Matrix2x3 matrix, Vector2 position,
bool isText, out Vector2 nomalizedPos)
{
if (isText && area == EffectArea.Character)
{
nomalizedPos = matrix * splitedCharacterPosition[(index + 3) % 4];
}
else
{
nomalizedPos = matrix * position;
}
}
}
}

View File

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

View File

@@ -0,0 +1,14 @@
namespace Coffee.UIEffects
{
/// <summary>
/// Effect mode.
/// </summary>
public enum EffectMode
{
None = 0,
Grayscale = 1,
Sepia = 2,
Nega = 3,
Pixel = 4,
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 092769547c242d74cbad96631a00963f
timeCreated: 1528296875
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,14 @@
namespace Coffee.UIEffects
{
/// <summary>
/// Shadow effect style.
/// </summary>
public enum ShadowStyle
{
None = 0,
Shadow,
Outline,
Outline8,
Shadow3,
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: b0eda5bf10146491c9cfe6a31c66f9a7
timeCreated: 1528296875
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,319 @@
using System;
using UnityEngine;
using UnityEditor;
using UnityEngine.UI;
using UnityEngine.Serialization;
using System.Text;
using System.Linq;
using System.IO;
namespace Coffee.UIEffects
{
/// <summary>
/// Dissolve effect for uGUI.
/// </summary>
[AddComponentMenu("UI/UIEffects/UIDissolve", 3)]
public class UIDissolve : BaseMaterialEffect, IMaterialModifier
{
private const uint k_ShaderId = 0 << 3;
private static readonly ParameterTexture s_ParamTex = new ParameterTexture(8, 128, "_ParamTex");
private static readonly int k_TransitionTexId = Shader.PropertyToID("_TransitionTex");
private bool _lastKeepAspectRatio;
private EffectArea _lastEffectArea;
private static Texture _defaultTransitionTexture;
[Tooltip("Current location[0-1] for dissolve effect. 0 is not dissolved, 1 is completely dissolved.")]
[FormerlySerializedAs("m_Location")]
[SerializeField]
[Range(0, 1)]
float m_EffectFactor = 0.5f;
[Tooltip("Edge width.")] [SerializeField] [Range(0, 1)]
float m_Width = 0.5f;
[Tooltip("Edge softness.")] [SerializeField] [Range(0, 1)]
float m_Softness = 0.5f;
[Tooltip("Edge color.")] [SerializeField] [ColorUsage(false)]
Color m_Color = new Color(0.0f, 0.25f, 1.0f);
[Tooltip("Edge color effect mode.")] [SerializeField]
ColorMode m_ColorMode = ColorMode.Add;
[Tooltip("Noise texture for dissolving (single channel texture).")]
[SerializeField]
[FormerlySerializedAs("m_NoiseTexture")]
Texture m_TransitionTexture;
[Header("Advanced Option")] [Tooltip("The area for effect.")] [SerializeField]
protected EffectArea m_EffectArea;
[Tooltip("Keep effect aspect ratio.")] [SerializeField]
bool m_KeepAspectRatio;
[Header("Effect Player")] [SerializeField]
EffectPlayer m_Player;
[Tooltip("Reverse the dissolve effect.")] [FormerlySerializedAs("m_ReverseAnimation")] [SerializeField]
bool m_Reverse = false;
/// <summary>
/// Effect factor between 0(start) and 1(end).
/// </summary>
public float effectFactor
{
get { return this.m_EffectFactor; }
set
{
value = Mathf.Clamp(value, 0, 1);
if (Mathf.Approximately(this.m_EffectFactor, value)) return;
this.m_EffectFactor = value;
SetEffectParamsDirty();
}
}
/// <summary>
/// Edge width.
/// </summary>
public float width
{
get { return this.m_Width; }
set
{
value = Mathf.Clamp(value, 0, 1);
if (Mathf.Approximately(this.m_Width, value)) return;
this.m_Width = value;
SetEffectParamsDirty();
}
}
/// <summary>
/// Edge softness.
/// </summary>
public float softness
{
get { return this.m_Softness; }
set
{
value = Mathf.Clamp(value, 0, 1);
if (Mathf.Approximately(this.m_Softness, value)) return;
this.m_Softness = value;
SetEffectParamsDirty();
}
}
/// <summary>
/// Edge color.
/// </summary>
public Color color
{
get { return this.m_Color; }
set
{
if (this.m_Color == value) return;
this.m_Color = value;
SetEffectParamsDirty();
}
}
/// <summary>
/// Noise texture.
/// </summary>
public Texture transitionTexture
{
get
{
return this.m_TransitionTexture
? this.m_TransitionTexture
: defaultTransitionTexture;
}
set
{
if (this.m_TransitionTexture == value) return;
this.m_TransitionTexture = value;
SetMaterialDirty();
}
}
private static Texture defaultTransitionTexture
{
get
{
return _defaultTransitionTexture
? _defaultTransitionTexture
: (_defaultTransitionTexture = Resources.Load<Texture>("Default-Transition"));
}
}
/// <summary>
/// The area for effect.
/// </summary>
public EffectArea effectArea
{
get { return this.m_EffectArea; }
set
{
if (this.m_EffectArea == value) return;
this.m_EffectArea = value;
SetVerticesDirty();
}
}
/// <summary>
/// Keep aspect ratio.
/// </summary>
public bool keepAspectRatio
{
get { return this.m_KeepAspectRatio; }
set
{
if (this.m_KeepAspectRatio == value) return;
this.m_KeepAspectRatio = value;
SetVerticesDirty();
}
}
/// <summary>
/// Color effect mode.
/// </summary>
public ColorMode colorMode
{
get { return this.m_ColorMode; }
set
{
if (this.m_ColorMode == value) return;
this.m_ColorMode = value;
SetMaterialDirty();
}
}
/// <summary>
/// Gets the parameter texture.
/// </summary>
public override ParameterTexture paramTex
{
get { return s_ParamTex; }
}
public EffectPlayer effectPlayer
{
get { return this.m_Player ?? (this.m_Player = new EffectPlayer()); }
}
public override Hash128 GetMaterialHash(Material material)
{
if (!this.isActiveAndEnabled || !material || !material.shader)
return k_InvalidHash;
var shaderVariantId = (uint) ((int) this.m_ColorMode << 6);
var resourceId = (uint) this.transitionTexture.GetInstanceID();
return new Hash128(
(uint) material.GetInstanceID(),
k_ShaderId + shaderVariantId,
resourceId,
0
);
}
public override void ModifyMaterial(Material newMaterial, Graphic graphic)
{
var connector = GraphicConnector.FindConnector(graphic);
newMaterial.shader = Shader.Find(string.Format("Hidden/{0} (UIDissolve)", newMaterial.shader.name));
SetShaderVariants(newMaterial, this.m_ColorMode);
newMaterial.SetTexture(k_TransitionTexId, this.transitionTexture);
this.paramTex.RegisterMaterial(newMaterial);
}
/// <summary>
/// Modifies the mesh.
/// </summary>
public override void ModifyMesh(VertexHelper vh, Graphic graphic)
{
if (!this.isActiveAndEnabled)
return;
// bool isText = isTMPro || graphic is Text;
var normalizedIndex = this.paramTex.GetNormalizedIndex(this);
// rect.
var tex = this.transitionTexture;
var aspectRatio = this.m_KeepAspectRatio && tex ? ((float) tex.width) / tex.height : -1;
var rect = this.m_EffectArea.GetEffectArea(vh, this.rectTransform.rect, aspectRatio);
// Calculate vertex position.
var vertex = default(UIVertex);
var count = vh.currentVertCount;
for (var i = 0; i < count; i++)
{
vh.PopulateUIVertex(ref vertex, i);
float x;
float y;
this.connector.GetPositionFactor(this.m_EffectArea, i, rect, vertex.position, out x, out y);
vertex.uv0 = new Vector2(
Packer.ToFloat(vertex.uv0.x, vertex.uv0.y),
Packer.ToFloat(x, y, normalizedIndex)
);
vh.SetUIVertex(vertex, i);
}
}
protected override void SetEffectParamsDirty()
{
this.paramTex.SetData(this, 0, this.m_EffectFactor); // param1.x : location
this.paramTex.SetData(this, 1, this.m_Width); // param1.y : width
this.paramTex.SetData(this, 2, this.m_Softness); // param1.z : softness
this.paramTex.SetData(this, 4, this.m_Color.r); // param2.x : red
this.paramTex.SetData(this, 5, this.m_Color.g); // param2.y : green
this.paramTex.SetData(this, 6, this.m_Color.b); // param2.z : blue
}
protected override void SetVerticesDirty()
{
base.SetVerticesDirty();
this._lastKeepAspectRatio = this.m_KeepAspectRatio;
this._lastEffectArea = this.m_EffectArea;
}
protected override void OnDidApplyAnimationProperties()
{
base.OnDidApplyAnimationProperties();
if (this._lastKeepAspectRatio != this.m_KeepAspectRatio
|| this._lastEffectArea != this.m_EffectArea)
SetVerticesDirty();
}
/// <summary>
/// Play effect.
/// </summary>
public void Play(bool reset = true)
{
this.effectPlayer.Play(reset);
}
/// <summary>
/// Stop effect.
/// </summary>
public void Stop(bool reset = true)
{
this.effectPlayer.Stop(reset);
}
protected override void OnEnable()
{
base.OnEnable();
this.effectPlayer.OnEnable((f) => this.effectFactor = this.m_Reverse ? 1f - f : f);
}
protected override void OnDisable()
{
base.OnDisable();
this.effectPlayer.OnDisable();
}
}
}

View File

@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: ce76b7a490bd74f34a2f2752641aea24
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences:
- m_TransitionTexture: {fileID: 2800000, guid: 3e04c247fb2604af186173fce0bc62de,
type: 3}
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,367 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Serialization;
#if UNITY_EDITOR
using System.IO;
using System.Linq;
using UnityEditor;
#endif
namespace Coffee.UIEffects
{
/// <summary>
/// UIEffect.
/// </summary>
[ExecuteInEditMode]
[RequireComponent(typeof(Graphic))]
[DisallowMultipleComponent]
[AddComponentMenu("UI/UIEffects/UIEffect", 1)]
public class UIEffect : BaseMaterialEffect, IMaterialModifier
{
private const uint k_ShaderId = 2 << 3;
private static readonly ParameterTexture s_ParamTex = new ParameterTexture(4, 1024, "_ParamTex");
[FormerlySerializedAs("m_ToneLevel")]
[Tooltip("Effect factor between 0(no effect) and 1(complete effect).")]
[SerializeField]
[Range(0, 1)]
float m_EffectFactor = 1;
[Tooltip("Color effect factor between 0(no effect) and 1(complete effect).")] [SerializeField] [Range(0, 1)]
float m_ColorFactor = 1;
[FormerlySerializedAs("m_Blur")]
[Tooltip("How far is the blurring from the graphic.")]
[SerializeField]
[Range(0, 1)]
float m_BlurFactor = 1;
[FormerlySerializedAs("m_ToneMode")] [Tooltip("Effect mode")] [SerializeField]
EffectMode m_EffectMode = EffectMode.None;
[Tooltip("Color effect mode")] [SerializeField]
ColorMode m_ColorMode = ColorMode.Multiply;
[Tooltip("Blur effect mode")] [SerializeField]
BlurMode m_BlurMode = BlurMode.None;
[Tooltip("Advanced blurring remove common artifacts in the blur effect for uGUI.")] [SerializeField]
bool m_AdvancedBlur = false;
private enum BlurEx
{
None = 0,
Ex = 1,
}
/// <summary>
/// Additional canvas shader channels to use this component.
/// </summary>
public AdditionalCanvasShaderChannels uvMaskChannel
{
get { return this.connector.extraChannel; }
}
/// <summary>
/// Effect factor between 0(no effect) and 1(complete effect).
/// </summary>
public float effectFactor
{
get { return this.m_EffectFactor; }
set
{
value = Mathf.Clamp(value, 0, 1);
if (Mathf.Approximately(this.m_EffectFactor, value)) return;
this.m_EffectFactor = value;
SetEffectParamsDirty();
}
}
/// <summary>
/// Color effect factor between 0(no effect) and 1(complete effect).
/// </summary>
public float colorFactor
{
get { return this.m_ColorFactor; }
set
{
value = Mathf.Clamp(value, 0, 1);
if (Mathf.Approximately(this.m_ColorFactor, value)) return;
this.m_ColorFactor = value;
SetEffectParamsDirty();
}
}
/// <summary>
/// How far is the blurring from the graphic.
/// </summary>
public float blurFactor
{
get { return this.m_BlurFactor; }
set
{
value = Mathf.Clamp(value, 0, 1);
if (Mathf.Approximately(this.m_BlurFactor, value)) return;
this.m_BlurFactor = value;
SetEffectParamsDirty();
}
}
/// <summary>
/// Effect mode.
/// </summary>
public EffectMode effectMode
{
get { return this.m_EffectMode; }
set
{
if (this.m_EffectMode == value) return;
this.m_EffectMode = value;
SetMaterialDirty();
}
}
/// <summary>
/// Color effect mode.
/// </summary>
public ColorMode colorMode
{
get { return this.m_ColorMode; }
set
{
if (this.m_ColorMode == value) return;
this.m_ColorMode = value;
SetMaterialDirty();
}
}
/// <summary>
/// Blur effect mode(readonly).
/// </summary>
public BlurMode blurMode
{
get { return this.m_BlurMode; }
set
{
if (this.m_BlurMode == value) return;
this.m_BlurMode = value;
SetMaterialDirty();
}
}
/// <summary>
/// Gets the parameter texture.
/// </summary>
public override ParameterTexture paramTex
{
get { return s_ParamTex; }
}
/// <summary>
/// Advanced blurring remove common artifacts in the blur effect for uGUI.
/// </summary>
public bool advancedBlur
{
get { return this.m_AdvancedBlur; }
set
{
if (this.m_AdvancedBlur == value) return;
this.m_AdvancedBlur = value;
SetVerticesDirty();
SetMaterialDirty();
}
}
public override Hash128 GetMaterialHash(Material material)
{
if (!this.isActiveAndEnabled || !material || !material.shader)
return k_InvalidHash;
var shaderVariantId = (uint) (((int) this.m_EffectMode << 6) + ((int) this.m_ColorMode << 9) +
((int) this.m_BlurMode << 11) + ((this.m_AdvancedBlur ? 1 : 0) << 13));
return new Hash128(
(uint) material.GetInstanceID(),
k_ShaderId + shaderVariantId,
0,
0
);
}
public override void ModifyMaterial(Material newMaterial, Graphic graphic)
{
var connector = GraphicConnector.FindConnector(graphic);
newMaterial.shader = Shader.Find(string.Format("Hidden/{0} (UIEffect)", newMaterial.shader.name));
SetShaderVariants(newMaterial, this.m_EffectMode, this.m_ColorMode, this.m_BlurMode, this.m_AdvancedBlur ? BlurEx.Ex : BlurEx.None);
this.paramTex.RegisterMaterial(newMaterial);
}
/// <summary>
/// Modifies the mesh.
/// </summary>
public override void ModifyMesh(VertexHelper vh, Graphic graphic)
{
if (!this.isActiveAndEnabled)
{
return;
}
var normalizedIndex = this.paramTex.GetNormalizedIndex(this);
if (this.m_BlurMode != BlurMode.None && this.advancedBlur)
{
vh.GetUIVertexStream(s_TempVerts);
vh.Clear();
var count = s_TempVerts.Count;
// Bundle
int bundleSize = this.connector.IsText(graphic) ? 6 : count;
Rect posBounds = default(Rect);
Rect uvBounds = default(Rect);
Vector3 size = default(Vector3);
Vector3 tPos = default(Vector3);
Vector3 tUV = default(Vector3);
float expand = (float) this.blurMode * 6 * 2;
for (int i = 0; i < count; i += bundleSize)
{
// min/max for bundled-quad
GetBounds(s_TempVerts, i, bundleSize, ref posBounds, ref uvBounds, true);
// Pack uv mask.
Vector2 uvMask = new Vector2(Packer.ToFloat(uvBounds.xMin, uvBounds.yMin),
Packer.ToFloat(uvBounds.xMax, uvBounds.yMax));
// Quad
for (int j = 0; j < bundleSize; j += 6)
{
Vector3 cornerPos1 = s_TempVerts[i + j + 1].position;
Vector3 cornerPos2 = s_TempVerts[i + j + 4].position;
// Is outer quad?
bool hasOuterEdge = (bundleSize == 6)
|| !posBounds.Contains(cornerPos1)
|| !posBounds.Contains(cornerPos2);
if (hasOuterEdge)
{
Vector3 cornerUv1 = s_TempVerts[i + j + 1].uv0;
Vector3 cornerUv2 = s_TempVerts[i + j + 4].uv0;
Vector3 centerPos = (cornerPos1 + cornerPos2) / 2;
Vector3 centerUV = (cornerUv1 + cornerUv2) / 2;
size = (cornerPos1 - cornerPos2);
size.x = 1 + expand / Mathf.Abs(size.x);
size.y = 1 + expand / Mathf.Abs(size.y);
size.z = 1 + expand / Mathf.Abs(size.z);
tPos = centerPos - Vector3.Scale(size, centerPos);
tUV = centerUV - Vector3.Scale(size, centerUV);
}
// Vertex
for (int k = 0; k < 6; k++)
{
UIVertex vt = s_TempVerts[i + j + k];
Vector3 pos = vt.position;
Vector2 uv0 = vt.uv0;
if (hasOuterEdge && (pos.x < posBounds.xMin || posBounds.xMax < pos.x))
{
pos.x = pos.x * size.x + tPos.x;
uv0.x = uv0.x * size.x + tUV.x;
}
if (hasOuterEdge && (pos.y < posBounds.yMin || posBounds.yMax < pos.y))
{
pos.y = pos.y * size.y + tPos.y;
uv0.y = uv0.y * size.y + tUV.y;
}
vt.uv0 = new Vector2(Packer.ToFloat((uv0.x + 0.5f) / 2f, (uv0.y + 0.5f) / 2f),
normalizedIndex);
vt.position = pos;
this.connector.SetExtraChannel(ref vt, uvMask);
s_TempVerts[i + j + k] = vt;
}
}
}
vh.AddUIVertexTriangleStream(s_TempVerts);
s_TempVerts.Clear();
}
else
{
int count = vh.currentVertCount;
UIVertex vt = default(UIVertex);
for (int i = 0; i < count; i++)
{
vh.PopulateUIVertex(ref vt, i);
Vector2 uv0 = vt.uv0;
vt.uv0 = new Vector2(
Packer.ToFloat((uv0.x + 0.5f) / 2f, (uv0.y + 0.5f) / 2f),
normalizedIndex
);
vh.SetUIVertex(vt, i);
}
}
}
protected override void SetEffectParamsDirty()
{
this.paramTex.SetData(this, 0, this.m_EffectFactor); // param.x : effect factor
this.paramTex.SetData(this, 1, this.m_ColorFactor); // param.y : color factor
this.paramTex.SetData(this, 2, this.m_BlurFactor); // param.z : blur factor
}
static void GetBounds(List<UIVertex> verts, int start, int count, ref Rect posBounds, ref Rect uvBounds,
bool global)
{
Vector2 minPos = new Vector2(float.MaxValue, float.MaxValue);
Vector2 maxPos = new Vector2(float.MinValue, float.MinValue);
Vector2 minUV = new Vector2(float.MaxValue, float.MaxValue);
Vector2 maxUV = new Vector2(float.MinValue, float.MinValue);
for (int i = start; i < start + count; i++)
{
UIVertex vt = verts[i];
Vector2 uv = vt.uv0;
Vector3 pos = vt.position;
// Left-Bottom
if (minPos.x >= pos.x && minPos.y >= pos.y)
{
minPos = pos;
}
// Right-Top
else if (maxPos.x <= pos.x && maxPos.y <= pos.y)
{
maxPos = pos;
}
// Left-Bottom
if (minUV.x >= uv.x && minUV.y >= uv.y)
{
minUV = uv;
}
// Right-Top
else if (maxUV.x <= uv.x && maxUV.y <= uv.y)
{
maxUV = uv;
}
}
// Shrink coordinate for detect edge
posBounds.Set(minPos.x + 0.001f, minPos.y + 0.001f, maxPos.x - minPos.x - 0.002f,
maxPos.y - minPos.y - 0.002f);
uvBounds.Set(minUV.x, minUV.y, maxUV.x - minUV.x, maxUV.y - minUV.y);
}
}
}

View File

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

View File

@@ -0,0 +1,67 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
namespace Coffee.UIEffects
{
[DisallowMultipleComponent]
[AddComponentMenu("UI/UIEffects/UIFlip", 102)]
public class UIFlip : BaseMeshEffect
{
[Tooltip("Flip horizontally.")] [SerializeField]
private bool m_Horizontal = false;
[Tooltip("Flip vertically.")] [SerializeField]
private bool m_Veritical = false;
/// <summary>
/// Gets or sets a value indicating whether this <see cref="Coffee.UIEffects.UIFlip"/> should be flipped horizontally.
/// </summary>
/// <value><c>true</c> if be flipped horizontally; otherwise, <c>false</c>.</value>
public bool horizontal
{
get { return this.m_Horizontal; }
set
{
if (this.m_Horizontal == value) return;
this.m_Horizontal = value;
SetEffectParamsDirty();
}
}
/// <summary>
/// Gets or sets a value indicating whether this <see cref="Coffee.UIEffects.UIFlip"/> should be flipped vertically.
/// </summary>
/// <value><c>true</c> if be flipped horizontally; otherwise, <c>false</c>.</value>
public bool vertical
{
get { return this.m_Veritical; }
set
{
if (this.m_Veritical == value) return;
this.m_Veritical = value;
SetEffectParamsDirty();
}
}
/// <summary>
/// Call used to modify mesh.
/// </summary>
/// <param name="vh">VertexHelper.</param>
public override void ModifyMesh(VertexHelper vh, Graphic graphic)
{
if (!this.isActiveAndEnabled) return;
var vt = default(UIVertex);
for (var i = 0; i < vh.currentVertCount; i++)
{
vh.PopulateUIVertex(ref vt, i);
var pos = vt.position;
vt.position = new Vector3(this.m_Horizontal ? -pos.x : pos.x, this.m_Veritical ? -pos.y : pos.y
);
vh.SetUIVertex(vt, i);
}
}
}
}

View File

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

View File

@@ -0,0 +1,319 @@
using UnityEngine;
using UnityEngine.UI;
namespace Coffee.UIEffects
{
/// <summary>
/// UIGradient.
/// </summary>
[DisallowMultipleComponent]
[AddComponentMenu("UI/UIEffects/UIGradient", 101)]
public class UIGradient : BaseMeshEffect
{
static readonly Vector2[] s_SplitedCharacterPosition = {Vector2.up, Vector2.one, Vector2.right, Vector2.zero};
/// <summary>
/// Gradient direction.
/// </summary>
public enum Direction
{
Horizontal,
Vertical,
Angle,
Diagonal,
}
/// <summary>
/// Gradient space for Text.
/// </summary>
public enum GradientStyle
{
Rect,
Fit,
Split,
}
[Tooltip("Gradient Direction.")] [SerializeField]
Direction m_Direction;
[Tooltip("Color1: Top or Left.")] [SerializeField]
Color m_Color1 = Color.white;
[Tooltip("Color2: Bottom or Right.")] [SerializeField]
Color m_Color2 = Color.white;
[Tooltip("Color3: For diagonal.")] [SerializeField]
Color m_Color3 = Color.white;
[Tooltip("Color4: For diagonal.")] [SerializeField]
Color m_Color4 = Color.white;
[Tooltip("Gradient rotation.")] [SerializeField] [Range(-180, 180)]
float m_Rotation;
[Tooltip("Gradient offset for Horizontal, Vertical or Angle.")] [SerializeField] [Range(-1, 1)]
float m_Offset1;
[Tooltip("Gradient offset for Diagonal.")] [SerializeField] [Range(-1, 1)]
float m_Offset2;
[Tooltip("Gradient style for Text.")] [SerializeField]
GradientStyle m_GradientStyle;
[Tooltip("Color space to correct color.")] [SerializeField]
ColorSpace m_ColorSpace = ColorSpace.Uninitialized;
[Tooltip("Ignore aspect ratio.")] [SerializeField]
bool m_IgnoreAspectRatio = true;
/// <summary>
/// Gradient Direction.
/// </summary>
public Direction direction
{
get { return this.m_Direction; }
set
{
if (this.m_Direction == value) return;
this.m_Direction = value;
SetVerticesDirty();
}
}
/// <summary>
/// Color1: Top or Left.
/// </summary>
public Color color1
{
get { return this.m_Color1; }
set
{
if (this.m_Color1 == value) return;
this.m_Color1 = value;
SetVerticesDirty();
}
}
/// <summary>
/// Color2: Bottom or Right.
/// </summary>
public Color color2
{
get { return this.m_Color2; }
set
{
if (this.m_Color2 == value) return;
this.m_Color2 = value;
SetVerticesDirty();
}
}
/// <summary>
/// Color3: For diagonal.
/// </summary>
public Color color3
{
get { return this.m_Color3; }
set
{
if (this.m_Color3 == value) return;
this.m_Color3 = value;
SetVerticesDirty();
}
}
/// <summary>
/// Color4: For diagonal.
/// </summary>
public Color color4
{
get { return this.m_Color4; }
set
{
if (this.m_Color4 == value) return;
this.m_Color4 = value;
SetVerticesDirty();
}
}
/// <summary>
/// Gradient rotation.
/// </summary>
public float rotation
{
get
{
return this.m_Direction == Direction.Horizontal ? -90
: this.m_Direction == Direction.Vertical ? 0
: this.m_Rotation;
}
set
{
if (Mathf.Approximately(this.m_Rotation, value)) return;
this.m_Rotation = value;
SetVerticesDirty();
}
}
/// <summary>
/// Gradient offset for Horizontal, Vertical or Angle.
/// </summary>
public float offset
{
get { return this.m_Offset1; }
set
{
if (Mathf.Approximately(this.m_Offset1, value)) return;
this.m_Offset1 = value;
SetVerticesDirty();
}
}
/// <summary>
/// Gradient offset for Diagonal.
/// </summary>
public Vector2 offset2
{
get { return new Vector2(this.m_Offset2, this.m_Offset1); }
set
{
if (Mathf.Approximately(this.m_Offset1, value.y) && Mathf.Approximately(this.m_Offset2, value.x)) return;
this.m_Offset1 = value.y;
this.m_Offset2 = value.x;
SetVerticesDirty();
}
}
/// <summary>
/// Gradient style for Text.
/// </summary>
public GradientStyle gradientStyle
{
get { return this.m_GradientStyle; }
set
{
if (this.m_GradientStyle == value) return;
this.m_GradientStyle = value;
SetVerticesDirty();
}
}
/// <summary>
/// Color space to correct color.
/// </summary>
public ColorSpace colorSpace
{
get { return this.m_ColorSpace; }
set
{
if (this.m_ColorSpace == value) return;
this.m_ColorSpace = value;
SetVerticesDirty();
}
}
/// <summary>
/// Ignore aspect ratio.
/// </summary>
public bool ignoreAspectRatio
{
get { return this.m_IgnoreAspectRatio; }
set
{
if (this.m_IgnoreAspectRatio == value) return;
this.m_IgnoreAspectRatio = value;
SetVerticesDirty();
}
}
/// <summary>
/// Call used to modify mesh.
/// </summary>
public override void ModifyMesh(VertexHelper vh, Graphic graphic)
{
if (!this.isActiveAndEnabled)
return;
// Gradient space.
var rect = default(Rect);
var vertex = default(UIVertex);
switch (this.m_GradientStyle)
{
case GradientStyle.Rect:
// RectTransform.
rect = graphic.rectTransform.rect;
break;
case GradientStyle.Split:
// Each characters.
rect.Set(0, 0, 1, 1);
break;
case GradientStyle.Fit:
{
// Fit to contents.
rect.xMin = rect.yMin = float.MaxValue;
rect.xMax = rect.yMax = float.MinValue;
for (var i = 0; i < vh.currentVertCount; i++)
{
vh.PopulateUIVertex(ref vertex, i);
rect.xMin = Mathf.Min(rect.xMin, vertex.position.x);
rect.yMin = Mathf.Min(rect.yMin, vertex.position.y);
rect.xMax = Mathf.Max(rect.xMax, vertex.position.x);
rect.yMax = Mathf.Max(rect.yMax, vertex.position.y);
}
break;
}
}
// Gradient rotation.
var rad = this.rotation * Mathf.Deg2Rad;
var dir = new Vector2(Mathf.Cos(rad), Mathf.Sin(rad));
if (!this.m_IgnoreAspectRatio && Direction.Angle <= this.m_Direction)
{
dir.x *= rect.height / rect.width;
dir = dir.normalized;
}
// Calculate vertex color.
var localMatrix = new Matrix2x3(rect, dir.x, dir.y); // Get local matrix.
for (var i = 0; i < vh.currentVertCount; i++)
{
vh.PopulateUIVertex(ref vertex, i);
// Normalize vertex position by local matrix.
Vector2 normalizedPos;
if (this.m_GradientStyle == GradientStyle.Split)
{
// Each characters.
normalizedPos = localMatrix * s_SplitedCharacterPosition[i % 4] + this.offset2;
}
else
{
normalizedPos = localMatrix * vertex.position + this.offset2;
}
// Interpolate vertex color.
Color color;
if (this.direction == Direction.Diagonal)
{
color = Color.LerpUnclamped(
Color.LerpUnclamped(this.m_Color1, this.m_Color2, normalizedPos.x),
Color.LerpUnclamped(this.m_Color3, this.m_Color4, normalizedPos.x),
normalizedPos.y);
}
else
{
color = Color.LerpUnclamped(this.m_Color2, this.m_Color1, normalizedPos.y);
}
// Correct color.
vertex.color *= (this.m_ColorSpace == ColorSpace.Gamma) ? color.gamma
: (this.m_ColorSpace == ColorSpace.Linear) ? color.linear
: color;
vh.SetUIVertex(vertex, i);
}
}
}
}

View File

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

View File

@@ -0,0 +1,170 @@
using System;
using UnityEngine;
using UnityEngine.Serialization;
using UnityEngine.UI;
namespace Coffee.UIEffects
{
/// <summary>
/// HSV Modifier.
/// </summary>
[AddComponentMenu("UI/UIEffects/UIHsvModifier", 4)]
public class UIHsvModifier : BaseMaterialEffect
{
private const uint k_ShaderId = 6 << 3;
private static readonly ParameterTexture s_ParamTex = new ParameterTexture(7, 128, "_ParamTex");
[Header("Target")] [Tooltip("Target color to affect hsv shift.")] [SerializeField] [ColorUsage(false)]
Color m_TargetColor = Color.red;
[Tooltip("Color range to affect hsv shift [0 ~ 1].")] [SerializeField] [Range(0, 1)]
float m_Range = 0.1f;
[Header("Adjustment")] [Tooltip("Hue shift [-0.5 ~ 0.5].")] [SerializeField] [Range(-0.5f, 0.5f)]
float m_Hue;
[Tooltip("Saturation shift [-0.5 ~ 0.5].")] [SerializeField] [Range(-0.5f, 0.5f)]
float m_Saturation;
[Tooltip("Value shift [-0.5 ~ 0.5].")] [SerializeField] [Range(-0.5f, 0.5f)]
float m_Value;
/// <summary>
/// Target color to affect hsv shift.
/// </summary>
public Color targetColor
{
get { return this.m_TargetColor; }
set
{
if (this.m_TargetColor == value) return;
this.m_TargetColor = value;
SetEffectParamsDirty();
}
}
/// <summary>
/// Color range to affect hsv shift [0 ~ 1].
/// </summary>
public float range
{
get { return this.m_Range; }
set
{
value = Mathf.Clamp(value, 0, 1);
if (Mathf.Approximately(this.m_Range, value)) return;
this.m_Range = value;
SetEffectParamsDirty();
}
}
/// <summary>
/// Saturation shift [-0.5 ~ 0.5].
/// </summary>
public float saturation
{
get { return this.m_Saturation; }
set
{
value = Mathf.Clamp(value, -0.5f, 0.5f);
if (Mathf.Approximately(this.m_Saturation, value)) return;
this.m_Saturation = value;
SetEffectParamsDirty();
}
}
/// <summary>
/// Value shift [-0.5 ~ 0.5].
/// </summary>
public float value
{
get { return this.m_Value; }
set
{
value = Mathf.Clamp(value, -0.5f, 0.5f);
if (Mathf.Approximately(this.m_Value, value)) return;
this.m_Value = value;
SetEffectParamsDirty();
}
}
/// <summary>
/// Hue shift [-0.5 ~ 0.5].
/// </summary>
public float hue
{
get { return this.m_Hue; }
set
{
value = Mathf.Clamp(value, -0.5f, 0.5f);
if (Mathf.Approximately(this.m_Hue, value)) return;
this.m_Hue = value;
SetEffectParamsDirty();
}
}
/// <summary>
/// Gets the parameter texture.
/// </summary>
public override ParameterTexture paramTex
{
get { return s_ParamTex; }
}
public override Hash128 GetMaterialHash(Material material)
{
if (!this.isActiveAndEnabled || !material || !material.shader)
return k_InvalidHash;
return new Hash128(
(uint) material.GetInstanceID(),
k_ShaderId,
0,
0
);
}
public override void ModifyMaterial(Material newMaterial, Graphic graphic)
{
var connector = GraphicConnector.FindConnector(graphic);
newMaterial.shader = Shader.Find(string.Format("Hidden/{0} (UIHsvModifier)", newMaterial.shader.name));
this.paramTex.RegisterMaterial(newMaterial);
}
public override void ModifyMesh(VertexHelper vh, Graphic graphic)
{
if (!this.isActiveAndEnabled)
return;
var normalizedIndex = this.paramTex.GetNormalizedIndex(this);
var vertex = default(UIVertex);
var count = vh.currentVertCount;
for (var i = 0; i < count; i++)
{
vh.PopulateUIVertex(ref vertex, i);
vertex.uv0 = new Vector2(
Packer.ToFloat(vertex.uv0.x, vertex.uv0.y),
normalizedIndex
);
vh.SetUIVertex(vertex, i);
}
}
protected override void SetEffectParamsDirty()
{
float h, s, v;
Color.RGBToHSV(this.m_TargetColor, out h, out s, out v);
this.paramTex.SetData(this, 0, h); // param1.x : target hue
this.paramTex.SetData(this, 1, s); // param1.y : target saturation
this.paramTex.SetData(this, 2, v); // param1.z : target value
this.paramTex.SetData(this, 3, this.m_Range); // param1.w : target range
this.paramTex.SetData(this, 4, this.m_Hue + 0.5f); // param2.x : hue shift
this.paramTex.SetData(this, 5, this.m_Saturation + 0.5f); // param2.y : saturation shift
this.paramTex.SetData(this, 6, this.m_Value + 0.5f); // param2.z : value shift
}
}
}

View File

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

View File

@@ -0,0 +1,383 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Serialization;
using UnityEngine.UI;
#if UNITY_EDITOR
using System.IO;
using System.Linq;
using UnityEditor;
#endif
namespace Coffee.UIEffects
{
/// <summary>
/// UIEffect.
/// </summary>
[RequireComponent(typeof(Graphic))]
[AddComponentMenu("UI/UIEffects/UIShadow", 100)]
public class UIShadow : BaseMeshEffect, IParameterTexture
{
static readonly List<UIShadow> tmpShadows = new List<UIShadow>();
static readonly List<UIVertex> s_Verts = new List<UIVertex>(4096);
int _graphicVertexCount;
UIEffect _uiEffect;
[Tooltip("How far is the blurring shadow from the graphic.")]
[FormerlySerializedAs("m_Blur")]
[SerializeField]
[Range(0, 1)]
float m_BlurFactor = 1;
[Tooltip("Shadow effect style.")] [SerializeField]
ShadowStyle m_Style = ShadowStyle.Shadow;
[SerializeField] private Color m_EffectColor = new Color(0f, 0f, 0f, 0.5f);
[SerializeField] private Vector2 m_EffectDistance = new Vector2(1f, -1f);
[SerializeField] private bool m_UseGraphicAlpha = true;
private const float kMaxEffectDistance = 600f;
public Color effectColor
{
get { return this.m_EffectColor; }
set
{
if (this.m_EffectColor == value) return;
this.m_EffectColor = value;
SetVerticesDirty();
}
}
public Vector2 effectDistance
{
get { return this.m_EffectDistance; }
set
{
if (value.x > kMaxEffectDistance)
value.x = kMaxEffectDistance;
if (value.x < -kMaxEffectDistance)
value.x = -kMaxEffectDistance;
if (value.y > kMaxEffectDistance)
value.y = kMaxEffectDistance;
if (value.y < -kMaxEffectDistance)
value.y = -kMaxEffectDistance;
if (this.m_EffectDistance == value) return;
this.m_EffectDistance = value;
SetEffectParamsDirty();
}
}
public bool useGraphicAlpha
{
get { return this.m_UseGraphicAlpha; }
set
{
if (this.m_UseGraphicAlpha == value) return;
this.m_UseGraphicAlpha = value;
SetEffectParamsDirty();
}
}
/// <summary>
/// How far is the blurring shadow from the graphic.
/// </summary>
public float blurFactor
{
get { return this.m_BlurFactor; }
set
{
value = Mathf.Clamp(value, 0, 2);
if (Mathf.Approximately(this.m_BlurFactor, value)) return;
this.m_BlurFactor = value;
SetEffectParamsDirty();
}
}
/// <summary>
/// Shadow effect style.
/// </summary>
public ShadowStyle style
{
get { return this.m_Style; }
set
{
if (this.m_Style == value) return;
this.m_Style = value;
SetEffectParamsDirty();
}
}
/// <summary>
/// Gets or sets the parameter index.
/// </summary>
public int parameterIndex { get; set; }
/// <summary>
/// Gets the parameter texture.
/// </summary>
public ParameterTexture paramTex { get; private set; }
protected override void OnEnable()
{
base.OnEnable();
this._uiEffect = GetComponent<UIEffect>();
if (!this._uiEffect) return;
this.paramTex = this._uiEffect.paramTex;
this.paramTex.Register(this);
}
protected override void OnDisable()
{
base.OnDisable();
this._uiEffect = null;
if (this.paramTex == null) return;
this.paramTex.Unregister(this);
this.paramTex = null;
}
// #if UNITY_EDITOR
// protected override void OnValidate()
// {
// effectDistance = m_EffectDistance;
// base.OnValidate();
// }
// #endif
// #if TMP_PRESENT
// protected void OnCullStateChanged (bool state)
// {
// SetVerticesDirty ();
// }
//
// Vector2 res;
// protected override void LateUpdate ()
// {
// if (res.x != Screen.width || res.y != Screen.height)
// {
// res.x = Screen.width;
// res.y = Screen.height;
// SetVerticesDirty ();
// }
// if (textMeshPro && transform.hasChanged)
// {
// transform.hasChanged = false;
// }
// base.LateUpdate ();
// }
// #endif
/// <summary>
/// Modifies the mesh.
/// </summary>
public override void ModifyMesh(VertexHelper vh, Graphic graphic)
{
if (!this.isActiveAndEnabled || vh.currentVertCount <= 0 || this.m_Style == ShadowStyle.None)
{
return;
}
vh.GetUIVertexStream(s_Verts);
GetComponents<UIShadow>(tmpShadows);
foreach (var s in tmpShadows)
{
if (!s.isActiveAndEnabled) continue;
if (s == this)
{
foreach (var s2 in tmpShadows)
{
s2._graphicVertexCount = s_Verts.Count;
}
}
break;
}
tmpShadows.Clear();
//================================
// Append shadow vertices.
//================================
{
this._uiEffect = this._uiEffect ? this._uiEffect : GetComponent<UIEffect>();
var start = s_Verts.Count - this._graphicVertexCount;
var end = s_Verts.Count;
if (this.paramTex != null && this._uiEffect && this._uiEffect.isActiveAndEnabled)
{
this.paramTex.SetData(this, 0, this._uiEffect.effectFactor); // param.x : effect factor
this.paramTex.SetData(this, 1, 255); // param.y : color factor
this.paramTex.SetData(this, 2, this.m_BlurFactor); // param.z : blur factor
}
ApplyShadow(s_Verts, this.effectColor, ref start, ref end, this.effectDistance, this.style, this.useGraphicAlpha);
}
vh.Clear();
vh.AddUIVertexTriangleStream(s_Verts);
s_Verts.Clear();
}
/// <summary>
/// Append shadow vertices.
/// * It is similar to Shadow component implementation.
/// </summary>
private void ApplyShadow(List<UIVertex> verts, Color color, ref int start, ref int end, Vector2 distance,
ShadowStyle style, bool alpha)
{
if (style == ShadowStyle.None || color.a <= 0)
return;
var x = distance.x;
var y = distance.y;
// Append Shadow.
ApplyShadowZeroAlloc(verts, color, ref start, ref end, x, y, alpha);
switch (style)
{
// Append Shadow3.
case ShadowStyle.Shadow3:
ApplyShadowZeroAlloc(verts, color, ref start, ref end, x, 0, alpha);
ApplyShadowZeroAlloc(verts, color, ref start, ref end, 0, y, alpha);
break;
// Append Outline.
case ShadowStyle.Outline:
ApplyShadowZeroAlloc(verts, color, ref start, ref end, x, -y, alpha);
ApplyShadowZeroAlloc(verts, color, ref start, ref end, -x, y, alpha);
ApplyShadowZeroAlloc(verts, color, ref start, ref end, -x, -y, alpha);
break;
// Append Outline8.
case ShadowStyle.Outline8:
ApplyShadowZeroAlloc(verts, color, ref start, ref end, x, -y, alpha);
ApplyShadowZeroAlloc(verts, color, ref start, ref end, -x, y, alpha);
ApplyShadowZeroAlloc(verts, color, ref start, ref end, -x, -y, alpha);
ApplyShadowZeroAlloc(verts, color, ref start, ref end, -x, 0, alpha);
ApplyShadowZeroAlloc(verts, color, ref start, ref end, 0, -y, alpha);
ApplyShadowZeroAlloc(verts, color, ref start, ref end, x, 0, alpha);
ApplyShadowZeroAlloc(verts, color, ref start, ref end, 0, y, alpha);
break;
}
}
/// <summary>
/// Append shadow vertices.
/// * It is similar to Shadow component implementation.
/// </summary>
private void ApplyShadowZeroAlloc(List<UIVertex> verts, Color color, ref int start, ref int end, float x,
float y, bool alpha)
{
// Check list capacity.
var count = end - start;
var neededCapacity = verts.Count + count;
if (verts.Capacity < neededCapacity)
verts.Capacity *= 2;
var normalizedIndex = this.paramTex != null && this._uiEffect && this._uiEffect.isActiveAndEnabled
? this.paramTex.GetNormalizedIndex(this)
: -1;
// Add
var vt = default(UIVertex);
for (var i = 0; i < count; i++)
{
verts.Add(vt);
}
// Move
for (var i = verts.Count - 1; count <= i; i--)
{
verts[i] = verts[i - count];
}
// Append shadow vertices to the front of list.
// * The original vertex is pushed backward.
for (var i = 0; i < count; ++i)
{
vt = verts[i + start + count];
var v = vt.position;
vt.position.Set(v.x + x, v.y + y, v.z);
var vertColor = this.effectColor;
vertColor.a = alpha ? color.a * vt.color.a / 255 : color.a;
vt.color = vertColor;
// Set UIEffect parameters
if (0 <= normalizedIndex)
{
vt.uv0 = new Vector2(
vt.uv0.x,
normalizedIndex
);
}
verts[i] = vt;
}
// Update next shadow offset.
start = end;
end = verts.Count;
}
/// <summary>
/// Mark the UIEffect as dirty.
/// </summary>
// void _SetDirty()
// {
// if (graphic)
// graphic.SetVerticesDirty();
// }
// #if UNITY_EDITOR
// public void OnBeforeSerialize()
// {
// }
//
// public void OnAfterDeserialize()
// {
// EditorApplication.delayCall += UpgradeIfNeeded;
// }
//
//
// #pragma warning disable 0612
// void UpgradeIfNeeded()
// {
// if (0 < m_AdditionalShadows.Count)
// {
// foreach (var s in m_AdditionalShadows)
// {
// if (s.style == ShadowStyle.None)
// {
// continue;
// }
//
// var shadow = gameObject.AddComponent<UIShadow>();
// shadow.style = s.style;
// shadow.effectDistance = s.effectDistance;
// shadow.effectColor = s.effectColor;
// shadow.useGraphicAlpha = s.useGraphicAlpha;
// shadow.blurFactor = s.blur;
// }
//
// m_AdditionalShadows = null;
// }
// }
// #pragma warning restore 0612
// #endif
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 0848bff101191904ead4bb831f7084db
timeCreated: 1485321967
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: -400
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,278 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Serialization;
using UnityEngine.UI;
using System.Collections;
namespace Coffee.UIEffects
{
/// <summary>
/// UIEffect.
/// </summary>
[AddComponentMenu("UI/UIEffects/UIShiny", 2)]
public class UIShiny : BaseMaterialEffect
{
private const uint k_ShaderId = 1 << 3;
private static readonly ParameterTexture s_ParamTex = new ParameterTexture(8, 128, "_ParamTex");
float _lastRotation;
EffectArea _lastEffectArea;
[Tooltip("Location for shiny effect.")] [FormerlySerializedAs("m_Location")] [SerializeField] [Range(0, 1)]
float m_EffectFactor = 0.5f;
[Tooltip("Width for shiny effect.")] [SerializeField] [Range(0, 1)]
float m_Width = 0.25f;
[Tooltip("Rotation for shiny effect.")] [SerializeField] [Range(-180, 180)]
float m_Rotation = 135;
[Tooltip("Softness for shiny effect.")] [SerializeField] [Range(0.01f, 1)]
float m_Softness = 1f;
[Tooltip("Brightness for shiny effect.")] [FormerlySerializedAs("m_Alpha")] [SerializeField] [Range(0, 1)]
float m_Brightness = 1f;
[Tooltip("Gloss factor for shiny effect.")] [FormerlySerializedAs("m_Highlight")] [SerializeField] [Range(0, 1)]
float m_Gloss = 1;
[Header("Advanced Option")] [Tooltip("The area for effect.")] [SerializeField]
protected EffectArea m_EffectArea;
[SerializeField] EffectPlayer m_Player;
/// <summary>
/// Effect factor between 0(start) and 1(end).
/// </summary>
public float effectFactor
{
get { return this.m_EffectFactor; }
set
{
value = Mathf.Clamp(value, 0, 1);
if (Mathf.Approximately(this.m_EffectFactor, value)) return;
this.m_EffectFactor = value;
SetEffectParamsDirty();
}
}
/// <summary>
/// Width for shiny effect.
/// </summary>
public float width
{
get { return this.m_Width; }
set
{
value = Mathf.Clamp(value, 0, 1);
if (Mathf.Approximately(this.m_Width, value)) return;
this.m_Width = value;
SetEffectParamsDirty();
}
}
/// <summary>
/// Softness for shiny effect.
/// </summary>
public float softness
{
get { return this.m_Softness; }
set
{
value = Mathf.Clamp(value, 0.01f, 1);
if (Mathf.Approximately(this.m_Softness, value)) return;
this.m_Softness = value;
SetEffectParamsDirty();
}
}
/// <summary>
/// Brightness for shiny effect.
/// </summary>
public float brightness
{
get { return this.m_Brightness; }
set
{
value = Mathf.Clamp(value, 0, 1);
if (Mathf.Approximately(this.m_Brightness, value)) return;
this.m_Brightness = value;
SetEffectParamsDirty();
}
}
/// <summary>
/// Gloss factor for shiny effect.
/// </summary>
public float gloss
{
get { return this.m_Gloss; }
set
{
value = Mathf.Clamp(value, 0, 1);
if (Mathf.Approximately(this.m_Gloss, value)) return;
this.m_Gloss = value;
SetEffectParamsDirty();
}
}
/// <summary>
/// Rotation for shiny effect.
/// </summary>
public float rotation
{
get { return this.m_Rotation; }
set
{
if (Mathf.Approximately(this.m_Rotation, value)) return;
this.m_Rotation = value;
SetVerticesDirty();
}
}
/// <summary>
/// The area for effect.
/// </summary>
public EffectArea effectArea
{
get { return this.m_EffectArea; }
set
{
if (this.m_EffectArea == value) return;
this.m_EffectArea = value;
SetVerticesDirty();
}
}
/// <summary>
/// Gets the parameter texture.
/// </summary>
public override ParameterTexture paramTex
{
get { return s_ParamTex; }
}
public EffectPlayer effectPlayer
{
get { return this.m_Player ?? (this.m_Player = new EffectPlayer()); }
}
/// <summary>
/// This function is called when the object becomes enabled and active.
/// </summary>
protected override void OnEnable()
{
base.OnEnable();
this.effectPlayer.OnEnable(f => this.effectFactor = f);
}
/// <summary>
/// This function is called when the behaviour becomes disabled () or inactive.
/// </summary>
protected override void OnDisable()
{
base.OnDisable();
this.effectPlayer.OnDisable();
}
public override Hash128 GetMaterialHash(Material material)
{
if (!this.isActiveAndEnabled || !material || !material.shader)
return k_InvalidHash;
return new Hash128(
(uint) material.GetInstanceID(),
k_ShaderId,
0,
0
);
}
public override void ModifyMaterial(Material newMaterial, Graphic graphic)
{
var connector = GraphicConnector.FindConnector(graphic);
newMaterial.shader = Shader.Find(string.Format("Hidden/{0} (UIShiny)", newMaterial.shader.name));
this.paramTex.RegisterMaterial(newMaterial);
}
/// <summary>
/// Modifies the mesh.
/// </summary>
public override void ModifyMesh(VertexHelper vh, Graphic graphic)
{
if (!this.isActiveAndEnabled)
return;
var normalizedIndex = this.paramTex.GetNormalizedIndex(this);
var rect = this.m_EffectArea.GetEffectArea(vh, this.rectTransform.rect);
// rotation.
var rad = this.m_Rotation * Mathf.Deg2Rad;
var dir = new Vector2(Mathf.Cos(rad), Mathf.Sin(rad));
dir.x *= rect.height / rect.width;
dir = dir.normalized;
// Calculate vertex position.
var vertex = default(UIVertex);
var localMatrix = new Matrix2x3(rect, dir.x, dir.y); // Get local matrix.
for (int i = 0; i < vh.currentVertCount; i++)
{
vh.PopulateUIVertex(ref vertex, i);
Vector2 normalizedPos;
this.connector.GetNormalizedFactor(this.m_EffectArea, i, localMatrix, vertex.position, out normalizedPos);
vertex.uv0 = new Vector2(
Packer.ToFloat(vertex.uv0.x, vertex.uv0.y),
Packer.ToFloat(normalizedPos.y, normalizedIndex)
);
vh.SetUIVertex(vertex, i);
}
}
/// <summary>
/// Play effect.
/// </summary>
public void Play(bool reset = true)
{
this.effectPlayer.Play(reset);
}
/// <summary>
/// Stop effect.
/// </summary>
public void Stop(bool reset = true)
{
this.effectPlayer.Stop(reset);
}
protected override void SetEffectParamsDirty()
{
this.paramTex.SetData(this, 0, this.m_EffectFactor); // param1.x : location
this.paramTex.SetData(this, 1, this.m_Width); // param1.y : width
this.paramTex.SetData(this, 2, this.m_Softness); // param1.z : softness
this.paramTex.SetData(this, 3, this.m_Brightness); // param1.w : blightness
this.paramTex.SetData(this, 4, this.m_Gloss); // param2.x : gloss
}
protected override void SetVerticesDirty()
{
base.SetVerticesDirty();
this._lastRotation = this.m_Rotation;
this._lastEffectArea = this.m_EffectArea;
}
protected override void OnDidApplyAnimationProperties()
{
base.OnDidApplyAnimationProperties();
if (!Mathf.Approximately(this._lastRotation, this.m_Rotation)
|| this._lastEffectArea != this.m_EffectArea)
SetVerticesDirty();
}
}
}

View File

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

View File

@@ -0,0 +1,81 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
namespace Coffee.UIEffects
{
/// <summary>
/// Dissolve effect for uGUI.
/// </summary>
[ExecuteInEditMode]
public class UISyncEffect : BaseMaterialEffect
{
[Tooltip("The target effect to synchronize.")] [SerializeField]
private BaseMeshEffect m_TargetEffect;
public BaseMeshEffect targetEffect
{
get { return this.m_TargetEffect != this ? this.m_TargetEffect : null; }
set
{
if (this.m_TargetEffect == value) return;
this.m_TargetEffect = value;
SetVerticesDirty();
SetMaterialDirty();
SetEffectParamsDirty();
}
}
protected override void OnEnable()
{
if (this.targetEffect) this.targetEffect.syncEffects.Add(this);
base.OnEnable();
}
protected override void OnDisable()
{
if (this.targetEffect) this.targetEffect.syncEffects.Remove(this);
base.OnDisable();
}
public override Hash128 GetMaterialHash(Material baseMaterial)
{
if (!this.isActiveAndEnabled) return k_InvalidHash;
var matEffect = this.targetEffect as BaseMaterialEffect;
if (!matEffect || !matEffect.isActiveAndEnabled) return k_InvalidHash;
return matEffect.GetMaterialHash(baseMaterial);
}
public override void ModifyMaterial(Material newMaterial, Graphic graphic)
{
if (!this.isActiveAndEnabled) return;
var matEffect = this.targetEffect as BaseMaterialEffect;
if (!matEffect || !matEffect.isActiveAndEnabled) return;
matEffect.ModifyMaterial(newMaterial, graphic);
}
public override void ModifyMesh(VertexHelper vh, Graphic graphic)
{
if (!this.isActiveAndEnabled) return;
if (!this.targetEffect || !this.targetEffect.isActiveAndEnabled) return;
this.targetEffect.ModifyMesh(vh, graphic);
}
#if UNITY_EDITOR
protected override void OnValidate()
{
SetVerticesDirty();
SetMaterialDirty();
SetEffectParamsDirty();
}
#endif
}
}

View File

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

View File

@@ -0,0 +1,332 @@
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Serialization;
using System;
namespace Coffee.UIEffects
{
/// <summary>
/// Transition effect.
/// </summary>
[AddComponentMenu("UI/UIEffects/UITransitionEffect", 5)]
public class UITransitionEffect : BaseMaterialEffect
{
/// <summary>
/// Effect mode.
/// </summary>
public enum EffectMode
{
Fade = 1,
Cutoff = 2,
Dissolve = 3,
}
private const uint k_ShaderId = 5 << 3;
private static readonly int k_TransitionTexId = Shader.PropertyToID("_TransitionTex");
private static readonly ParameterTexture s_ParamTex = new ParameterTexture(8, 128, "_ParamTex");
private bool _lastKeepAspectRatio;
private static Texture _defaultTransitionTexture;
[Tooltip("Effect mode.")] [SerializeField]
EffectMode m_EffectMode = EffectMode.Cutoff;
[Tooltip("Effect factor between 0(hidden) and 1(shown).")] [SerializeField] [Range(0, 1)]
float m_EffectFactor = 0.5f;
[Tooltip("Transition texture (single channel texture).")] [SerializeField]
Texture m_TransitionTexture;
[Header("Advanced Option")] [Tooltip("The area for effect.")] [SerializeField]
EffectArea m_EffectArea = EffectArea.RectTransform;
[Tooltip("Keep effect aspect ratio.")] [SerializeField]
bool m_KeepAspectRatio;
[Tooltip("Dissolve edge width.")] [SerializeField] [Range(0, 1)]
float m_DissolveWidth = 0.5f;
[Tooltip("Dissolve edge softness.")] [SerializeField] [Range(0, 1)]
float m_DissolveSoftness = 0.5f;
[Tooltip("Dissolve edge color.")] [SerializeField] [ColorUsage(false)]
Color m_DissolveColor = new Color(0.0f, 0.25f, 1.0f);
[Tooltip("Disable the graphic's raycast target on hidden.")] [SerializeField]
bool m_PassRayOnHidden;
[Header("Effect Player")] [SerializeField]
EffectPlayer m_Player;
/// <summary>
/// Effect factor between 0(no effect) and 1(complete effect).
/// </summary>
public float effectFactor
{
get { return this.m_EffectFactor; }
set
{
value = Mathf.Clamp(value, 0, 1);
if (Mathf.Approximately(this.m_EffectFactor, value)) return;
this.m_EffectFactor = value;
SetEffectParamsDirty();
}
}
/// <summary>
/// Transition texture.
/// </summary>
public Texture transitionTexture
{
get
{
return this.m_TransitionTexture
? this.m_TransitionTexture
: defaultTransitionTexture;
}
set
{
if (this.m_TransitionTexture == value) return;
this.m_TransitionTexture = value;
SetMaterialDirty();
}
}
private static Texture defaultTransitionTexture
{
get
{
return _defaultTransitionTexture
? _defaultTransitionTexture
: (_defaultTransitionTexture = Resources.Load<Texture>("Default-Transition"));
}
}
/// <summary>
/// Effect mode.
/// </summary>
public EffectMode effectMode
{
get { return this.m_EffectMode; }
set
{
if (this.m_EffectMode == value) return;
this.m_EffectMode = value;
SetMaterialDirty();
}
}
/// <summary>
/// Keep aspect ratio.
/// </summary>
public bool keepAspectRatio
{
get { return this.m_KeepAspectRatio; }
set
{
if (this.m_KeepAspectRatio == value) return;
this.m_KeepAspectRatio = value;
SetVerticesDirty();
}
}
/// <summary>
/// Gets the parameter texture.
/// </summary>
public override ParameterTexture paramTex
{
get { return s_ParamTex; }
}
/// <summary>
/// Dissolve edge width.
/// </summary>
public float dissolveWidth
{
get { return this.m_DissolveWidth; }
set
{
value = Mathf.Clamp(value, 0, 1);
if (Mathf.Approximately(this.m_DissolveWidth, value)) return;
this.m_DissolveWidth = value;
SetEffectParamsDirty();
}
}
/// <summary>
/// Dissolve edge softness.
/// </summary>
public float dissolveSoftness
{
get { return this.m_DissolveSoftness; }
set
{
value = Mathf.Clamp(value, 0, 1);
if (Mathf.Approximately(this.m_DissolveSoftness, value)) return;
this.m_DissolveSoftness = value;
SetEffectParamsDirty();
}
}
/// <summary>
/// Dissolve edge color.
/// </summary>
public Color dissolveColor
{
get { return this.m_DissolveColor; }
set
{
if (this.m_DissolveColor == value) return;
this.m_DissolveColor = value;
SetEffectParamsDirty();
}
}
/// <summary>
/// Disable graphic's raycast target on hidden.
/// </summary>
public bool passRayOnHidden
{
get { return this.m_PassRayOnHidden; }
set { this.m_PassRayOnHidden = value; }
}
public EffectPlayer effectPlayer
{
get { return this.m_Player ?? (this.m_Player = new EffectPlayer()); }
}
/// <summary>
/// Show transition.
/// </summary>
public void Show(bool reset = true)
{
this.effectPlayer.loop = false;
this.effectPlayer.Play(reset, f => this.effectFactor = f);
}
/// <summary>
/// Hide transition.
/// </summary>
public void Hide(bool reset = true)
{
this.effectPlayer.loop = false;
this.effectPlayer.Play(reset, f => this.effectFactor = 1 - f);
}
public override Hash128 GetMaterialHash(Material material)
{
if (!this.isActiveAndEnabled || !material || !material.shader)
return k_InvalidHash;
var shaderVariantId = (uint) ((int) this.m_EffectMode << 6);
var resourceId = (uint) this.transitionTexture.GetInstanceID();
return new Hash128(
(uint) material.GetInstanceID(),
k_ShaderId + shaderVariantId,
resourceId,
0
);
}
public override void ModifyMaterial(Material newMaterial, Graphic graphic)
{
var connector = GraphicConnector.FindConnector(graphic);
newMaterial.shader = Shader.Find(string.Format("Hidden/{0} (UITransition)", newMaterial.shader.name));
SetShaderVariants(newMaterial, this.m_EffectMode);
newMaterial.SetTexture(k_TransitionTexId, this.transitionTexture);
this.paramTex.RegisterMaterial(newMaterial);
}
/// <summary>
/// Modifies the mesh.
/// </summary>
public override void ModifyMesh(VertexHelper vh, Graphic graphic)
{
if (!this.isActiveAndEnabled)
{
return;
}
var normalizedIndex = this.paramTex.GetNormalizedIndex(this);
// rect.
var tex = this.transitionTexture;
var aspectRatio = this.m_KeepAspectRatio && tex ? ((float) tex.width) / tex.height : -1;
var rect = this.m_EffectArea.GetEffectArea(vh, this.rectTransform.rect, aspectRatio);
// Set parameters to vertex.
var vertex = default(UIVertex);
var count = vh.currentVertCount;
for (var i = 0; i < count; i++)
{
vh.PopulateUIVertex(ref vertex, i);
float x;
float y;
this.connector.GetPositionFactor(this.m_EffectArea, i, rect, vertex.position, out x, out y);
vertex.uv0 = new Vector2(
Packer.ToFloat(vertex.uv0.x, vertex.uv0.y),
Packer.ToFloat(x, y, normalizedIndex)
);
vh.SetUIVertex(vertex, i);
}
}
/// <summary>
/// This function is called when the object becomes enabled and active.
/// </summary>
protected override void OnEnable()
{
base.OnEnable();
this.effectPlayer.OnEnable(null);
this.effectPlayer.loop = false;
}
/// <summary>
/// This function is called when the behaviour becomes disabled () or inactive.
/// </summary>
protected override void OnDisable()
{
base.OnDisable();
this.effectPlayer.OnDisable();
}
protected override void SetEffectParamsDirty()
{
this.paramTex.SetData(this, 0, this.m_EffectFactor); // param1.x : effect factor
if (this.m_EffectMode == EffectMode.Dissolve)
{
this.paramTex.SetData(this, 1, this.m_DissolveWidth); // param1.y : width
this.paramTex.SetData(this, 2, this.m_DissolveSoftness); // param1.z : softness
this.paramTex.SetData(this, 4, this.m_DissolveColor.r); // param2.x : red
this.paramTex.SetData(this, 5, this.m_DissolveColor.g); // param2.y : green
this.paramTex.SetData(this, 6, this.m_DissolveColor.b); // param2.z : blue
}
// Disable graphic's raycastTarget on hidden.
if (this.m_PassRayOnHidden)
{
this.graphic.raycastTarget = 0 < this.m_EffectFactor;
}
}
protected override void SetVerticesDirty()
{
base.SetVerticesDirty();
this._lastKeepAspectRatio = this.m_KeepAspectRatio;
}
protected override void OnDidApplyAnimationProperties()
{
base.OnDidApplyAnimationProperties();
if (this._lastKeepAspectRatio != this.m_KeepAspectRatio)
SetVerticesDirty();
}
}
}

View File

@@ -0,0 +1,16 @@
fileFormatVersion: 2
guid: 922b805bc01c243e5853d9cbb544118c
timeCreated: 1538827562
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences:
- m_EffectMaterial: {instanceID: 0}
- m_PtexMaterial: {instanceID: 0}
- m_TransitionTexture: {fileID: 2800000, guid: 3e04c247fb2604af186173fce0bc62de,
type: 3}
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: