diff --git a/Assets/GWConquest/Prefabs/UI/PlanetIndicator.prefab b/Assets/GWConquest/Prefabs/UI/PlanetIndicator.prefab index 714b9da..70ce8e5 100644 --- a/Assets/GWConquest/Prefabs/UI/PlanetIndicator.prefab +++ b/Assets/GWConquest/Prefabs/UI/PlanetIndicator.prefab @@ -60,6 +60,7 @@ MonoBehaviour: m_Material: {fileID: 0} m_Color: {r: 0.8, g: 0.25490198, b: 0.14509805, a: 0.62352943} m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} m_Maskable: 1 m_OnCullStateChanged: m_PersistentCalls: @@ -85,7 +86,7 @@ GameObject: - component: {fileID: 2845208572781105551} - component: {fileID: 6883330568249547342} - component: {fileID: 7197385088179281400} - - component: {fileID: 5556159197701511021} + - component: {fileID: 3216987783940624451} m_Layer: 5 m_Name: FactionIcon m_TagString: Untagged @@ -135,6 +136,7 @@ MonoBehaviour: m_Material: {fileID: 0} m_Color: {r: 1, g: 1, b: 1, a: 1} m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} m_Maskable: 1 m_OnCullStateChanged: m_PersistentCalls: @@ -149,7 +151,7 @@ MonoBehaviour: m_FillOrigin: 0 m_UseSpriteMesh: 0 m_PixelsPerUnitMultiplier: 1 ---- !u!114 &5556159197701511021 +--- !u!114 &3216987783940624451 MonoBehaviour: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} @@ -158,12 +160,25 @@ MonoBehaviour: m_GameObject: {fileID: 1004975018085727846} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: e19747de3f5aca642ab2be37e372fb86, type: 3} + m_Script: {fileID: 11500000, guid: 52c162dc854d2f24fa639ba0623de5ef, type: 3} m_Name: m_EditorClassIdentifier: - m_EffectColor: {r: 0, g: 0, b: 0, a: 0.6431373} - m_EffectDistance: {x: 1, y: -1} - m_UseGraphicAlpha: 1 + size: 3.48 + spread: 0.916 + offsetAngle: 90 + offsetDistance: 8 + offset: {x: 0, y: 0} + color: {r: 0, g: 0, b: 0, a: 1} + inset: 0 + blendMode: 0 + useCasterAlpha: 1 + ignoreCasterColor: 0 + colorBleedMode: 0 + shadowAsSibling: 0 + cutout: 0 + baked: 0 + modifiedFromInspector: 0 + bakedShadows: [] --- !u!1 &1425561383975781025 GameObject: m_ObjectHideFlags: 0 @@ -224,6 +239,7 @@ MonoBehaviour: m_Material: {fileID: 0} m_Color: {r: 0.8, g: 0.25490198, b: 0.14509805, a: 0.62352943} m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} m_Maskable: 1 m_OnCullStateChanged: m_PersistentCalls: @@ -298,6 +314,7 @@ MonoBehaviour: m_Material: {fileID: 0} m_Color: {r: 1, g: 1, b: 1, a: 1} m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} m_Maskable: 1 m_OnCullStateChanged: m_PersistentCalls: @@ -348,7 +365,7 @@ RectTransform: - {fileID: 1577843074573127529} - {fileID: 5933915466098524944} m_Father: {fileID: 7384831771431062766} - m_RootOrder: 1 + m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} @@ -526,6 +543,7 @@ MonoBehaviour: m_Material: {fileID: 0} m_Color: {r: 1, g: 0.8901961, b: 0.5686275, a: 0.62352943} m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} m_Maskable: 1 m_OnCullStateChanged: m_PersistentCalls: @@ -600,6 +618,7 @@ MonoBehaviour: m_Material: {fileID: 0} m_Color: {r: 0.681, g: 0.681, b: 0.681, a: 0.99607843} m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} m_Maskable: 1 m_OnCullStateChanged: m_PersistentCalls: @@ -674,6 +693,7 @@ MonoBehaviour: m_Material: {fileID: 0} m_Color: {r: 0.681, g: 0.681, b: 0.681, a: 0.99607843} m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} m_Maskable: 1 m_OnCullStateChanged: m_PersistentCalls: @@ -699,7 +719,7 @@ GameObject: - component: {fileID: 7493439069602050584} - component: {fileID: 8817467615109816757} - component: {fileID: 8517481495962601137} - - component: {fileID: 8442851035215243681} + - component: {fileID: 5092933628985013823} m_Layer: 5 m_Name: Text m_TagString: Untagged @@ -719,7 +739,7 @@ RectTransform: m_LocalScale: {x: 1, y: 1, z: 1} m_Children: [] m_Father: {fileID: 7384831771431062766} - m_RootOrder: 0 + m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} @@ -749,6 +769,7 @@ MonoBehaviour: m_Material: {fileID: 0} m_Color: {r: 0.688, g: 0.688, b: 0.688, a: 1} m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} m_Maskable: 1 m_OnCullStateChanged: m_PersistentCalls: @@ -767,7 +788,7 @@ MonoBehaviour: m_VerticalOverflow: 0 m_LineSpacing: 1 m_Text: MENAXURIE ---- !u!114 &8442851035215243681 +--- !u!114 &5092933628985013823 MonoBehaviour: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} @@ -776,12 +797,25 @@ MonoBehaviour: m_GameObject: {fileID: 3536075192841412823} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: e19747de3f5aca642ab2be37e372fb86, type: 3} + m_Script: {fileID: 11500000, guid: 52c162dc854d2f24fa639ba0623de5ef, type: 3} m_Name: m_EditorClassIdentifier: - m_EffectColor: {r: 0, g: 0, b: 0, a: 0.63529414} - m_EffectDistance: {x: 2, y: -2} - m_UseGraphicAlpha: 1 + size: 3.48 + spread: 0.916 + offsetAngle: 90 + offsetDistance: 8 + offset: {x: 0, y: 0} + color: {r: 0, g: 0, b: 0, a: 1} + inset: 0 + blendMode: 0 + useCasterAlpha: 1 + ignoreCasterColor: 0 + colorBleedMode: 0 + shadowAsSibling: 0 + cutout: 0 + baked: 0 + modifiedFromInspector: 0 + bakedShadows: [] --- !u!1 &4082808148708746503 GameObject: m_ObjectHideFlags: 0 @@ -842,6 +876,7 @@ MonoBehaviour: m_Material: {fileID: 0} m_Color: {r: 0.681, g: 0.681, b: 0.681, a: 0.99607843} m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} m_Maskable: 1 m_OnCullStateChanged: m_PersistentCalls: @@ -916,6 +951,7 @@ MonoBehaviour: m_Material: {fileID: 0} m_Color: {r: 1, g: 0.8901961, b: 0.5686275, a: 0.62352943} m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} m_Maskable: 1 m_OnCullStateChanged: m_PersistentCalls: @@ -1027,6 +1063,7 @@ MonoBehaviour: m_Material: {fileID: 0} m_Color: {r: 0.681, g: 0.681, b: 0.681, a: 0.99607843} m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} m_Maskable: 1 m_OnCullStateChanged: m_PersistentCalls: @@ -1146,8 +1183,8 @@ RectTransform: m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} m_Children: - - {fileID: 7493439069602050584} - {fileID: 3206999086042524838} + - {fileID: 7493439069602050584} - {fileID: 6852626612145593344} m_Father: {fileID: 0} m_RootOrder: 0 @@ -1314,6 +1351,7 @@ MonoBehaviour: m_Material: {fileID: 0} m_Color: {r: 1, g: 0.64446914, b: 0.2688679, a: 1} m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} m_Maskable: 1 m_OnCullStateChanged: m_PersistentCalls: diff --git a/Assets/GWConquest/Prefabs/UI/PlanetIndicatorDistrictSymbol.prefab b/Assets/GWConquest/Prefabs/UI/PlanetIndicatorDistrictSymbol.prefab index 8c17924..3d135d6 100644 --- a/Assets/GWConquest/Prefabs/UI/PlanetIndicatorDistrictSymbol.prefab +++ b/Assets/GWConquest/Prefabs/UI/PlanetIndicatorDistrictSymbol.prefab @@ -11,7 +11,7 @@ GameObject: - component: {fileID: 7541130419680964749} - component: {fileID: 7541130419680964747} - component: {fileID: 7541130419680964746} - - component: {fileID: 6281905439376641608} + - component: {fileID: 5485887525763253888} m_Layer: 5 m_Name: PlanetIndicatorDistrictSymbol m_TagString: Untagged @@ -62,6 +62,7 @@ MonoBehaviour: m_Material: {fileID: 0} m_Color: {r: 1, g: 1, b: 1, a: 1} m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} m_Maskable: 1 m_OnCullStateChanged: m_PersistentCalls: @@ -76,7 +77,7 @@ MonoBehaviour: m_FillOrigin: 0 m_UseSpriteMesh: 0 m_PixelsPerUnitMultiplier: 1 ---- !u!114 &6281905439376641608 +--- !u!114 &5485887525763253888 MonoBehaviour: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} @@ -85,12 +86,25 @@ MonoBehaviour: m_GameObject: {fileID: 7541130419680964748} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: e19747de3f5aca642ab2be37e372fb86, type: 3} + m_Script: {fileID: 11500000, guid: 52c162dc854d2f24fa639ba0623de5ef, type: 3} m_Name: m_EditorClassIdentifier: - m_EffectColor: {r: 0, g: 0, b: 0, a: 0.63529414} - m_EffectDistance: {x: 1, y: -1} - m_UseGraphicAlpha: 1 + size: 3.48 + spread: 0.916 + offsetAngle: 90 + offsetDistance: 8 + offset: {x: 0, y: 0} + color: {r: 0, g: 0, b: 0, a: 1} + inset: 0 + blendMode: 0 + useCasterAlpha: 1 + ignoreCasterColor: 0 + colorBleedMode: 0 + shadowAsSibling: 0 + cutout: 0 + baked: 0 + modifiedFromInspector: 0 + bakedShadows: [] --- !u!1 &8644822413282706300 GameObject: m_ObjectHideFlags: 0 @@ -102,7 +116,7 @@ GameObject: - component: {fileID: 5640206779338511740} - component: {fileID: 8489971881928985428} - component: {fileID: 2380150125148524420} - - component: {fileID: 7035351003660383945} + - component: {fileID: 1054513047492580219} m_Layer: 5 m_Name: Image m_TagString: Untagged @@ -152,6 +166,7 @@ MonoBehaviour: m_Material: {fileID: 0} m_Color: {r: 1, g: 1, b: 1, a: 1} m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} m_Maskable: 1 m_OnCullStateChanged: m_PersistentCalls: @@ -166,7 +181,7 @@ MonoBehaviour: m_FillOrigin: 0 m_UseSpriteMesh: 0 m_PixelsPerUnitMultiplier: 1 ---- !u!114 &7035351003660383945 +--- !u!114 &1054513047492580219 MonoBehaviour: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} @@ -175,9 +190,22 @@ MonoBehaviour: m_GameObject: {fileID: 8644822413282706300} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: e19747de3f5aca642ab2be37e372fb86, type: 3} + m_Script: {fileID: 11500000, guid: 52c162dc854d2f24fa639ba0623de5ef, type: 3} m_Name: m_EditorClassIdentifier: - m_EffectColor: {r: 0, g: 0, b: 0, a: 0.63529414} - m_EffectDistance: {x: 0.5, y: -0.5} - m_UseGraphicAlpha: 1 + size: 3.48 + spread: 0.916 + offsetAngle: 90 + offsetDistance: 8 + offset: {x: 0, y: 0} + color: {r: 0, g: 0, b: 0, a: 1} + inset: 0 + blendMode: 0 + useCasterAlpha: 1 + ignoreCasterColor: 0 + colorBleedMode: 0 + shadowAsSibling: 0 + cutout: 0 + baked: 0 + modifiedFromInspector: 0 + bakedShadows: [] diff --git a/Assets/Le Tai's Asset.meta b/Assets/Le Tai's Asset.meta new file mode 100644 index 0000000..be8723d --- /dev/null +++ b/Assets/Le Tai's Asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: e65753410138a4801a6caf79d625ccd1 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Le Tai's Asset/TrueShadow.meta b/Assets/Le Tai's Asset/TrueShadow.meta new file mode 100644 index 0000000..5d9e00a --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 345755c04661c49208b308ceef47c557 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Le Tai's Asset/TrueShadow/LeTai.TrueShadow.asmdef b/Assets/Le Tai's Asset/TrueShadow/LeTai.TrueShadow.asmdef new file mode 100644 index 0000000..644d226 --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/LeTai.TrueShadow.asmdef @@ -0,0 +1,13 @@ +{ + "name": "LeTai.TrueShadow", + "references": [], + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": true, + "defineConstraints": [], + "versionDefines": [], + "noEngineReferences": false +} \ No newline at end of file diff --git a/Assets/Le Tai's Asset/TrueShadow/LeTai.TrueShadow.asmdef.meta b/Assets/Le Tai's Asset/TrueShadow/LeTai.TrueShadow.asmdef.meta new file mode 100644 index 0000000..ac00e7c --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/LeTai.TrueShadow.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 7ab3663edede26740845931880bf22af +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Le Tai's Asset/TrueShadow/Offline Documentation.pdf b/Assets/Le Tai's Asset/TrueShadow/Offline Documentation.pdf new file mode 100644 index 0000000..2603586 Binary files /dev/null and b/Assets/Le Tai's Asset/TrueShadow/Offline Documentation.pdf differ diff --git a/Assets/Le Tai's Asset/TrueShadow/Offline Documentation.pdf.meta b/Assets/Le Tai's Asset/TrueShadow/Offline Documentation.pdf.meta new file mode 100644 index 0000000..f375de1 --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Offline Documentation.pdf.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: c4e2187761ed8294780562fc58e8205e +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Le Tai's Asset/TrueShadow/Online Documentation (Recommended).txt b/Assets/Le Tai's Asset/TrueShadow/Online Documentation (Recommended).txt new file mode 100644 index 0000000..3ce6617 --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Online Documentation (Recommended).txt @@ -0,0 +1 @@ +https://leloctai.com/trueshadow/docs/ \ No newline at end of file diff --git a/Assets/Le Tai's Asset/TrueShadow/Online Documentation (Recommended).txt.meta b/Assets/Le Tai's Asset/TrueShadow/Online Documentation (Recommended).txt.meta new file mode 100644 index 0000000..66540bc --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Online Documentation (Recommended).txt.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 63a70f84fa489504abf9f477bd12d05e +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Le Tai's Asset/TrueShadow/Resources.meta b/Assets/Le Tai's Asset/TrueShadow/Resources.meta new file mode 100644 index 0000000..2afc3fa --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Resources.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d5929e1d292a9d84180571372bbb84f6 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Le Tai's Asset/TrueShadow/Resources/Shaders.meta b/Assets/Le Tai's Asset/TrueShadow/Resources/Shaders.meta new file mode 100644 index 0000000..5a9e700 --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Resources/Shaders.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 316e6d240db2e974d97ea072bee96163 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/EfficientBlur.shader b/Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/EfficientBlur.shader new file mode 100644 index 0000000..45c96d7 --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/EfficientBlur.shader @@ -0,0 +1,103 @@ +Shader "Hidden/EfficientBlur" +{ + Properties + { + _MainTex ("Texture", 2D) = "white" {} + } + + CGINCLUDE + #include "UnityCG.cginc" + + sampler2D _MainTex; + half4 _MainTex_TexelSize; + half4 _MainTex_ST; + + uniform half _Radius; + + struct v2f + { + half4 vertex : SV_POSITION; + half4 texcoord : TEXCOORD0; + }; + + /*struct appdata + { + half4 vertex : POSITION; + half2 texcoord: TEXCOORD0; + }*/ + + v2f vert(appdata_img v) + { + v2f o; + o.vertex = UnityObjectToClipPos(v.vertex); + + half4 offset = half2(-0.5h, 0.5h).xxyy; //-x, -y, x, y + offset *= _MainTex_TexelSize.xyxy; + offset *= _Radius; + o.texcoord = v.texcoord.xyxy + offset; + + return o; + } + + half4 frag(v2f i) : SV_Target + { +// half4 o = +// tex2D(_MainTex, i.texcoord.xw); +// o += tex2D(_MainTex, i.texcoord.zw); +// o += tex2D(_MainTex, i.texcoord.xy); +// o += tex2D(_MainTex, i.texcoord.zy); +// o /= 4.0; + + + //Pray to the compiler god these will MAD + half4 o = + tex2D(_MainTex, i.texcoord.xw) / 4.0h; + o += tex2D(_MainTex, i.texcoord.zw) / 4.0h; + o += tex2D(_MainTex, i.texcoord.xy) / 4.0h; + o += tex2D(_MainTex, i.texcoord.zy) / 4.0h; + + return o; + } + ENDCG + + SubShader + { + Cull Off ZWrite Off ZTest Always Blend Off + + Pass + { + CGPROGRAM + #pragma vertex vert + #pragma fragment frag + ENDCG + } + + Pass + { + CGPROGRAM + //Crop before blur + #pragma vertex vertCrop + #pragma fragment frag + + half4 _CropRegion; + + half2 getNewUV(half2 oldUV) + { + return lerp(_CropRegion.xy, _CropRegion.zw, oldUV); + } + + v2f vertCrop(appdata_img v) + { + v2f o = vert(v); + + o.texcoord.xy = getNewUV(o.texcoord.xy); + o.texcoord.zw = getNewUV(o.texcoord.zw); + + return o; + } + ENDCG + } + } + + FallBack Off +} diff --git a/Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/EfficientBlur.shader.meta b/Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/EfficientBlur.shader.meta new file mode 100644 index 0000000..c42e372 --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/EfficientBlur.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 11ecd49e831fe6c4f8f68b583206390c +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/ImprintPostProcess.shader b/Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/ImprintPostProcess.shader new file mode 100644 index 0000000..4248d0f --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/ImprintPostProcess.shader @@ -0,0 +1,61 @@ +Shader "Hidden/TrueShadow/ImprintPostProcess" +{ + Properties + { + _MainTex ("Texture", 2D) = "white" {} + } + SubShader + { + Cull Off ZWrite Off ZTest Always + + Pass + { + CGPROGRAM + #pragma vertex vert + #pragma fragment frag + #pragma multi_compile_local __ BLEACH + #pragma multi_compile_local __ INSET + + #include "UnityCG.cginc" + + struct appdata + { + float4 vertex : POSITION; + float2 uv : TEXCOORD0; + }; + + struct v2f + { + float2 uv : TEXCOORD0; + float4 vertex : SV_POSITION; + }; + + v2f vert(appdata v) + { + v2f o; + o.vertex = UnityObjectToClipPos(v.vertex); + o.uv = v.uv; + return o; + } + + sampler2D _MainTex; + + half4 frag(v2f i) : SV_Target + { + #if BLEACH + half4 color = half4(1,1,1, tex2D(_MainTex, i.uv).a); + #else + half4 color = tex2D(_MainTex, i.uv); + #endif + + #if INSET + color.a = 1 - color.a; + #endif + + color.rgb*=color.a; + return color; + } + ENDCG + } + } +} diff --git a/Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/ImprintPostProcess.shader.meta b/Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/ImprintPostProcess.shader.meta new file mode 100644 index 0000000..647f43d --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/ImprintPostProcess.shader.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 56c6b737089145c590ee9874dc3c09f7 +timeCreated: 1602477197 \ No newline at end of file diff --git a/Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/ShadowCutout.shader b/Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/ShadowCutout.shader new file mode 100644 index 0000000..c0d32be --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/ShadowCutout.shader @@ -0,0 +1,59 @@ +Shader "Hidden/TrueShadow/Cutout" +{ + Properties + { + _MainTex ("Texture", 2D) = "white" {} + _Offset ("Offset", Vector) = (0,0,0,0) + } + SubShader + { + Cull Off ZWrite Off ZTest Always + Blend Zero OneMinusSrcAlpha, Zero OneMinusSrcAlpha + BlendOp Add, Add +// ColorMask a + + Pass + { + CGPROGRAM + #pragma vertex vert + #pragma fragment frag + + #include "UnityCG.cginc" + + struct appdata + { + float4 vertex : POSITION; + float2 uv : TEXCOORD0; + }; + + struct v2f + { + float2 uv : TEXCOORD0; + float4 vertex : SV_POSITION; + }; + + v2f vert(appdata v) + { + v2f o; + o.vertex = UnityObjectToClipPos(v.vertex); + o.uv = v.uv; + return o; + } + + uniform sampler2D _MainTex; + uniform float2 _Offset; + uniform float _OverflowAlpha; + + fixed4 frag(v2f i) : SV_Target + { + float2 uv = i.uv + _Offset; + + if (any(uv > 1) || any(uv < 0)) + return _OverflowAlpha; + + return fixed4(0, 0, 0, tex2D(_MainTex, uv).a); + } + ENDCG + } + } +} diff --git a/Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/ShadowCutout.shader.meta b/Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/ShadowCutout.shader.meta new file mode 100644 index 0000000..f814c0c --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/ShadowCutout.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 77361e944e5710f4993a94af0720a22f +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/ShadowPostProcess.shader b/Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/ShadowPostProcess.shader new file mode 100644 index 0000000..bf5116b --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/ShadowPostProcess.shader @@ -0,0 +1,69 @@ +Shader "Hidden/TrueShadow/PostProcess" +{ + Properties + { + _MainTex ("Texture", 2D) = "white" {} + _Offset ("Offset", Vector) = (0,0,0,0) + } + SubShader + { + Cull Off ZWrite Off ZTest Always + + Pass + { + CGPROGRAM + #pragma vertex vert + #pragma fragment frag + + #include "UnityCG.cginc" + + struct appdata + { + float4 vertex : POSITION; + float2 uv : TEXCOORD0; + }; + + struct v2f + { + float2 uv : TEXCOORD0; + float4 vertex : SV_POSITION; + }; + + v2f vert(appdata v) + { + v2f o; + o.vertex = UnityObjectToClipPos(v.vertex); + o.uv = v.uv; + return o; + } + + uniform sampler2D _ShadowTex; + uniform sampler2D _MainTex; + uniform float2 _Offset; + uniform float _OverflowAlpha; + uniform float _AlphaMultiplier; + + fixed4 frag(v2f i) : SV_Target + { + half4 shadow = tex2D(_ShadowTex, i.uv); + + half alpha = shadow.a; + half alphaBoosted = saturate(alpha * _AlphaMultiplier); + shadow.a = alphaBoosted; + shadow.rgb = shadow.rgb / alpha * alphaBoosted; + + float cutOut; + float2 cutoutUv = i.uv + _Offset; + if (any(cutoutUv > 1) || any(cutoutUv < 0)) + cutOut = _OverflowAlpha; + else + cutOut = tex2D(_MainTex, cutoutUv).a; + + shadow *= 1 - cutOut; + + return shadow; + } + ENDCG + } + } +} diff --git a/Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/ShadowPostProcess.shader.meta b/Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/ShadowPostProcess.shader.meta new file mode 100644 index 0000000..3028b46 --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/ShadowPostProcess.shader.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 64f3fdefd5e7411dae947574155e2253 +timeCreated: 1614411795 \ No newline at end of file diff --git a/Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/TrueShadow-Additive.shader b/Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/TrueShadow-Additive.shader new file mode 100644 index 0000000..6c738af --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/TrueShadow-Additive.shader @@ -0,0 +1,54 @@ +Shader "UI/TrueShadow-Additive" +{ + Properties + { + [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {} + + _StencilComp ("Stencil Comparison", Float) = 8 + _Stencil ("Stencil ID", Float) = 0 + _StencilOp ("Stencil Operation", Float) = 0 + _StencilWriteMask ("Stencil Write Mask", Float) = 255 + _StencilReadMask ("Stencil Read Mask", Float) = 255 + + _ColorMask ("Color Mask", Float) = 15 + + [Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0 + } + + SubShader + { + Tags + { + "Queue"="Transparent" + "IgnoreProjector"="True" + "RenderType"="Transparent" + "PreviewType"="Plane" + "CanUseSpriteAtlas"="True" + } + + Stencil + { + Ref [_Stencil] + Comp [_StencilComp] + Pass [_StencilOp] + ReadMask [_StencilReadMask] + WriteMask [_StencilWriteMask] + } + + Cull Off + Lighting Off + ZWrite Off + ZTest [unity_GUIZTestMode] + Blend One One + ColorMask [_ColorMask] + + Pass + { + CGPROGRAM + #include "TrueShadow.cginc" + #pragma vertex vert + #pragma fragment frag + ENDCG + } + } +} diff --git a/Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/TrueShadow-Additive.shader.meta b/Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/TrueShadow-Additive.shader.meta new file mode 100644 index 0000000..fec4ade --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/TrueShadow-Additive.shader.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 6c0e0b60ad64412c8cfcffd1553dcc06 +timeCreated: 1594096623 \ No newline at end of file diff --git a/Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/TrueShadow-Multiply.shader b/Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/TrueShadow-Multiply.shader new file mode 100644 index 0000000..9005267 --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/TrueShadow-Multiply.shader @@ -0,0 +1,56 @@ +Shader "UI/TrueShadow-Multiply" +{ + Properties + { + [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {} + + _StencilComp ("Stencil Comparison", Float) = 8 + _Stencil ("Stencil ID", Float) = 0 + _StencilOp ("Stencil Operation", Float) = 0 + _StencilWriteMask ("Stencil Write Mask", Float) = 255 + _StencilReadMask ("Stencil Read Mask", Float) = 255 + + _ColorMask ("Color Mask", Float) = 15 + + [Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0 + } + + SubShader + { + Tags + { + "Queue"="Transparent" + "IgnoreProjector"="True" + "RenderType"="Transparent" + "PreviewType"="Plane" + "CanUseSpriteAtlas"="True" + } + + Stencil + { + Ref [_Stencil] + Comp [_StencilComp] + Pass [_StencilOp] + ReadMask [_StencilReadMask] + WriteMask [_StencilWriteMask] + } + + Cull Off + Lighting Off + ZWrite Off + ZTest [unity_GUIZTestMode] + Blend DstColor Zero + ColorMask [_ColorMask] + + Pass + { + CGPROGRAM + #define DO_BLEND_POSTPROCESS color.rgb = 1 - color.a + color.rgb; + + #include "TrueShadow.cginc" + #pragma vertex vert + #pragma fragment frag + ENDCG + } + } +} diff --git a/Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/TrueShadow-Multiply.shader.meta b/Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/TrueShadow-Multiply.shader.meta new file mode 100644 index 0000000..681b96f --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/TrueShadow-Multiply.shader.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 84318cb7c8604c59a985a677d93e4048 +timeCreated: 1594096631 \ No newline at end of file diff --git a/Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/TrueShadow-Normal.shader b/Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/TrueShadow-Normal.shader new file mode 100644 index 0000000..757339d --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/TrueShadow-Normal.shader @@ -0,0 +1,54 @@ +Shader "UI/TrueShadow-Normal" +{ + Properties + { + [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {} + + _StencilComp ("Stencil Comparison", Float) = 8 + _Stencil ("Stencil ID", Float) = 0 + _StencilOp ("Stencil Operation", Float) = 0 + _StencilWriteMask ("Stencil Write Mask", Float) = 255 + _StencilReadMask ("Stencil Read Mask", Float) = 255 + + _ColorMask ("Color Mask", Float) = 15 + + [Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0 + } + + SubShader + { + Tags + { + "Queue"="Transparent" + "IgnoreProjector"="True" + "RenderType"="Transparent" + "PreviewType"="Plane" + "CanUseSpriteAtlas"="True" + } + + Stencil + { + Ref [_Stencil] + Comp [_StencilComp] + Pass [_StencilOp] + ReadMask [_StencilReadMask] + WriteMask [_StencilWriteMask] + } + + Cull Off + Lighting Off + ZWrite Off + ZTest [unity_GUIZTestMode] + Blend One OneMinusSrcAlpha + ColorMask [_ColorMask] + + Pass + { + CGPROGRAM + #include "TrueShadow.cginc" + #pragma vertex vert + #pragma fragment frag + ENDCG + } + } +} diff --git a/Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/TrueShadow-Normal.shader.meta b/Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/TrueShadow-Normal.shader.meta new file mode 100644 index 0000000..395c49d --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/TrueShadow-Normal.shader.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: d81692c4b57a49aabf43f3423dc99e51 +timeCreated: 1594094098 \ No newline at end of file diff --git a/Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/TrueShadow-Screen.shader b/Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/TrueShadow-Screen.shader new file mode 100644 index 0000000..0c13328 --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/TrueShadow-Screen.shader @@ -0,0 +1,54 @@ +Shader "UI/TrueShadow-Screen" +{ + Properties + { + [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {} + + _StencilComp ("Stencil Comparison", Float) = 8 + _Stencil ("Stencil ID", Float) = 0 + _StencilOp ("Stencil Operation", Float) = 0 + _StencilWriteMask ("Stencil Write Mask", Float) = 255 + _StencilReadMask ("Stencil Read Mask", Float) = 255 + + _ColorMask ("Color Mask", Float) = 15 + + [Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0 + } + + SubShader + { + Tags + { + "Queue"="Transparent" + "IgnoreProjector"="True" + "RenderType"="Transparent" + "PreviewType"="Plane" + "CanUseSpriteAtlas"="True" + } + + Stencil + { + Ref [_Stencil] + Comp [_StencilComp] + Pass [_StencilOp] + ReadMask [_StencilReadMask] + WriteMask [_StencilWriteMask] + } + + Cull Off + Lighting Off + ZWrite Off + ZTest [unity_GUIZTestMode] + Blend OneMinusDstColor One + ColorMask [_ColorMask] + + Pass + { + CGPROGRAM + #include "TrueShadow.cginc" + #pragma vertex vert + #pragma fragment frag + ENDCG + } + } +} diff --git a/Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/TrueShadow-Screen.shader.meta b/Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/TrueShadow-Screen.shader.meta new file mode 100644 index 0000000..6a4983a --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/TrueShadow-Screen.shader.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: f15b379e29b64cb1ae050f22d002148a +timeCreated: 1610185734 \ No newline at end of file diff --git a/Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/TrueShadow.cginc b/Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/TrueShadow.cginc new file mode 100644 index 0000000..b3f9651 --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/TrueShadow.cginc @@ -0,0 +1,62 @@ +#pragma target 2.0 + +#include "UnityCG.cginc" +#include "UnityUI.cginc" + +#pragma multi_compile_local _ UNITY_UI_CLIP_RECT +#pragma multi_compile_local _ UNITY_UI_ALPHACLIP + +struct appdata_t +{ + float4 vertex : POSITION; + float4 color : COLOR; + float2 texcoord : TEXCOORD0; + UNITY_VERTEX_INPUT_INSTANCE_ID +}; + +struct v2f +{ + float4 vertex : SV_POSITION; + fixed4 color : COLOR; + float2 texcoord : TEXCOORD0; + float4 worldPosition : TEXCOORD1; + UNITY_VERTEX_OUTPUT_STEREO +}; + +sampler2D _MainTex; +fixed4 _TextureSampleAdd; +float4 _ClipRect; +float4 _MainTex_ST; + +v2f vert(appdata_t v) +{ + v2f OUT; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT); + OUT.worldPosition = v.vertex; + OUT.vertex = UnityObjectToClipPos(OUT.worldPosition); + OUT.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex); + OUT.color.a = v.color.a; + OUT.color.rgb = v.color.rgb * v.color.a; + + return OUT; +} + +fixed4 frag(v2f IN) : SV_Target +{ + float4 color = (tex2D(_MainTex, IN.texcoord) + _TextureSampleAdd) * IN.color; + + #ifdef UNITY_UI_CLIP_RECT + color.a *= UnityGet2DClipping(IN.worldPosition.xy, _ClipRect); + #endif + + #ifdef UNITY_UI_ALPHACLIP + clip (color.a - 0.001); + #endif + + #ifdef DO_BLEND_POSTPROCESS + DO_BLEND_POSTPROCESS + #endif + + return color; +} diff --git a/Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/TrueShadow.cginc.meta b/Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/TrueShadow.cginc.meta new file mode 100644 index 0000000..ec45305 --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Resources/Shaders/TrueShadow.cginc.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 3521747ea3d847a58d919a5a4d9f0fc6 +timeCreated: 1594096488 \ No newline at end of file diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts.meta b/Assets/Le Tai's Asset/TrueShadow/Scripts.meta new file mode 100644 index 0000000..ad432eb --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: adf483f749616b14ab22fc1bac9a154e +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/DebugSettings.cs b/Assets/Le Tai's Asset/TrueShadow/Scripts/DebugSettings.cs new file mode 100644 index 0000000..2cbf7fb --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/DebugSettings.cs @@ -0,0 +1,78 @@ +#if LETAI_TRUESHADOW_DEBUG +using System; +using UnityEngine; +#if UNITY_EDITOR +using System.IO; +using UnityEditor; + +#endif + +namespace LeTai.TrueShadow +{ +[Serializable] +public class DebugSettings +{ + const string FILE_PATH = "ProjectSettings/TrueShadowDebugSettings.json"; + + static DebugSettings instance; + + public static DebugSettings Instance + { + get + { + if (instance == null) + { +#if UNITY_EDITOR + try + { + if (File.Exists(FILE_PATH)) + instance = JsonUtility.FromJson(File.ReadAllText(FILE_PATH)); + else + Create(); + } + catch (Exception) + { + Create(); + } +#else + Create(); +#endif + } + + return instance; + } + } + + static void Create() + { + instance = new DebugSettings(); + instance.Save(); + } + + public bool showObjects = true; + + void Save() + { +#if UNITY_EDITOR + File.WriteAllText(FILE_PATH, JsonUtility.ToJson(this, true)); +#endif + } + +#if UNITY_EDITOR + [MenuItem("Tools/Show Objects")] + static void ShowObjects() + { + Instance.showObjects = true; + Instance.Save(); + } + + [MenuItem("Tools/Hide Objects")] + static void HideObjects() + { + Instance.showObjects = false; + Instance.Save(); + } +#endif +} +} +#endif diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/DebugSettings.cs.meta b/Assets/Le Tai's Asset/TrueShadow/Scripts/DebugSettings.cs.meta new file mode 100644 index 0000000..fa54428 --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/DebugSettings.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 15f8726536514604185aa6c94cb75b8b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor.meta b/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor.meta new file mode 100644 index 0000000..5012873 --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 711abe41546958b459a552baad798f17 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/AutoCustomScriptingDefine.cs b/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/AutoCustomScriptingDefine.cs new file mode 100644 index 0000000..979f7cf --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/AutoCustomScriptingDefine.cs @@ -0,0 +1,33 @@ +using System.Collections.Generic; +using System.Linq; +using UnityEditor; + +namespace LeTai.TrueShadow.Editor +{ +[InitializeOnLoad] +public static class AutoCustomScriptingDefine +{ + internal static readonly HashSet SYMBOLS = new HashSet {"LETAI_TRUESHADOW"}; + + static AutoCustomScriptingDefine() + { + Apply(); + } + + public static void Apply() + { + AddMissingSymbols(EditorUserBuildSettings.activeBuildTarget); + } + + static void AddMissingSymbols(BuildTarget buildTarget) + { + var currentGroup = BuildPipeline.GetBuildTargetGroup(buildTarget); + var defines = PlayerSettings.GetScriptingDefineSymbolsForGroup(currentGroup).Split(';').ToList(); + var missing = SYMBOLS.Except(defines).ToList(); + defines.AddRange(missing); + + if (missing.Count > 0) + PlayerSettings.SetScriptingDefineSymbolsForGroup(currentGroup, string.Join(";", defines)); + } +} +} diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/AutoCustomScriptingDefine.cs.meta b/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/AutoCustomScriptingDefine.cs.meta new file mode 100644 index 0000000..356c2ca --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/AutoCustomScriptingDefine.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 150508a406864b6ca9ad4e38e75cb333 +timeCreated: 1597477199 \ No newline at end of file diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/EditorProperty.cs b/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/EditorProperty.cs new file mode 100644 index 0000000..d73ac6e --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/EditorProperty.cs @@ -0,0 +1,59 @@ +using System; +using System.Globalization; +using System.Reflection; +using UnityEditor; + +namespace LeTai.TrueShadow.Editor +{ +public class EditorProperty +{ + public readonly SerializedProperty serializedProperty; + + readonly SerializedObject serializedObject; + readonly MethodInfo propertySetter; + readonly SerializedProperty dirtyFlag; + + public EditorProperty(SerializedObject obj, string name) + { + var propertyName = char.ToLowerInvariant(name[0]) + name.Substring(1); + serializedObject = obj; + serializedProperty = serializedObject.FindProperty(propertyName); + propertySetter = serializedObject.targetObject.GetType().GetProperty(name).SetMethod; + dirtyFlag = serializedObject.FindProperty("modifiedFromInspector"); + } + + public void Draw() + { + using (var scope = new EditorGUI.ChangeCheckScope()) + { + EditorGUILayout.PropertyField(serializedProperty); + + if (!scope.changed) + return; + + dirtyFlag.boolValue = true; + serializedObject.ApplyModifiedProperties(); + + foreach (var target in serializedObject.targetObjects) + { + switch (serializedProperty.propertyType) + { + case SerializedPropertyType.Float: + propertySetter.Invoke(target, new object[] {serializedProperty.floatValue}); + break; + case SerializedPropertyType.Enum: + propertySetter.Invoke(target, new object[] {serializedProperty.enumValueIndex}); + break; + case SerializedPropertyType.Boolean: + propertySetter.Invoke(target, new object[] {serializedProperty.boolValue}); + break; + case SerializedPropertyType.Color: + propertySetter.Invoke(target, new object[] {serializedProperty.colorValue}); + break; + default: throw new NotImplementedException(); + } + } + } + } +} +} diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/EditorProperty.cs.meta b/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/EditorProperty.cs.meta new file mode 100644 index 0000000..f2f6944 --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/EditorProperty.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 1f9db8b2544c48c2a7f13b46f27236e8 +timeCreated: 1594635819 \ No newline at end of file diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/InlineToolbar.cs b/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/InlineToolbar.cs new file mode 100644 index 0000000..ef96e7e --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/InlineToolbar.cs @@ -0,0 +1,67 @@ +using UnityEditor; +using UnityEngine; + +namespace LeTai.TrueShadow.Editor +{ +[CustomPropertyDrawer(typeof(InsetToggleAttribute))] +public class InsetToggle : InlineToolbar +{ + static readonly Texture OUTER_SHADOW_TEXTURE = Utility.FindAsset("Outer Shadow"); + static readonly Texture INNER_SHADOW_TEXTURE = Utility.FindAsset("Inner Shadow"); + + static InsetToggle() + { + textures = new[] {OUTER_SHADOW_TEXTURE, INNER_SHADOW_TEXTURE}; + } +} + +public class InlineToolbar : PropertyDrawer +{ + protected static Texture[] textures; + + static readonly GUIStyle LABEL_STYLE = new GUIStyle(EditorStyles.label) + {alignment = TextAnchor.MiddleLeft,}; + + public override void OnGUI(Rect position, SerializedProperty property, + GUIContent label) + { + using (var propScope = new EditorGUI.PropertyScope(position, label, property)) + { + int id = GUIUtility.GetControlID(FocusType.Keyboard, position); + var lableRect = position; + lableRect.y += (lableRect.height - EditorGUIUtility.singleLineHeight) / 2; + lableRect.height = EditorGUIUtility.singleLineHeight; + var toolbarRect = EditorGUI.PrefixLabel(lableRect, id, propScope.content, LABEL_STYLE); + toolbarRect.width = EditorGUIUtility.singleLineHeight * 4f; + toolbarRect.height = position.height; + toolbarRect.y = position.y; + + using (var changeScope = new EditorGUI.ChangeCheckScope()) + { + var isOn = GUI.Toolbar(toolbarRect, property.boolValue ? 1 : 0, textures) == 1; + var changed = changeScope.changed; + + if (Event.current.type == EventType.KeyDown && + GUIUtility.keyboardControl == id) + { + if (Event.current.keyCode == KeyCode.Return || + Event.current.keyCode == KeyCode.KeypadEnter || + Event.current.keyCode == KeyCode.Space) + { + changed = GUI.changed = true; + isOn = !isOn; + } + } + + if (changed) + property.boolValue = isOn; + } + } + } + + public override float GetPropertyHeight(SerializedProperty property, GUIContent label) + { + return EditorGUIUtility.singleLineHeight * 2f; + } +} +} diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/InlineToolbar.cs.meta b/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/InlineToolbar.cs.meta new file mode 100644 index 0000000..ba82f12 --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/InlineToolbar.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: ea4346ac17c04991bf233f1dc0def012 +timeCreated: 1602580020 \ No newline at end of file diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/KnobPropertyDrawer.cs b/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/KnobPropertyDrawer.cs new file mode 100644 index 0000000..d45cead --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/KnobPropertyDrawer.cs @@ -0,0 +1,184 @@ +using System; +using System.Reflection; +using UnityEditor; +using UnityEngine; +using static LeTai.TrueShadow.Math; +using EGU = UnityEditor.EditorGUIUtility; + +namespace LeTai.TrueShadow.Editor +{ +[CustomPropertyDrawer(typeof(KnobAttribute))] +public class KnobPropertyDrawer : PropertyDrawer +{ + public static bool procrastinationMode = false; + + static readonly Texture2D KNOB_BG_TEXTURE = Utility.FindAsset("Knob_BG"); + static readonly Texture2D KNOB_FG_TEXTURE = Utility.FindAsset("Knob_FG"); + + static readonly MethodInfo DO_FLOAT_FIELD_METHOD; + static readonly FieldInfo RECYCLED_EDITOR_PROPERTY; + static readonly FieldInfo FLOAT_FIELD_FORMAT_STRING_CONST; + + static readonly Color KNOB_BG_COLOR; + static readonly Color KNOB_FG_COLOR; + static readonly Color KNOB_FG_COLOR_ACTIVE; + + static KnobPropertyDrawer() + { + var editorGUIType = typeof(EditorGUI); + + const BindingFlags flags = BindingFlags.NonPublic | BindingFlags.Static; + + Type[] argumentTypes = { + Assembly.GetAssembly(editorGUIType).GetType("UnityEditor.EditorGUI+RecycledTextEditor"), + typeof(Rect), + typeof(Rect), + typeof(int), + typeof(float), + typeof(string), + typeof(GUIStyle), + typeof(bool) + }; + DO_FLOAT_FIELD_METHOD = editorGUIType.GetMethod("DoFloatField", flags, null, argumentTypes, null); + RECYCLED_EDITOR_PROPERTY = editorGUIType.GetField("s_RecycledEditor", flags); + FLOAT_FIELD_FORMAT_STRING_CONST = editorGUIType.GetField("kFloatFieldFormatString", flags); + + if (EGU.isProSkin) + { + KNOB_BG_COLOR = new Color(.164f, .164f, .164f); + KNOB_FG_COLOR = new Color(.701f, .701f, .701f); + KNOB_FG_COLOR_ACTIVE = new Color(.49f, .67f, .94f); + } + else + { + KNOB_BG_COLOR = new Color(.941f, .941f, .941f); + KNOB_FG_COLOR = new Color(.239f, .239f, .239f); + KNOB_FG_COLOR_ACTIVE = new Color(.054f, .274f, .549f); + } + } + + static float DoFloatFieldInternal(Rect position, + Rect dragHotZone, + int id, + float value, + string formatString = null, + GUIStyle style = null, + bool draggable = true) + { + style = style ?? EditorStyles.numberField; + formatString = formatString ?? (string) FLOAT_FIELD_FORMAT_STRING_CONST.GetValue(null); + + var editor = RECYCLED_EDITOR_PROPERTY.GetValue(null); + + return (float) DO_FLOAT_FIELD_METHOD.Invoke(null, new[] { + editor, + position, + dragHotZone, + id, + value, + formatString, + style, + draggable + }); + } + + public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) + { + if (!(attribute is KnobAttribute)) return; + + KnobProperty(position, label, property, Vector2.right); + } + + public override float GetPropertyHeight(SerializedProperty property, GUIContent label) + { + return ControlHeight; + } + + static float ControlHeight => EGU.singleLineHeight * 2.0f; + static float KnobSize => EGU.singleLineHeight * 2.5f; + static float KnobYOffset => (ControlHeight - KnobSize) / 2; + + static Color Lighten(Color color, float amount) + { + Color.RGBToHSV(color, out var h, out var s, out var v); + return Color.HSVToRGB(h, s, v + amount); + } + + public static void KnobProperty(Rect rect, GUIContent label, SerializedProperty prop, Vector2 zeroVector) + { + float angle = prop.floatValue; + float prevAngle = angle; + + using (var propScope = new EditorGUI.PropertyScope(rect, label, prop)) + using (var changeScope = new EditorGUI.ChangeCheckScope()) + { + var labelRect = new Rect(rect) { + y = rect.y + (ControlHeight - EGU.singleLineHeight) / 2, + height = EGU.singleLineHeight + }; + + int fieldId = GUIUtility.GetControlID(FocusType.Keyboard, labelRect); + var fieldRect = EditorGUI.PrefixLabel(labelRect, fieldId, propScope.content); + labelRect.xMax = fieldRect.x; + fieldRect.x += ControlHeight; + fieldRect.width -= ControlHeight; + + + Rect knobRect = new Rect(rect.x + EGU.labelWidth + KnobYOffset, + rect.y + KnobYOffset, + KnobSize, KnobSize); + int knobId = GUIUtility.GetControlID(FocusType.Passive, knobRect); + + if (Event.current != null) + { + if (Event.current.type == EventType.MouseDown && knobRect.Contains(Event.current.mousePosition)) + { + GUIUtility.hotControl = knobId; + + angle = Angle360(zeroVector, Event.current.mousePosition - knobRect.center); + } + else if (Event.current.type == EventType.MouseUp && GUIUtility.hotControl == knobId) + { + GUIUtility.hotControl = 0; + } + else if (Event.current.type == EventType.MouseDrag && GUIUtility.hotControl == knobId) + { + angle = Angle360(zeroVector, Event.current.mousePosition - knobRect.center); + } + else if (Event.current.type == EventType.Repaint) + { + var notRotated = GUI.matrix; + var oldColor = GUI.color; + var highlighted = GUIUtility.hotControl == knobId || + GUIUtility.hotControl == fieldId || + GUIUtility.keyboardControl == fieldId; + + GUIUtility.RotateAroundPivot(angle, knobRect.center); + GUI.color = KNOB_BG_COLOR; + GUI.DrawTexture(knobRect, KNOB_BG_TEXTURE, ScaleMode.ScaleToFit, true, 1); + GUI.color = highlighted ? KNOB_FG_COLOR_ACTIVE : KNOB_FG_COLOR; + if (procrastinationMode) GUI.color = Color.red; + GUI.DrawTexture(knobRect, KNOB_FG_TEXTURE, ScaleMode.ScaleToFit, true, 1); + + if (!procrastinationMode) + GUI.matrix = notRotated; + GUI.color = oldColor; + } + + if (angle != prevAngle) GUI.changed = true; + } + + + angle = DoFloatFieldInternal( + fieldRect, + labelRect, + fieldId, + angle + ); + + + if (changeScope.changed) prop.floatValue = angle; + } + } +} +} diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/KnobPropertyDrawer.cs.meta b/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/KnobPropertyDrawer.cs.meta new file mode 100644 index 0000000..a95cec5 --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/KnobPropertyDrawer.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 07c24ad14ec14d40ab304c80ba6af657 +timeCreated: 1594636852 \ No newline at end of file diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/LeTai.TrueShadow.Editor.asmdef b/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/LeTai.TrueShadow.Editor.asmdef new file mode 100644 index 0000000..e090287 --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/LeTai.TrueShadow.Editor.asmdef @@ -0,0 +1,16 @@ +{ + "name": "LeTai.TrueShadow.Editor", + "references": [ + "LeTai.TrueShadow" + ], + "optionalUnityReferences": [], + "includePlatforms": [ + "Editor" + ], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": true, + "defineConstraints": [] +} \ No newline at end of file diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/LeTai.TrueShadow.Editor.asmdef.meta b/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/LeTai.TrueShadow.Editor.asmdef.meta new file mode 100644 index 0000000..b4d4e78 --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/LeTai.TrueShadow.Editor.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: a3c0f23110aac1b4384b9377b63b6595 +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/MigrateToV0_5Window.cs b/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/MigrateToV0_5Window.cs new file mode 100644 index 0000000..edacad7 --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/MigrateToV0_5Window.cs @@ -0,0 +1,104 @@ +using System.Linq; +using UnityEditor; +using UnityEngine; + +namespace LeTai.TrueShadow.Editor +{ +public class MigrateToVV1Window : EditorWindow +{ + private const string SHOW_ON_START_EDITOR_PREFS_KEY = "LeTai.TrueShadow.MigrateToVV1WindowShown"; + + [MenuItem("Tools/TrueShadow/Migrate To v1")] + public static MigrateToVV1Window ShowWindow() + { + var window = GetWindow(true, "True Shadow"); + window.position = new Rect(600, 400, 600, 400); + return window; + } + + [InitializeOnLoadMethod] + private static void InitializeOnLoadMethod() + { + RegisterWindowCheck(); + } + + private static void RegisterWindowCheck() + { + if (!EditorApplication.isPlayingOrWillChangePlaymode) + { + EditorApplication.update += CheckShowWindow; + } + } + + private static void CheckShowWindow() + { + EditorApplication.update -= CheckShowWindow; + if (EditorPrefs.GetBool(SHOW_ON_START_EDITOR_PREFS_KEY, true)) + { + ShowWindow(); + } + } + + void OnDestroy() + { + EditorPrefs.SetBool(SHOW_ON_START_EDITOR_PREFS_KEY, false); + } + + bool haveBackup; + + private void OnGUI() + { + GUILayout.Label("Migrate to v1", EditorStyles.largeLabel); + EditorGUILayout.Separator(); + EditorGUILayout.HelpBox( + "In v1, Blend Mode was changed to produce better looking shadows, as well as better compatibility with 3rd parties asset. As a side effect, most shadows should now use Color Bleed Mode: . This tool attempt to do this automatically.\n\n" + + "All True Shadows in currently loaded scenes will be migrated. You may want to load all scenes you want to fix before migrating. All True Shadows in prefabs will also be migrated.\n\n" + + "All True Shadows in prefabs will also be migrated.\n\n" + + "You may access this dialog later from the Tools menu.", + MessageType.Info + ); + EditorGUILayout.Separator(); + EditorGUILayout.HelpBox( + "!!! MAKE SURE TO BACK UP YOUR PROJECT BEFORE USE !!!\n\n" + + "This tool will modify your project files. Please backup your project before use. If you are unsure how to do this, do NOT use this tool! Manually change any problematic shadows Color Bleed mode to Black instead!", + MessageType.Warning); + EditorGUILayout.Separator(); + haveBackup = EditorGUILayout.ToggleLeft("I have backed up the project and can undo any changes done by the tool", haveBackup); + if (haveBackup) + { + if (GUILayout.Button("Migrate to v1")) + MigrateToV1(); + } + } + + public static void MigrateToV1() + { + var allPrefabs = AssetDatabase.FindAssets("t:Prefab"); + foreach (var guid in allPrefabs) + { + var path = AssetDatabase.GUIDToAssetPath(guid); + var prefabRoot = PrefabUtility.LoadPrefabContents(path); + var changed = false; + + foreach (var shadow in prefabRoot.GetComponentsInChildren()) + { + shadow.ColorBleedMode = ColorBleedMode.Black; + changed = true; + } + + if (changed) + PrefabUtility.SaveAsPrefabAsset(prefabRoot, path); + + PrefabUtility.UnloadPrefabContents(prefabRoot); + } + + var inScene = Resources.FindObjectsOfTypeAll() + .ToArray(); + Undo.RecordObjects(inScene, "Migrate to 0.5"); + foreach (var shadow in inScene) + { + shadow.ColorBleedMode = ColorBleedMode.Black; + } + } +} +} diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/MigrateToV0_5Window.cs.meta b/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/MigrateToV0_5Window.cs.meta new file mode 100644 index 0000000..b41c8a4 --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/MigrateToV0_5Window.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 126149305ac84024ac1d713f39caf754 +timeCreated: 1611560835 \ No newline at end of file diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/PrefabEventHandler.cs b/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/PrefabEventHandler.cs new file mode 100644 index 0000000..acc5fac --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/PrefabEventHandler.cs @@ -0,0 +1,19 @@ +using UnityEditor; + +namespace LeTai.TrueShadow.Editor +{ +[InitializeOnLoad] +class PrefabEventHandler +{ + static PrefabEventHandler() + { + PrefabUtility.prefabInstanceUpdated += go => + { + var shadows = go.GetComponentsInChildren(); + + foreach (var shadow in shadows) + shadow.ApplySerializedData(); + }; + } +} +} diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/PrefabEventHandler.cs.meta b/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/PrefabEventHandler.cs.meta new file mode 100644 index 0000000..13d3563 --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/PrefabEventHandler.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 9806fc5a3b18445e9766a68cf69b81c9 +timeCreated: 1600845150 \ No newline at end of file diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/ScenceGizmoAutoDisable.cs b/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/ScenceGizmoAutoDisable.cs new file mode 100644 index 0000000..26beb76 --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/ScenceGizmoAutoDisable.cs @@ -0,0 +1,62 @@ +using System; +using System.Linq; +using System.Reflection; + +namespace LeTai.Asset.TrueShadow.Editor +{ +public static class ScenceGizmoAutoDisable +{ + static readonly string[] NO_GIZMOS_CLASSES = { + "TrueShadow" + }; + + [UnityEditor.Callbacks.DidReloadScripts] + private static void OnScriptsReloaded() + { + var Annotation = Type.GetType("UnityEditor.Annotation, UnityEditor"); + if (Annotation == null) return; + + var ClassId = Annotation.GetField("classID"); + var ScriptClass = Annotation.GetField("scriptClass"); + var Flags = Annotation.GetField("flags"); + var IconEnabled = Annotation.GetField("iconEnabled"); + + Type AnnotationUtility = Type.GetType("UnityEditor.AnnotationUtility, UnityEditor"); + if (AnnotationUtility == null) return; + + var GetAnnotations = AnnotationUtility.GetMethod("GetAnnotations", + BindingFlags.NonPublic | BindingFlags.Public | + BindingFlags.Static); + if (GetAnnotations == null) return; + var SetIconEnabled = AnnotationUtility.GetMethod("SetIconEnabled", + BindingFlags.NonPublic | BindingFlags.Public | + BindingFlags.Static); + if (SetIconEnabled == null) return; + + + Array annotations = (Array) GetAnnotations.Invoke(null, null); + foreach (var a in annotations) + { + int classId = (int) ClassId.GetValue(a); + string scriptClass = (string) ScriptClass.GetValue(a); + int flags = (int) Flags.GetValue(a); + int iconEnabled = (int) IconEnabled.GetValue(a); + + // built in types + if (string.IsNullOrEmpty(scriptClass)) continue; + + // load a json or text file with class names + + const int HasIcon = 1; + bool hasIconFlag = (flags & HasIcon) == HasIcon; + + if (hasIconFlag && + iconEnabled != 0 && + NO_GIZMOS_CLASSES.Contains(scriptClass)) + { + SetIconEnabled.Invoke(null, new object[] {classId, scriptClass, 0}); + } + } + } +} +} diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/ScenceGizmoAutoDisable.cs.meta b/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/ScenceGizmoAutoDisable.cs.meta new file mode 100644 index 0000000..c2804f1 --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/ScenceGizmoAutoDisable.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a1266d64cf1066b47b900e5115a5b75d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/SpreadSliderDrawer.cs b/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/SpreadSliderDrawer.cs new file mode 100644 index 0000000..ba950de --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/SpreadSliderDrawer.cs @@ -0,0 +1,87 @@ +using UnityEditor; +using UnityEngine; +using static UnityEditor.EditorGUI; + +namespace LeTai.TrueShadow.Editor +{ +[CustomPropertyDrawer(typeof(SpreadSliderAttribute))] +public class SpreadSliderDrawer : PropertyDrawer +{ + const float SLIDER_SPACING = 5; + const float MARKER_HEIGHT = 6; + const float MARKER_ALPHA = .75f; + const float MARKER_FILLET = 2; + + static readonly Vector4 START_RADII = new Vector4(MARKER_FILLET, 0, 0, MARKER_FILLET); + static readonly Vector4 END_RADII = new Vector4(0, MARKER_FILLET, MARKER_FILLET, 0); + + public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) + { + using (var propScope = new PropertyScope(position, label, property)) + using (var changeScope = new ChangeCheckScope()) + { + var controlPosition = PrefixLabel(position, propScope.content); + + var floatFieldWidth = Mathf.Min(EditorGUIUtility.fieldWidth, controlPosition.width); + var sliderPosition = new Rect(controlPosition) + {width = controlPosition.width - floatFieldWidth - SLIDER_SPACING}; + + const float marker1 = .8f; + const float marker2 = .95f; + + DrawMarkers(sliderPosition, + (marker1, new Color(1.00000f, 0.60392f, 0.01961f, MARKER_ALPHA)), + (marker2, new Color(1.00000f, 0.25490f, 0.20784f, MARKER_ALPHA))); + + var newVal = Slider(controlPosition, + GUIContent.none, + property.floatValue, + 0, 1); + + if (!Event.current.control && !Event.current.alt) + { + var dist1 = (newVal - marker1) * sliderPosition.width; + var dist2 = (newVal - marker2) * sliderPosition.width; + if (0 < dist1 && dist1 < 4) + newVal = marker1; + if (0 < dist2 && dist2 < 4) + newVal = marker2; + } + + if (changeScope.changed) + property.floatValue = newVal; + } + } + + void DrawMarkers(Rect sliderPosition, params (float, Color)[] markers) + { + var hPad = GUI.skin.horizontalSliderThumb.fixedWidth / 2f; + var markerXStart = sliderPosition.x + hPad; + var markerXEnd = sliderPosition.width - hPad * 2; + var vPad = (sliderPosition.height - MARKER_HEIGHT) / 2f; + var markerYStart = sliderPosition.y + vPad; + var markerHeight = sliderPosition.height - vPad * 2; + for (var i = 0; i < markers.Length; i++) + { + var (offset, color) = markers[i]; + + var x = markerXStart + markerXEnd * offset; + var width = i < markers.Length - 1 + ? sliderPosition.width * (markers[i + 1].Item1 - offset) - 1 + : sliderPosition.xMax - x; + var position = new Rect { + x = x, + y = markerYStart, + width = width, + height = markerHeight + }; + + var radii = i == 0 ? START_RADII : END_RADII; + + GUI.DrawTexture(position, + Texture2D.whiteTexture, ScaleMode.StretchToFill, true, 0, color, + Vector4.zero, radii); + } + } +} +} diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/SpreadSliderDrawer.cs.meta b/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/SpreadSliderDrawer.cs.meta new file mode 100644 index 0000000..a98c9e4 --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/SpreadSliderDrawer.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 3292983b33504803ae542a485f446019 +timeCreated: 1615190623 \ No newline at end of file diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/Textures.meta b/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/Textures.meta new file mode 100644 index 0000000..332da49 --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/Textures.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 1cd90590774134c4ea35245f256f89e9 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/Textures/Inner Shadow.png b/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/Textures/Inner Shadow.png new file mode 100644 index 0000000..7974718 Binary files /dev/null and b/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/Textures/Inner Shadow.png differ diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/Textures/Inner Shadow.png.meta b/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/Textures/Inner Shadow.png.meta new file mode 100644 index 0000000..ca90dbe --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/Textures/Inner Shadow.png.meta @@ -0,0 +1,130 @@ +fileFormatVersion: 2 +guid: b11fa2df94e30d244aadf3846cb15aeb +labels: +- TrueShadowEditorResources +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 11 + mipmaps: + mipMapMode: 1 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 1 + mipBias: -100 + wrapU: 1 + wrapV: 1 + wrapW: -1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + applyGammaDecoding: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: WebGL + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: 21fab31b34964614680dcb53be2692d1 + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/Textures/Knob_BG.png b/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/Textures/Knob_BG.png new file mode 100644 index 0000000..136b7bc Binary files /dev/null and b/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/Textures/Knob_BG.png differ diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/Textures/Knob_BG.png.meta b/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/Textures/Knob_BG.png.meta new file mode 100644 index 0000000..e3403df --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/Textures/Knob_BG.png.meta @@ -0,0 +1,130 @@ +fileFormatVersion: 2 +guid: 413bbe8f3993d194682180c4acfc0d1e +labels: +- TrueShadowEditorResources +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 11 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 2 + aniso: 16 + mipBias: -100 + wrapU: 1 + wrapV: 1 + wrapW: -1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + applyGammaDecoding: 1 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: WebGL + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: 21fab31b34964614680dcb53be2692d1 + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/Textures/Knob_FG.png b/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/Textures/Knob_FG.png new file mode 100644 index 0000000..92a73f8 Binary files /dev/null and b/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/Textures/Knob_FG.png differ diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/Textures/Knob_FG.png.meta b/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/Textures/Knob_FG.png.meta new file mode 100644 index 0000000..b14904f --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/Textures/Knob_FG.png.meta @@ -0,0 +1,130 @@ +fileFormatVersion: 2 +guid: 94d408ca95ce77245aa4866768b6b55c +labels: +- TrueShadowEditorResources +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 11 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 2 + aniso: 16 + mipBias: -100 + wrapU: 1 + wrapV: 1 + wrapW: -1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + applyGammaDecoding: 1 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: WebGL + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: 21fab31b34964614680dcb53be2692d1 + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/Textures/Outer Shadow.png b/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/Textures/Outer Shadow.png new file mode 100644 index 0000000..e2c9c9f Binary files /dev/null and b/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/Textures/Outer Shadow.png differ diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/Textures/Outer Shadow.png.meta b/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/Textures/Outer Shadow.png.meta new file mode 100644 index 0000000..c8726e6 --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/Textures/Outer Shadow.png.meta @@ -0,0 +1,130 @@ +fileFormatVersion: 2 +guid: 8cad3feef3766b240a76d467e152152e +labels: +- TrueShadowEditorResources +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 11 + mipmaps: + mipMapMode: 1 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 1 + mipBias: -100 + wrapU: 1 + wrapV: 1 + wrapW: -1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + applyGammaDecoding: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: WebGL + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: 21fab31b34964614680dcb53be2692d1 + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/Textures/True Shadow Icon.png b/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/Textures/True Shadow Icon.png new file mode 100644 index 0000000..dc5f207 Binary files /dev/null and b/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/Textures/True Shadow Icon.png differ diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/Textures/True Shadow Icon.png.meta b/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/Textures/True Shadow Icon.png.meta new file mode 100644 index 0000000..e594769 --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/Textures/True Shadow Icon.png.meta @@ -0,0 +1,128 @@ +fileFormatVersion: 2 +guid: 098c7906709c37c4bba842c34581765c +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 11 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 1 + mipBias: -100 + wrapU: 1 + wrapV: 1 + wrapW: -1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + applyGammaDecoding: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: WebGL + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: 21fab31b34964614680dcb53be2692d1 + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/TrueShadowEditor.cs b/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/TrueShadowEditor.cs new file mode 100644 index 0000000..fe27347 --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/TrueShadowEditor.cs @@ -0,0 +1,104 @@ +using UnityEditor; +using UnityEngine; +using static UnityEditor.EditorGUILayout; + +namespace LeTai.TrueShadow.Editor +{ +[CanEditMultipleObjects] +[CustomEditor(typeof(TrueShadow))] +public class TrueShadowEditor : UnityEditor.Editor +{ + EditorProperty insetProp; + EditorProperty sizeProp; + EditorProperty spreadProp; + EditorProperty angleProp; + EditorProperty distanceProp; + EditorProperty colorProp; + EditorProperty blendModeProp; + EditorProperty multiplyCasterAlphaProp; + EditorProperty ignoreCasterColorProp; + EditorProperty colorBleedModeProp; + + GUIContent procrastinateLabel; + + static bool showExperimental; + static bool showAdvanced; + + void OnEnable() + { + insetProp = new EditorProperty(serializedObject, nameof(TrueShadow.Inset)); + sizeProp = new EditorProperty(serializedObject, nameof(TrueShadow.Size)); + spreadProp = new EditorProperty(serializedObject, nameof(TrueShadow.Spread)); + angleProp = new EditorProperty(serializedObject, nameof(TrueShadow.OffsetAngle)); + distanceProp = new EditorProperty(serializedObject, nameof(TrueShadow.OffsetDistance)); + colorProp = new EditorProperty(serializedObject, nameof(TrueShadow.Color)); + blendModeProp = new EditorProperty(serializedObject, nameof(TrueShadow.BlendMode)); + multiplyCasterAlphaProp = new EditorProperty(serializedObject, nameof(TrueShadow.UseCasterAlpha)); + ignoreCasterColorProp = new EditorProperty(serializedObject, nameof(TrueShadow.IgnoreCasterColor)); + colorBleedModeProp = new EditorProperty(serializedObject, nameof(TrueShadow.ColorBleedMode)); + + if (EditorPrefs.GetBool("LeTai_TrueShadow_" + nameof(showExperimental))) + { + showExperimental = EditorPrefs.GetBool("LeTai_TrueShadow_" + nameof(showExperimental), false); + showAdvanced = EditorPrefs.GetBool("LeTai_TrueShadow_" + nameof(showAdvanced), false); + } + + procrastinateLabel = new GUIContent("Procrastinate", "A bug that is too fun to fix"); + } + + public override void OnInspectorGUI() + { + serializedObject.Update(); + + var ts = (TrueShadow) target; + + insetProp.Draw(); + sizeProp.Draw(); + spreadProp.Draw(); + angleProp.Draw(); + distanceProp.Draw(); + colorProp.Draw(); + if (ts.UsingRendererMaterialProvider) + { + using(new EditorGUI.DisabledScope(true)) + LabelField(blendModeProp.serializedProperty.displayName, "Custom Material"); + } + else + { + blendModeProp.Draw(); + } + + using (var change = new EditorGUI.ChangeCheckScope()) + { + showAdvanced = Foldout(showAdvanced, "Advanced Settings", true); + using (new EditorGUI.IndentLevelScope()) + if (showAdvanced) + { + multiplyCasterAlphaProp.Draw(); + ignoreCasterColorProp.Draw(); + colorBleedModeProp.Draw(); + + if (KnobPropertyDrawer.procrastinationMode) + { + var rot = GUI.matrix; + GUI.matrix = Matrix4x4.identity; + KnobPropertyDrawer.procrastinationMode ^= Toggle("Be Productive", false); + GUI.matrix = rot; + } + else + { + KnobPropertyDrawer.procrastinationMode |= Toggle(procrastinateLabel, false); + } + } + + if (change.changed) + { + EditorPrefs.SetBool("LeTai_TrueShadow_" + nameof(showExperimental), showExperimental); + EditorPrefs.SetBool("LeTai_TrueShadow_" + nameof(showAdvanced), showAdvanced); + } + } + + serializedObject.ApplyModifiedProperties(); + } +} +} diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/TrueShadowEditor.cs.meta b/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/TrueShadowEditor.cs.meta new file mode 100644 index 0000000..e92595e --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/TrueShadowEditor.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 120b61c7775149ed9de9c782978f6d61 +timeCreated: 1592985822 \ No newline at end of file diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/Utility.cs b/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/Utility.cs new file mode 100644 index 0000000..f12efa0 --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/Utility.cs @@ -0,0 +1,22 @@ +using UnityEditor; +using UnityEngine; + +namespace LeTai.TrueShadow.Editor +{ +public static class Utility +{ + public static T FindAsset(string assetName) where T : UnityEngine.Object + { + var guids = AssetDatabase.FindAssets("l:TrueShadowEditorResources " + assetName); + if (guids.Length == 0) + { + Debug.LogError($"Asset \"{assetName}\" not found. " + + $"Make sure it have the label \"TrueShadowEditorResources\""); + return null; + } + + var path = AssetDatabase.GUIDToAssetPath(guids[0]); + return AssetDatabase.LoadAssetAtPath(path); + } +} +} diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/Utility.cs.meta b/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/Utility.cs.meta new file mode 100644 index 0000000..9dcb3f2 --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/Editor/Utility.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 09b72999f3c04f898c16bf60deb38c6e +timeCreated: 1602578784 \ No newline at end of file diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Effects.meta b/Assets/Le Tai's Asset/TrueShadow/Scripts/Effects.meta new file mode 100644 index 0000000..df32430 --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/Effects.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 20daae54a38548b488eb9c2aa1d39507 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Effects/BlurConfig.cs b/Assets/Le Tai's Asset/TrueShadow/Scripts/Effects/BlurConfig.cs new file mode 100644 index 0000000..a2750e2 --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/Effects/BlurConfig.cs @@ -0,0 +1,9 @@ +using UnityEngine; + +namespace LeTai.Effects +{ + public class BlurConfig : ScriptableObject + { + + } +} diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Effects/BlurConfig.cs.meta b/Assets/Le Tai's Asset/TrueShadow/Scripts/Effects/BlurConfig.cs.meta new file mode 100644 index 0000000..7d5faca --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/Effects/BlurConfig.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1598e613c3d69154db682bbf3c234cb2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Effects/IBlurAlgorithm.cs b/Assets/Le Tai's Asset/TrueShadow/Scripts/Effects/IBlurAlgorithm.cs new file mode 100644 index 0000000..f24b4c6 --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/Effects/IBlurAlgorithm.cs @@ -0,0 +1,15 @@ +using UnityEngine; +using UnityEngine.Rendering; + +namespace LeTai.Effects +{ +public interface IBlurAlgorithm +{ + void Configure(BlurConfig config); + + void Blur(CommandBuffer cmd, + RenderTargetIdentifier src, + Rect srcCropRegion, + RenderTexture target); +} +} diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Effects/IBlurAlgorithm.cs.meta b/Assets/Le Tai's Asset/TrueShadow/Scripts/Effects/IBlurAlgorithm.cs.meta new file mode 100644 index 0000000..180729e --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/Effects/IBlurAlgorithm.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5bc98ab7243bbdc40a0c52f6d1ed58a0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Effects/ScalableBlur.cs b/Assets/Le Tai's Asset/TrueShadow/Scripts/Effects/ScalableBlur.cs new file mode 100644 index 0000000..82f4758 --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/Effects/ScalableBlur.cs @@ -0,0 +1,104 @@ +using UnityEngine; +using UnityEngine.Rendering; + +namespace LeTai.Effects +{ +public class ScalableBlur : IBlurAlgorithm +{ + Material material; + ScalableBlurConfig config; + + const int BLUR_PASS = 0; + const int CROP_BLUR_PASS = 1; + + Material Material + { + get + { + if (material == null) + Material = new Material(Shader.Find("Hidden/EfficientBlur")); + + return material; + } + set => material = value; + } + + ~ScalableBlur() + { + if (!material) return; + + if (Application.isPlaying) + Object.Destroy(material); + else + Object.DestroyImmediate(material); + } + + public void Configure(BlurConfig config) + { + this.config = (ScalableBlurConfig) config; + } + + public void Blur(CommandBuffer cmd, + RenderTargetIdentifier src, + Rect srcCropRegion, + RenderTexture target) + { + float radius = config.Radius; + Material.SetFloat(ShaderProperties.blurRadius, radius); + Material.SetVector(ShaderProperties.blurTextureCropRegion, srcCropRegion.ToMinMaxVector()); + + int firstDownsampleFactor = config.Iteration > 0 ? 1 : 0; + int stepCount = Mathf.Max(config.Iteration * 2 - 1, 1); + + int firstIRT = ShaderProperties.intermediateRT[0]; + CreateTempRenderTextureFrom(cmd, firstIRT, target, firstDownsampleFactor); + + // cmd.BlitFullscreenTriangle(src, firstIRT, Material, CROP_BLUR_PASS); + cmd.Blit(src, firstIRT, Material, CROP_BLUR_PASS); + + for (var i = 1; i < stepCount; i++) + { + BlurAtDepth(cmd, i, target); + } + + // cmd.BlitFullscreenTriangle(ShaderProperties.intermediateRT[stepCount - 1], target, Material, BLUR_PASS); + cmd.Blit(ShaderProperties.intermediateRT[stepCount - 1], target, Material, BLUR_PASS); + + CleanupIntermediateRT(cmd, stepCount); + } + + protected virtual void BlurAtDepth(CommandBuffer cmd, int depth, RenderTexture baseTexture) + { + int sizeLevel = Utility.SimplePingPong(depth, config.Iteration - 1) + 1; + sizeLevel = Mathf.Min(sizeLevel, config.MaxDepth); + CreateTempRenderTextureFrom(cmd, ShaderProperties.intermediateRT[depth], baseTexture, sizeLevel); + + // cmd.BlitFullscreenTriangle( + cmd.Blit( + ShaderProperties.intermediateRT[depth - 1], + ShaderProperties.intermediateRT[depth], + Material, + 0 + ); + } + + static void CreateTempRenderTextureFrom(CommandBuffer cmd, + int nameId, + RenderTexture src, + int downsampleFactor) + { + int w = src.width >> downsampleFactor; //= width / 2^downsample + int h = src.height >> downsampleFactor; + + cmd.GetTemporaryRT(nameId, w, h, 0, FilterMode.Bilinear, src.format); + } + + static void CleanupIntermediateRT(CommandBuffer cmd, int amount) + { + for (var i = 0; i < amount; i++) + { + cmd.ReleaseTemporaryRT(ShaderProperties.intermediateRT[i]); + } + } +} +} diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Effects/ScalableBlur.cs.meta b/Assets/Le Tai's Asset/TrueShadow/Scripts/Effects/ScalableBlur.cs.meta new file mode 100644 index 0000000..ece9834 --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/Effects/ScalableBlur.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d72465d1220a01e4abccda77619f6763 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Effects/ScalableBlurConfig.cs b/Assets/Le Tai's Asset/TrueShadow/Scripts/Effects/ScalableBlurConfig.cs new file mode 100644 index 0000000..ffc7ddb --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/Effects/ScalableBlurConfig.cs @@ -0,0 +1,110 @@ +using UnityEngine; +using static UnityEngine.Mathf; + +namespace LeTai.Effects +{ +public class ScalableBlurConfig : BlurConfig +{ + [SerializeField] float radius = 4; + [SerializeField] int iteration = 4; + [SerializeField] int maxDepth = 6; + [SerializeField] [Range(0, 256)] float strength; + + /// + /// Distance between the base texel and the texel to be sampled. + /// + public float Radius + { + get { return radius; } + set { radius = Max(0, value); } + } + + /// + /// Half the number of time to process the image. It is half because the real number of iteration must alway be even. Using half also make calculation simpler + /// + /// + /// Must be non-negative + /// + public int Iteration + { + get { return iteration; } + set { iteration = Max(0, value); } + } + + /// + /// Clamp the minimum size of the intermediate texture. Reduce flickering and blur + /// + /// + /// Must larger than 0 + /// + public int MaxDepth + { + get { return maxDepth; } + set { maxDepth = Max(1, value); } + } + + /// + /// User friendly property to control the amount of blur + /// + /// + /// Must be non-negative + /// + public float Strength + { + get { return strength = radius * (3 * (1 << iteration) - 2) / UNIT_VARIANCE; } + set + { + strength = Max(0, value); + SetAdvancedFieldFromSimple(); + } + } + + // With the "correct" unit variance, the edge of the shadow at higher stddev go below 8bit fixed point resolution + // We "wastes" processing power on these. + // TODO: optimize that: + // The maximum distance that will show up is: + // e^(-D^2 / 2R^2) < .5/256 + // => D < 3*sqrt(2*log(2)) * R ~ 3.53223*R + // Can probably stop sooner than that + static readonly float UNIT_VARIANCE = 1f + Sqrt(2f) / 2f; + + /// + /// Calculate size and iteration from strength + /// + protected virtual void SetAdvancedFieldFromSimple() + { + if (strength < 1e-2) + { + iteration = 0; + radius = 0; + return; + } + + var variance = strength * UNIT_VARIANCE; + + // Each level of the pyramid have double the effective radius of the last, so total effective radius would be: + // S = (2^0 + 2^1 +...+ 2^iteration +...+ 2^1 + 2^0) * R + // https://en.wikipedia.org/wiki/1_%2B_2_%2B_4_%2B_8_%2B_%E2%8B%AF + // S = (3 * 2^I - 2) * R + // so: + // I = log((s + 2r)/ (3r))/log(2) + // and: + // R = S / (3 * 2^I - 2) + // + // Experimental result show that best result are obtained with R <= 2^I - 1, so: + // I >= log(1/6 * (sqrt(12S + 1) + 5))/log(2) + // + // There still some artifact at the lower end, not sure how to handle that yet + // TODO: use a different algorithm for low Strength. + + iteration = CeilToInt(Log(1 / 6f * (Sqrt(12 * variance + 1) + 5)) / Log(2)); + + radius = variance / (3 * (1 << iteration) - 2); + } + + void OnValidate() + { + SetAdvancedFieldFromSimple(); + } +} +} diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Effects/ScalableBlurConfig.cs.meta b/Assets/Le Tai's Asset/TrueShadow/Scripts/Effects/ScalableBlurConfig.cs.meta new file mode 100644 index 0000000..aa4a5e5 --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/Effects/ScalableBlurConfig.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 506e4e7bc6f8ce24486de8c2732c0a1b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Effects/ShaderProperties.cs b/Assets/Le Tai's Asset/TrueShadow/Scripts/Effects/ShaderProperties.cs new file mode 100644 index 0000000..012f4fb --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/Effects/ShaderProperties.cs @@ -0,0 +1,37 @@ +using UnityEngine; + +namespace LeTai.Effects +{ + public static class ShaderProperties + { + private static bool isInitialized; + + public static int[] intermediateRT; + + public static int blurRadius; + public static int blurTextureCropRegion; + + public static void Init() + { + if (isInitialized) + return; + + + blurRadius = Shader.PropertyToID("_Radius"); + blurTextureCropRegion = Shader.PropertyToID("_CropRegion"); + + isInitialized = true; + } + + public static void Init(int stackDepth) + { + intermediateRT = new int[stackDepth * 2 - 1]; + for (var i = 0; i < intermediateRT.Length; i++) + { + intermediateRT[i] = Shader.PropertyToID(string.Format("TI_intermediate_rt_{0}", i)); + } + + Init(); + } + } +} \ No newline at end of file diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Effects/ShaderProperties.cs.meta b/Assets/Le Tai's Asset/TrueShadow/Scripts/Effects/ShaderProperties.cs.meta new file mode 100644 index 0000000..e05f0bf --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/Effects/ShaderProperties.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3ae61d4a8774bbb41acdf25cded306c2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Helper.meta b/Assets/Le Tai's Asset/TrueShadow/Scripts/Helper.meta new file mode 100644 index 0000000..09f2720 --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/Helper.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: fa263cbfa5524d12a0df2e7befd04f50 +timeCreated: 1593508707 \ No newline at end of file diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Helper/AnimatedBiStateButton.cs b/Assets/Le Tai's Asset/TrueShadow/Scripts/Helper/AnimatedBiStateButton.cs new file mode 100644 index 0000000..0231699 --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/Helper/AnimatedBiStateButton.cs @@ -0,0 +1,138 @@ +using System; +using UnityEngine; +using UnityEngine.EventSystems; + +public class AnimatedBiStateButton : MonoBehaviour, + IPointerDownHandler, IPointerUpHandler, + IPointerEnterHandler, IPointerExitHandler +{ + public enum State + { + Up, + AnimateDown, + Down, + AnimateUp, + } + + public float animationDuration = .1f; + public AnimationCurve animationCurve = AnimationCurve.EaseInOut(0, 0, 1, 1); + public bool useEnterExitEvents = true; + + public event Action willPress; + public event Action willRelease; + + protected State state = State.Up; + + /// + /// 0 = fully up + /// 1 = fully down + /// + protected float pressAmount = 0; + + protected bool IsAnimating => state == State.AnimateDown || state == State.AnimateUp; + + void Update() + { + PollPointerUp(); + DoAnimation(); + } + + void DoAnimation() + { + if (!IsAnimating) return; + + if (state == State.AnimateDown) + { + pressAmount += Time.deltaTime / animationDuration; + } + else if (state == State.AnimateUp) + { + pressAmount -= Time.deltaTime / animationDuration; + } + + pressAmount = Mathf.Clamp01(pressAmount); + var animationProgress = pressAmount; + if (state == State.AnimateUp) animationProgress = 1 - animationProgress; + animationProgress = animationCurve.Evaluate(animationProgress); + if (state == State.AnimateUp) animationProgress = 1 - animationProgress; + + Animate(animationProgress); + + if (state == State.AnimateDown && pressAmount == 1) + { + state = State.Down; + } + + if (state == State.AnimateUp && pressAmount == 0) + { + state = State.Up; + } + } + + protected void Press() + { + if (state != State.Down && state != State.AnimateDown) + { + OnWillPress(); + state = State.AnimateDown; + } + } + + protected void Release() + { + if (state != State.Up && state != State.AnimateUp) + { + OnWillRelease(); + state = State.AnimateUp; + } + } + + /// + /// Pointer Up event does not fire on an object if it was not the one receive the Pointer Down event. + /// + void PollPointerUp() + { + if (useEnterExitEvents + && (state == State.Down || state == State.AnimateDown) + && !Input.GetMouseButton(0)) + { + Release(); + } + } + + /// + /// NOP if not overrided + /// + /// conformed to + protected virtual void Animate(float visualPressAmount) { } + + public void OnPointerDown(PointerEventData eventData) + { + Press(); + } + + public void OnPointerUp(PointerEventData eventData) + { + Release(); + } + + public void OnPointerEnter(PointerEventData eventData) + { + if (useEnterExitEvents && Input.GetMouseButton(0)) Press(); + } + + public void OnPointerExit(PointerEventData eventData) + { + if (useEnterExitEvents) Release(); + } + + protected virtual void OnWillPress() + { + willPress?.Invoke(); + } + + protected virtual void OnWillRelease() + { + willRelease?.Invoke(); + } +} diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Helper/AnimatedBiStateButton.cs.meta b/Assets/Le Tai's Asset/TrueShadow/Scripts/Helper/AnimatedBiStateButton.cs.meta new file mode 100644 index 0000000..0044b03 --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/Helper/AnimatedBiStateButton.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: d498001a5177468b90ceba93a17a5307 +timeCreated: 1603966347 \ No newline at end of file diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Helper/InsetOnPress.cs b/Assets/Le Tai's Asset/TrueShadow/Scripts/Helper/InsetOnPress.cs new file mode 100644 index 0000000..cc92ff8 --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/Helper/InsetOnPress.cs @@ -0,0 +1,69 @@ +using UnityEngine; + +namespace LeTai.TrueShadow +{ +[RequireComponent(typeof(TrueShadow))] +public class InsetOnPress : AnimatedBiStateButton +{ + TrueShadow[] shadows; + float[] normalOpacity; + bool wasInset; + + void OnEnable() + { + shadows = GetComponents(); + normalOpacity = new float[shadows.Length]; + } + + protected override void Animate(float visualPressAmount) + { + void SetAllOpacity(float lerpProgress) + { + for (var i = 0; i < shadows.Length; i++) + { + var color = shadows[i].Color; + color.a = Mathf.Lerp(0, normalOpacity[i], lerpProgress); + shadows[i].Color = color; + } + } + + bool shouldInset = visualPressAmount > .5f; + + if (shouldInset != wasInset) + { + for (var i = 0; i < shadows.Length; i++) + { + shadows[i].Inset = shouldInset; + } + + wasInset = shouldInset; + } + + if (shouldInset) + { + SetAllOpacity(visualPressAmount * 2f - 1f); + } + else + { + SetAllOpacity(1 - visualPressAmount * 2f); + } + } + + void MemorizeOpacity() + { + if (IsAnimating) return; + + for (var i = 0; i < shadows.Length; i++) + { + normalOpacity[i] = shadows[i].Color.a; + } + } + + protected override void OnWillPress() + { + wasInset = shadows[0].Inset; + MemorizeOpacity(); + base.OnWillPress(); + } +} +} diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Helper/InsetOnPress.cs.meta b/Assets/Le Tai's Asset/TrueShadow/Scripts/Helper/InsetOnPress.cs.meta new file mode 100644 index 0000000..ea8f5a9 --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/Helper/InsetOnPress.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: dd53a06400e8496e82467031771bf46e +timeCreated: 1602747228 \ No newline at end of file diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Helper/InteractiveShadow.cs b/Assets/Le Tai's Asset/TrueShadow/Scripts/Helper/InteractiveShadow.cs new file mode 100644 index 0000000..c286c43 --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/Helper/InteractiveShadow.cs @@ -0,0 +1,242 @@ +using System.Collections; +using UnityEngine; +using UnityEngine.EventSystems; +using UnityEngine.UI; +using static UnityEngine.Mathf; + +namespace LeTai.TrueShadow +{ +[RequireComponent(typeof(TrueShadow))] +public class InteractiveShadow : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler, ISelectHandler, + IDeselectHandler, IPointerDownHandler, IPointerUpHandler +{ + public float smoothTime = .05f; + + [Tooltip("Deselect on pointer up")] + public bool autoDeselect; + + [Header("Size")] + public float selectedSize = 28; + + public float hoverSize = 28; + public float clickedSize = 24; + + [Header("Distance")] + public float selectedDistance = 12; + + public float hoverDistance = 12; + public float clickedDistance = 8; + + [Header("Color")] + public Color selectedColor = new Color(0, 0, 0, .25f); + + public Color hoverColor = new Color(0, 0, 0, .20f); + public Color clickedColor = new Color(0, 0, 0, .25f); + + float normalSize; + float normalDistance; + Color normalColor; + + bool isSelected; + bool isHovered; + bool isClicked; + + TrueShadow shadow; + Selectable selectable; + + float targetSize; + float targetDistance; + Color targetColor; + + static readonly Color FADED_COLOR = new Color(.5f, .5f, .5f, .5f); + +#if UNITY_EDITOR + void Reset() + { + shadow = FindTrueShadow(); + if (shadow) + { + normalSize = shadow.Size; + normalDistance = shadow.OffsetDistance; + normalColor = shadow.Color; + + // Clicked UI remain selected, which is unwanted. Selected state is probably most useful on console + // and keyboard nav, the later is rather hard to detect + bool selectedIsNormal = Input.mousePresent || Input.touchSupported; + autoDeselect = selectedIsNormal; + + hoverSize = Round(Min(normalSize * 1.75f, normalSize + 20f)); + selectedSize = selectedIsNormal ? normalSize : hoverSize; + clickedSize = Round(Min(normalSize * 1.25f, normalSize + 15f)); + + hoverDistance = Round(Min(normalDistance * 1.5f, normalDistance + 20f)); + selectedDistance = selectedIsNormal ? normalDistance : hoverDistance; + clickedDistance = Round(Min(normalDistance * 1.25f, normalDistance + 15f)); + + + hoverColor = Color.Lerp(normalColor, FADED_COLOR, .15f); + selectedColor = selectedIsNormal ? normalColor : hoverColor; + clickedColor = Color.Lerp(normalColor, FADED_COLOR, .25f); + } + } +#endif + + void OnEnable() + { + shadow = FindTrueShadow(); + selectable = GetComponent(); + + targetSize = normalSize = shadow.Size; + targetDistance = normalDistance = shadow.OffsetDistance; + targetColor = normalColor = shadow.Color; + + shadow.Size = targetSize = normalSize; + shadow.OffsetDistance = targetDistance = normalDistance; + } + + TrueShadow FindTrueShadow() + { + var shadows = GetComponents(); + if (shadows.Length == 0) return null; + + var ishadows = GetComponents(); + + int index = 0; + for (; index < ishadows.Length; index++) + if (ishadows[index] == this) + break; + + return shadows[index]; + } + + void OnStateChange() + { + if (isClicked) + { + targetSize = clickedSize; + targetDistance = clickedDistance; + targetColor = clickedColor; + } + else if (isSelected) + { + targetSize = selectedSize; + targetDistance = selectedDistance; + targetColor = selectedColor; + } + else if (isHovered) + { + targetSize = hoverSize; + targetDistance = hoverDistance; + targetColor = hoverColor; + } + else + { + targetSize = normalSize; + targetDistance = normalDistance; + targetColor = normalColor; + } + + + if (selectable && selectable.interactable && selectable.isActiveAndEnabled) + { + if (selectable.transition == Selectable.Transition.ColorTint) + { + StopAllCoroutines(); + StartCoroutine(DirtyForSeconds(selectable.colors.fadeDuration)); + } + } + } + + IEnumerator DirtyForSeconds(float duration) + { + var start = Time.time; + while (start + duration >= Time.time) + { + shadow.SetTextureDirty(); + yield return null; + } + } + + +#region AnimationState + + float currentSizeVelocity; + float currentDistanceVelocity; + float currentColorRVelocity; + float currentColorGVelocity; + float currentColorBVelocity; + float currentColorAVelocity; + +#endregion + + + void Update() + { + if (!Approximately(targetSize, shadow.Size)) + { + shadow.Size = SmoothDamp(shadow.Size, targetSize, + ref currentSizeVelocity, smoothTime); + } + + if (!Approximately(targetDistance, shadow.OffsetDistance)) + { + shadow.OffsetDistance = SmoothDamp(shadow.OffsetDistance, targetDistance, + ref currentDistanceVelocity, smoothTime); + } + + var shadowColor = shadow.Color; + if (!Approximately(targetColor.a, shadowColor.a)) + { + var r = SmoothDamp(shadowColor.r, targetColor.r, + ref currentColorRVelocity, smoothTime); + var g = SmoothDamp(shadowColor.g, targetColor.g, + ref currentColorGVelocity, smoothTime); + var b = SmoothDamp(shadowColor.b, targetColor.b, + ref currentColorBVelocity, smoothTime); + var a = SmoothDamp(shadowColor.a, targetColor.a, + ref currentColorAVelocity, smoothTime); + + shadow.Color = new Color(r, g, b, a); + } + } + + public void OnPointerEnter(PointerEventData eventData) + { + isHovered = true; + OnStateChange(); + } + + public void OnPointerExit(PointerEventData eventData) + { + isHovered = false; + OnStateChange(); + } + + public void OnSelect(BaseEventData eventData) + { + isSelected = true; + OnStateChange(); + } + + public void OnDeselect(BaseEventData eventData) + { + isSelected = false; + OnStateChange(); + } + + public void OnPointerDown(PointerEventData eventData) + { + isClicked = true; + OnStateChange(); + } + + public void OnPointerUp(PointerEventData eventData) + { + if (autoDeselect && EventSystem.current.currentSelectedGameObject == gameObject) + EventSystem.current.SetSelectedGameObject(null); + + isClicked = false; + OnStateChange(); + } +} +} diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Helper/InteractiveShadow.cs.meta b/Assets/Le Tai's Asset/TrueShadow/Scripts/Helper/InteractiveShadow.cs.meta new file mode 100644 index 0000000..ff4f192 --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/Helper/InteractiveShadow.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 2b6bd66378f54ffc974312b194733dd9 +timeCreated: 1593508708 \ No newline at end of file diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/PluginInterfaces.cs b/Assets/Le Tai's Asset/TrueShadow/Scripts/PluginInterfaces.cs new file mode 100644 index 0000000..3576c99 --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/PluginInterfaces.cs @@ -0,0 +1,40 @@ +using UnityEngine; +using UnityEngine.UI; + +namespace LeTai.TrueShadow.PluginInterfaces +{ +public interface ITrueShadowCasterMaterialProvider +{ + Material GetTrueShadowCasterMaterial(); +} + +public interface ITrueShadowCasterMeshModifier +{ + void ModifyTrueShadowCasterMesh(Mesh mesh); +} + +public interface ITrueShadowCasterMaterialPropertiesModifier +{ + void ModifyTrueShadowCasterMaterialProperties(MaterialPropertyBlock propertyBlock); +} + +public interface ITrueShadowCasterClearColorProvider +{ + Color GetTrueShadowCasterClearColor(); +} + +public interface ITrueShadowRendererMaterialProvider +{ + Material GetTrueShadowRendererMaterial(); +} + +public interface ITrueShadowRendererMaterialModifier +{ + void ModifyTrueShadowRendererMaterial(Material baseMaterial); +} + +public interface ITrueShadowRendererMeshModifier +{ + void ModifyTrueShadowRenderMesh(VertexHelper vertexHelper); +} +} diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/PluginInterfaces.cs.meta b/Assets/Le Tai's Asset/TrueShadow/Scripts/PluginInterfaces.cs.meta new file mode 100644 index 0000000..49f3031 --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/PluginInterfaces.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 81f076a2e89b8b34da77ca09f22cfe59 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/ShadowFactory.cs b/Assets/Le Tai's Asset/TrueShadow/Scripts/ShadowFactory.cs new file mode 100644 index 0000000..46dce7a --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/ShadowFactory.cs @@ -0,0 +1,312 @@ +using System.Collections.Generic; +using LeTai.Effects; +using UnityEngine; +using UnityEngine.Rendering; + +namespace LeTai.TrueShadow +{ +public class ShadowFactory +{ + private static ShadowFactory instance; + public static ShadowFactory Instance => instance ?? (instance = new ShadowFactory()); + + readonly Dictionary shadowCache = + new Dictionary(); + + readonly CommandBuffer cmd; + readonly MaterialPropertyBlock materialProps; + readonly ScalableBlur blurProcessor; + readonly ScalableBlurConfig blurConfig; + + Material cutoutMaterial; + Material imprintPostProcessMaterial; + Material shadowPostProcessMaterial; + + Material CutoutMaterial => + cutoutMaterial ? cutoutMaterial : cutoutMaterial = new Material(Shader.Find("Hidden/TrueShadow/Cutout")); + + Material ImprintPostProcessMaterial => + imprintPostProcessMaterial + ? imprintPostProcessMaterial + : imprintPostProcessMaterial = new Material(Shader.Find("Hidden/TrueShadow/ImprintPostProcess")); + + Material ShadowPostProcessMaterial => + shadowPostProcessMaterial + ? shadowPostProcessMaterial + : shadowPostProcessMaterial = new Material(Shader.Find("Hidden/TrueShadow/PostProcess")); + + private ShadowFactory() + { + cmd = new CommandBuffer {name = "Shadow Commands"}; + materialProps = new MaterialPropertyBlock(); + materialProps.SetVector(ShaderId.CLIP_RECT, + new Vector4(float.NegativeInfinity, float.NegativeInfinity, + float.PositiveInfinity, float.PositiveInfinity)); + materialProps.SetInt(ShaderId.COLOR_MASK, (int) ColorWriteMask.All); // Render shadow even if mask hide graphic + + ShaderProperties.Init(8); + blurConfig = ScriptableObject.CreateInstance(); + blurConfig.hideFlags = HideFlags.HideAndDontSave; + blurProcessor = new ScalableBlur(); + blurProcessor.Configure(blurConfig); + } + + ~ShadowFactory() + { + cmd.Dispose(); + Utility.SafeDestroy(blurConfig); + Utility.SafeDestroy(cutoutMaterial); + Utility.SafeDestroy(imprintPostProcessMaterial); + } + +#if LETAI_TRUESHADOW_DEBUG + RenderTexture debugTexture; +#endif + + // public int createdContainerCount; + // public int releasedContainerCount; + + internal void Get(ShadowSettingSnapshot snapshot, ref ShadowContainer container) + { + if (float.IsNaN(snapshot.dimensions.x) || snapshot.dimensions.x < 1 || + float.IsNaN(snapshot.dimensions.y) || snapshot.dimensions.y < 1) + { + ReleaseContainer(container); + return; + } + +#if LETAI_TRUESHADOW_DEBUG + RenderTexture.ReleaseTemporary(debugTexture); + if (snapshot.shadow.alwaysRender) + debugTexture = GenerateShadow(snapshot).Texture; +#endif + + // Each request need a coresponding shadow texture + // Texture may be shared by multiple elements + // Texture are released when no longer used by any element + // ShadowContainer keep track of texture and their usage + + + int requestHash = snapshot.GetHashCode(); + + // Case: requester can keep the same texture + if (container?.requestHash == requestHash) + return; + + ReleaseContainer(container); + + if (shadowCache.TryGetValue(requestHash, out var existingContainer)) + { + // Case: requester got texture from someone else + existingContainer.RefCount++; + container = existingContainer; + } + else + { + // Case: requester got new unique texture + container = shadowCache[requestHash] = GenerateShadow(snapshot); + // Debug.Log($"Created new container for request\t{requestHash}\tTotal Created: {++createdContainerCount}\t Alive: {createdContainerCount - releasedContainerCount}"); + } + } + + internal void ReleaseContainer(ShadowContainer container) + { + if (container == null) + return; + + if (--container.RefCount > 0) + return; + + RenderTexture.ReleaseTemporary(container.Texture); + shadowCache.Remove(container.requestHash); + + // Debug.Log($"Released container for request\t{container.requestHash}\tTotal Released: {++releasedContainerCount}\t Alive: {createdContainerCount - releasedContainerCount}"); + } + + static readonly Rect UNIT_RECT = new Rect(0, 0, 1, 1); + + ShadowContainer GenerateShadow(ShadowSettingSnapshot snapshot) + { + // return GenColoredTexture(request.GetHashCode()); + + cmd.Clear(); + cmd.BeginSample("TrueShadow:Capture"); + + var bounds = snapshot.shadow.SpriteMesh.bounds; + var misalignment = CalcMisalignment(snapshot.canvas, snapshot.canvasRt, snapshot.shadow.RectTransform, bounds); + + var padding = Mathf.CeilToInt(snapshot.size); + var imprintViewW = Mathf.RoundToInt(snapshot.dimensions.x + misalignment.bothSS.x); + var imprintViewH = Mathf.RoundToInt(snapshot.dimensions.y + misalignment.bothSS.y); + var tw = imprintViewW + padding * 2; + var th = imprintViewH + padding * 2; + + var shadowTex = RenderTexture.GetTemporary(tw, th, 0, RenderTextureFormat.ARGB32); + var imprintTexDesc = shadowTex.descriptor; + imprintTexDesc.msaaSamples = snapshot.shouldAntialiasImprint ? Mathf.Max(1, QualitySettings.antiAliasing) : 1; + var imprintTex = RenderTexture.GetTemporary(imprintTexDesc); + + RenderTexture imprintTexProcessed = null; + + bool needProcessImprint = snapshot.shadow.IgnoreCasterColor || snapshot.shadow.Inset; + if (needProcessImprint) + imprintTexProcessed = RenderTexture.GetTemporary(imprintTexDesc); + + var texture = snapshot.shadow.Content; + if (texture) + materialProps.SetTexture(ShaderId.MAIN_TEX, texture); + else + materialProps.SetTexture(ShaderId.MAIN_TEX, Texture2D.whiteTexture); + + cmd.SetRenderTarget(imprintTex); + cmd.ClearRenderTarget(true, true, snapshot.shadow.ClearColor); + + cmd.SetViewport(new Rect(padding, padding, imprintViewW, imprintViewH)); + + var imprintBoundMin = (Vector2) bounds.min - misalignment.minLS; + var imprintBoundMax = (Vector2) bounds.max + misalignment.maxLS; + cmd.SetViewProjectionMatrices( + Matrix4x4.identity, + Matrix4x4.Ortho(imprintBoundMin.x, imprintBoundMax.x, + imprintBoundMin.y, imprintBoundMax.y, + -1, 1) + ); + + snapshot.shadow.ModifyShadowCastingMesh(snapshot.shadow.SpriteMesh); + snapshot.shadow.ModifyShadowCastingMaterialProperties(materialProps); + cmd.DrawMesh(snapshot.shadow.SpriteMesh, + Matrix4x4.identity, + snapshot.shadow.GetShadowCastingMaterial(), + 0, 0, + materialProps); + + if (needProcessImprint) + { + ImprintPostProcessMaterial.SetKeyword("BLEACH", snapshot.shadow.IgnoreCasterColor); + ImprintPostProcessMaterial.SetKeyword("INSET", snapshot.shadow.Inset); + + cmd.Blit(imprintTex, imprintTexProcessed, ImprintPostProcessMaterial); + } + + cmd.EndSample("TrueShadow:Capture"); + + var needPostProcess = snapshot.shadow.Spread > 1e-3; + + cmd.BeginSample("TrueShadow:Cast"); + RenderTexture blurSrc = needProcessImprint ? imprintTexProcessed : imprintTex; + RenderTexture blurDst; + if (needPostProcess) + blurDst = RenderTexture.GetTemporary(shadowTex.descriptor); + else + blurDst = shadowTex; + + if (snapshot.size < 1e-2) + { + cmd.Blit(blurSrc, blurDst); + } + else + { + blurConfig.Strength = snapshot.size; + blurProcessor.Blur(cmd, blurSrc, UNIT_RECT, blurDst); + } + + cmd.EndSample("TrueShadow:Cast"); + + var relativeOffset = new Vector2(snapshot.canvasRelativeOffset.x / tw, + snapshot.canvasRelativeOffset.y / th); + var overflowAlpha = snapshot.shadow.Inset ? 1 : 0; + if (needPostProcess) + { + cmd.BeginSample("TrueShadow:PostProcess"); + + ShadowPostProcessMaterial.SetTexture(ShaderId.SHADOW_TEX, blurDst); + ShadowPostProcessMaterial.SetVector(ShaderId.OFFSET, relativeOffset); + ShadowPostProcessMaterial.SetFloat(ShaderId.OVERFLOW_ALPHA, overflowAlpha); + ShadowPostProcessMaterial.SetFloat(ShaderId.ALPHA_MULTIPLIER, + 1f / Mathf.Max(1e-6f, 1f - snapshot.shadow.Spread)); + + cmd.SetViewport(UNIT_RECT); + cmd.Blit(blurSrc, shadowTex, ShadowPostProcessMaterial); + + cmd.EndSample("TrueShadow:PostProcess"); + } + else if (snapshot.shadow.Cutout) + { + cmd.BeginSample("TrueShadow:Cutout"); + + CutoutMaterial.SetVector(ShaderId.OFFSET, relativeOffset); + CutoutMaterial.SetFloat(ShaderId.OVERFLOW_ALPHA, overflowAlpha); + + cmd.SetViewport(UNIT_RECT); + cmd.Blit(blurSrc, shadowTex, CutoutMaterial); + + cmd.EndSample("TrueShadow:Cutout"); + } + + Graphics.ExecuteCommandBuffer(cmd); + + RenderTexture.ReleaseTemporary(imprintTex); + RenderTexture.ReleaseTemporary(blurSrc); + if (needPostProcess) + RenderTexture.ReleaseTemporary(blurDst); + + return new ShadowContainer(shadowTex, snapshot, padding, misalignment.minLS); + } + + readonly struct PixelMisalignment + { + public readonly Vector2 bothSS; + public readonly Vector2 minLS; + public readonly Vector2 maxLS; + + public PixelMisalignment(Vector2 bothSS, Vector2 minLS, Vector2 maxLS) + { + this.bothSS = bothSS; + this.minLS = minLS; + this.maxLS = maxLS; + } + } + + PixelMisalignment CalcMisalignment(Canvas canvas, RectTransform canvasRt, RectTransform casterRt, Bounds meshBound) + { + PixelMisalignment misalignment; + + if (canvas.renderMode == RenderMode.WorldSpace) + { + misalignment = new PixelMisalignment(); + } + else + { + var referenceCamera = canvas.renderMode == RenderMode.ScreenSpaceCamera ? canvas.worldCamera : null; + + var pxMisalignmentAtMin = casterRt.LocalToScreenPoint(meshBound.min, referenceCamera).Frac(); + var pxMisalignmentAtMax = + Vector2.one - casterRt.LocalToScreenPoint(meshBound.max, referenceCamera).Frac(); + if (pxMisalignmentAtMax.x > 1 - 1e-5) + pxMisalignmentAtMax.x = 0; + if (pxMisalignmentAtMax.y > 1 - 1e-5) + pxMisalignmentAtMax.y = 0; + + misalignment = new PixelMisalignment( + pxMisalignmentAtMin + pxMisalignmentAtMax, + canvasRt.ScreenToCanvasSize(pxMisalignmentAtMin, referenceCamera), + canvasRt.ScreenToCanvasSize(pxMisalignmentAtMax, referenceCamera) + ); + } + + return misalignment; + } + + RenderTexture GenColoredTexture(int hash) + { + var tex = new Texture2D(1, 1); + tex.SetPixels32(new[] {new Color32((byte) (hash >> 8), (byte) (hash >> 16), (byte) (hash >> 24), 255)}); + tex.Apply(); + + var rt = RenderTexture.GetTemporary(1, 1); + Graphics.Blit(tex, rt); + + return rt; + } +} +} diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/ShadowFactory.cs.meta b/Assets/Le Tai's Asset/TrueShadow/Scripts/ShadowFactory.cs.meta new file mode 100644 index 0000000..6af0ab0 --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/ShadowFactory.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b8d1278f371c48a784a5294591372531 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/ShadowRenderer.MaskHandling.cs b/Assets/Le Tai's Asset/TrueShadow/Scripts/ShadowRenderer.MaskHandling.cs new file mode 100644 index 0000000..bc07dfe --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/ShadowRenderer.MaskHandling.cs @@ -0,0 +1,76 @@ +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.Rendering; +using UnityEngine.UI; + +namespace LeTai.TrueShadow +{ +public partial class ShadowRenderer +{ + // TODO: cleanup unused mask materials + static readonly Dictionary<(bool, Material), Material> MASK_MATERIALS_CACHE = + new Dictionary<(bool, Material), Material>(); + + internal static void ClearMaskMaterialCache() + { + foreach (var keyValuePair in MASK_MATERIALS_CACHE) + { + if(Application.isPlaying) + Destroy(keyValuePair.Value); + else + DestroyImmediate(keyValuePair.Value); + } + + MASK_MATERIALS_CACHE.Clear(); + } + + public Material GetModifiedMaterial(Material baseMaterial) + { + if (!shadow) + return baseMaterial; + + shadow.ModifyShadowRendererMaterial(baseMaterial); + + if (!baseMaterial.HasProperty(ShaderId.COLOR_MASK) || + !baseMaterial.HasProperty(ShaderId.STENCIL_OP)) + return baseMaterial; + + bool casterIsMask = shadow.GetComponent() != null; + + MASK_MATERIALS_CACHE.TryGetValue((casterIsMask, baseMaterial), out var mat); + + if (!mat) + { + mat = new Material(baseMaterial); + + if (shadow.ShadowAsSibling) + { + // Prevent shadow from writing to stencil mask + mat.SetInt(ShaderId.COLOR_MASK, (int) ColorWriteMask.All); + mat.SetInt(ShaderId.STENCIL_OP, (int) StencilOp.Keep); + } + else if (casterIsMask) + { + // Escape mask if we have one + var baseStencilId = mat.GetInt(ShaderId.STENCIL_ID) + 1; + int stencilDepth = 0; + for (; stencilDepth < 8; stencilDepth++) + { + if (((baseStencilId >> stencilDepth) & 1) == 1) + break; + } + + stencilDepth = Mathf.Max(0, stencilDepth - 1); + var stencilId = (1 << stencilDepth) - 1; + + mat.SetInt(ShaderId.STENCIL_ID, stencilId); + mat.SetInt(ShaderId.STENCIL_READ_MASK, stencilId); + } + + MASK_MATERIALS_CACHE[(casterIsMask, baseMaterial)] = mat; + } + + return mat; + } +} +} diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/ShadowRenderer.MaskHandling.cs.meta b/Assets/Le Tai's Asset/TrueShadow/Scripts/ShadowRenderer.MaskHandling.cs.meta new file mode 100644 index 0000000..fa4222d --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/ShadowRenderer.MaskHandling.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: b035d21af0d3447296a96ea4f27b5f53 +timeCreated: 1600848777 \ No newline at end of file diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/ShadowRenderer.cs b/Assets/Le Tai's Asset/TrueShadow/Scripts/ShadowRenderer.cs new file mode 100644 index 0000000..39b968a --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/ShadowRenderer.cs @@ -0,0 +1,189 @@ +using System; +using UnityEngine; +using UnityEngine.UI; + +namespace LeTai.TrueShadow +{ +[AddComponentMenu("")] +[ExecuteAlways] +public partial class ShadowRenderer : MonoBehaviour, ILayoutIgnorer, IMaterialModifier, IMeshModifier +{ + public bool ignoreLayout => true; + + internal CanvasRenderer CanvasRenderer { get; private set; } + + TrueShadow shadow; + RectTransform rt; + RawImage graphic; + Texture shadowTexture; + + public static void Initialize(TrueShadow shadow, ref ShadowRenderer renderer) + { + if (renderer && renderer.shadow == shadow) + { + renderer.gameObject.SetActive(true); + return; + } + + var obj = new GameObject($"{shadow.gameObject.name}'s Shadow") { +#if LETAI_TRUESHADOW_DEBUG + hideFlags = DebugSettings.Instance.showObjects + ? HideFlags.DontSave + : HideFlags.HideAndDontSave +#else + hideFlags = HideFlags.HideAndDontSave +#endif + }; + +#if LETAI_TRUESHADOW_DEBUG && UNITY_EDITOR + UnityEditor.SceneVisibilityManager.instance.DisablePicking(obj, true); +#endif + + shadow.SetHierachyDirty(); + + var rt = obj.AddComponent(); + rt.anchorMin = Vector2.zero; + rt.anchorMax = Vector2.zero; + + var graphic = obj.AddComponent(); + graphic.raycastTarget = false; + graphic.color = shadow.Color; + + renderer = obj.AddComponent(); + renderer.shadow = shadow; + renderer.rt = rt; + renderer.graphic = graphic; + + // renderer.RecreateGraphic(shadow.Baked ? GraphicType.Image : GraphicType.RawImage); + + renderer.UpdateMaterial(); + + renderer.CanvasRenderer = obj.GetComponent(); + renderer.CanvasRenderer.SetColor(shadow.IgnoreCasterColor ? Color.white : shadow.CanvasRenderer.GetColor()); + renderer.CanvasRenderer.SetAlpha(shadow.CanvasRenderer.GetAlpha()); + + renderer.ReLayout(); + } + + public void UpdateMaterial() + { + var mat = shadow.BlendMode.GetMaterial(); + graphic.material = mat ? mat : shadow.GetShadowRenderingNormalMaterial(); + } + + internal void ReLayout() + { + if (!isActiveAndEnabled) + return; + + var casterRt = shadow.RectTransform; + if (!casterRt) + { + CanvasRenderer.SetAlpha(0); + return; + } + + if (!shadowTexture) + { + CanvasRenderer.SetAlpha(0); + return; + } + + var container = shadow.ShadowContainer; + var canvasScale = container?.Snapshot?.canvasScale ?? graphic.canvas.scaleFactor; + + var shadowTexSize = new Vector2(shadowTexture.width, shadowTexture.height) / canvasScale; + rt.sizeDelta = shadowTexSize; + + // pivot should be relative to the un-blurred part of the texture, not the whole mesh + var casterPivotLS = -(Vector2) shadow.SpriteMesh.bounds.min; + var padding = (container?.Padding ?? Mathf.CeilToInt(shadow.Size * canvasScale)) / canvasScale * Vector2.one; + var misalign = container?.PxMisalignmentAtMinLS ?? Vector2.zero; + rt.pivot = (casterPivotLS + padding + misalign) / shadowTexSize; + + + var canvasRelativeOffset = container?.Snapshot?.canvasRelativeOffset / canvasScale ?? shadow.Offset; + var offset = shadow.ShadowAsSibling + ? shadow.Offset.WithZ(0) + : canvasRelativeOffset.WithZ(0); + rt.localPosition = shadow.ShadowAsSibling + ? casterRt.localPosition + offset + : offset; + + rt.localRotation = shadow.ShadowAsSibling ? casterRt.localRotation : Quaternion.identity; + rt.localScale = shadow.ShadowAsSibling ? casterRt.localScale : Vector3.one; + + + var color = shadow.Color; + if (shadow.UseCasterAlpha) + color.a *= shadow.Graphic.color.a; + graphic.color = color; + + CanvasRenderer.SetColor(shadow.IgnoreCasterColor ? Color.white : shadow.CanvasRenderer.GetColor()); + CanvasRenderer.SetAlpha(shadow.CanvasRenderer.GetAlpha()); + + graphic.Rebuild(CanvasUpdate.PreRender); + } + + public void SetTexture(Texture texture) + { + shadowTexture = texture; + CanvasRenderer.SetTexture(texture); + graphic.texture = texture; + } + + public void SetMaterialDirty() + { + graphic.SetMaterialDirty(); + } + + public void ModifyMesh(VertexHelper vertexHelper) + { + if (!shadow) + return; + + shadow.ModifyShadowRendererMesh(vertexHelper); + } + + public void ModifyMesh(Mesh mesh) + { + Debug.Assert(true, "This should only be called on old unsupported Unity version"); + } + + protected virtual void LateUpdate() + { + // Destroy events are not consistently called for some reason, have to poll + if (!shadow) + Dispose(); + } + + bool willBeDestroyed; + + protected virtual void OnDestroy() + { + willBeDestroyed = true; + } + + public void Dispose() + { + if (willBeDestroyed) return; + + if (shadow && shadow.ShadowAsSibling) + { + // Destroy does not happen immediately. Want out of hierarchy. + gameObject.SetActive(false); + transform.SetParent(null); + } + +#if UNITY_EDITOR + // This look redundant but is necessary! + if (!Application.isPlaying && !UnityEditor.EditorApplication.isPlayingOrWillChangePlaymode) + DestroyImmediate(gameObject); + else if (Application.isPlaying) + Destroy(gameObject); +#else + Destroy(gameObject); +#endif + } +} +} diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/ShadowRenderer.cs.meta b/Assets/Le Tai's Asset/TrueShadow/Scripts/ShadowRenderer.cs.meta new file mode 100644 index 0000000..a16fa95 --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/ShadowRenderer.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 8c213e24c3734f43b893d039b31ac5bc +timeCreated: 1592813121 \ No newline at end of file diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/ShadowSettingSnapshot.cs b/Assets/Le Tai's Asset/TrueShadow/Scripts/ShadowSettingSnapshot.cs new file mode 100644 index 0000000..85cd037 --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/ShadowSettingSnapshot.cs @@ -0,0 +1,139 @@ +using System; +using UnityEngine; +using UnityEngine.UI; + +namespace LeTai.TrueShadow +{ +class ShadowSettingSnapshot +{ + public readonly TrueShadow shadow; + public readonly Canvas canvas; + public readonly RectTransform canvasRt; + public readonly bool shouldAntialiasImprint; + public readonly float canvasScale; + public readonly float size; + public readonly Vector2 canvasRelativeOffset; + public readonly Vector2 dimensions; + + internal ShadowSettingSnapshot(TrueShadow shadow) + { + this.shadow = shadow; + canvas = shadow.Graphic.canvas; + canvasRt = (RectTransform) canvas.transform; + + var meshBound = shadow.SpriteMesh.bounds; + + shouldAntialiasImprint = canvas.renderMode != RenderMode.ScreenSpaceOverlay; + + canvasScale = canvas.scaleFactor; + + var canvasRelativeRotation = Quaternion.Inverse(canvasRt.rotation) * shadow.RectTransform.rotation; + canvasRelativeOffset = shadow.Offset.Rotate(-canvasRelativeRotation.eulerAngles.z) * canvasScale; + + dimensions = (Vector2) meshBound.size * canvasScale; + size = shadow.Size * canvasScale; + + CalcHash(); + } + + const int DIMENSIONS_HASH_STEP = 1; + + void CalcHash() + { + var graphic = shadow.Graphic; + + int canvasScaleHash = (int) (canvasScale * 1e4); + int insetHash = shadow.Inset ? 1 : 0; + + var clearColor = shadow.ClearColor; + var imageColor = graphic.color; + int colorHash = HashUtils.CombineHashCodes( + shadow.IgnoreCasterColor ? 1 : 0, + (int) shadow.ColorBleedMode, + (int) (imageColor.r * 255), + (int) (imageColor.g * 255), + (int) (imageColor.b * 255), + (int) (imageColor.a * 255), + (int) (clearColor.r * 255), + (int) (clearColor.g * 255), + (int) (clearColor.b * 255), + (int) (clearColor.a * 255) + ); + + // Hack until we have separated cutout cache, or proper sibling mode + int offsetHash = HashUtils.CombineHashCodes( + shadow.Cutout ? 1 : 0, + (int) (canvasRelativeOffset.x * 100), + (int) (canvasRelativeOffset.y * 100) + ); + + // Tiled type cannot be batched by similar size + int dimensionHash = graphic is Image im && im.type == Image.Type.Tiled + ? dimensions.GetHashCode() + : HashUtils.CombineHashCodes( + Mathf.CeilToInt(dimensions.x / DIMENSIONS_HASH_STEP) * DIMENSIONS_HASH_STEP, + Mathf.CeilToInt(dimensions.y / DIMENSIONS_HASH_STEP) * DIMENSIONS_HASH_STEP + ); + + var sizeHash = Mathf.CeilToInt(size * 100); + + var commonHash = HashUtils.CombineHashCodes( + shadow.TextureRevision, + canvasScaleHash, + insetHash, + colorHash, + offsetHash, + dimensionHash, + sizeHash + ); + + switch (graphic) + { + case Image image: + int spriteHash = 0; + if (image.sprite) + spriteHash = image.sprite.GetHashCode(); + + int imageHash = HashUtils.CombineHashCodes( + (int) image.type, + (int) (image.fillAmount * 360 * 20), + (int) image.fillMethod, + image.fillOrigin, + image.fillClockwise ? 1 : 0 + ); + + hash = HashUtils.CombineHashCodes( + commonHash, + spriteHash, + imageHash + ); + break; + case RawImage rawImage: + var textureHash = 0; + if (rawImage.texture) + textureHash = rawImage.texture.GetInstanceID(); + + hash = HashUtils.CombineHashCodes( + commonHash, + textureHash + ); + break; + default: + hash = commonHash; + break; + } + } + + int hash; + + // ReSharper disable once NonReadonlyMemberInGetHashCode + public override int GetHashCode() => hash; + + public override bool Equals(object obj) + { + if (obj == null) return false; + + return GetHashCode() == obj.GetHashCode(); + } +} +} diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/ShadowSettingSnapshot.cs.meta b/Assets/Le Tai's Asset/TrueShadow/Scripts/ShadowSettingSnapshot.cs.meta new file mode 100644 index 0000000..1fb2950 --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/ShadowSettingSnapshot.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 93693e4b8ffcbca48bc39fba2e37ffda +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/ShadowSorter.cs b/Assets/Le Tai's Asset/TrueShadow/Scripts/ShadowSorter.cs new file mode 100644 index 0000000..06387db --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/ShadowSorter.cs @@ -0,0 +1,193 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace LeTai.TrueShadow +{ +[ExecuteAlways] +public class ShadowSorter : MonoBehaviour +{ +#region SortDataContainer + readonly struct SortEntry : IComparable + { + public readonly TrueShadow shadow; + public readonly Transform shadowTransform; + public readonly Transform rendererTransform; + + public SortEntry(TrueShadow shadow) + { + this.shadow = shadow; + shadowTransform = shadow.transform; + rendererTransform = shadow.shadowRenderer.transform; + } + + public int CompareTo(SortEntry other) + { + return other.shadowTransform.GetSiblingIndex().CompareTo(shadowTransform.GetSiblingIndex()); + } + } + + readonly struct SortGroup + { + public readonly Transform parentTransform; + public readonly List sortEntries; + + public SortGroup(SortEntry firstEntry) + { + sortEntries = new List {firstEntry}; + parentTransform = firstEntry.shadowTransform.parent; + } + + public void Add(SortEntry pair) + { + if (pair.shadowTransform.parent != parentTransform) + return; + + var index = sortEntries.BinarySearch(pair); + if (index < 0) + sortEntries.Insert(~index, pair); + } + + public override int GetHashCode() + { + return parentTransform.GetHashCode(); + } + + public override bool Equals(object obj) + { + return obj is SortGroup other && other.parentTransform == parentTransform; + } + } +#endregion + + + private static ShadowSorter instance; + + public static ShadowSorter Instance + { + get + { + if (!instance) + { + var existings = FindObjectsOfType(); + for (int i = existings.Length - 1; i > 0; i--) + { + Destroy(existings[i]); + } + +#if UNITY_EDITOR + var hidden = GameObject.Find("/" + nameof(ShadowSorter)); + while (hidden) + { + DestroyImmediate(hidden); + hidden = GameObject.Find("/" + nameof(ShadowSorter)); + } +#endif + + instance = existings.Length > 0 ? existings[0] : null; + + if (!instance) + { + var obj = new GameObject(nameof(ShadowSorter)) { +#if LETAI_TRUESHADOW_DEBUG + hideFlags = DebugSettings.Instance.showObjects + ? HideFlags.DontSave + : HideFlags.HideAndDontSave +#else + hideFlags = HideFlags.HideAndDontSave +#endif + }; + instance = obj.AddComponent(); + } + } + + return instance; + } + } + + readonly IndexedSet shadows = new IndexedSet(); + readonly IndexedSet sortGroups = new IndexedSet(); + + public void Register(TrueShadow shadow) + { + shadows.AddUnique(shadow); + } + + public void UnRegister(TrueShadow shadow) + { + shadows.Remove(shadow); + } + + void LateUpdate() + { + if (!this) return; + + for (var i = 0; i < shadows.Count; i++) + { + var shadow = shadows[i]; + + if (!shadow || !shadow.isActiveAndEnabled) + continue; + + shadow.CheckHierarchyDirtied(); + if (shadow.hierachyDirty) + AddSortEntry(shadow); + } + + Sort(); + } + + void AddSortEntry(TrueShadow shadow) + { + var entry = new SortEntry(shadow); + var group = new SortGroup(entry); + var oldIndex = sortGroups.IndexOf(group); + if (oldIndex > -1) + sortGroups[oldIndex].Add(entry); + else + sortGroups.Add(group); + } + + public void Sort() + { + for (var i = 0; i < sortGroups.Count; i++) + { + var group = sortGroups[i]; + + if (!group.parentTransform) + continue; + + foreach (var entry in group.sortEntries) + { + entry.rendererTransform.SetParent(group.parentTransform, false); + var rendererSid = entry.rendererTransform.GetSiblingIndex(); + var shadowSid = entry.shadowTransform.GetSiblingIndex(); + if (rendererSid > shadowSid) + { + entry.rendererTransform.SetSiblingIndex(shadowSid); + } + else + { + entry.rendererTransform.SetSiblingIndex(shadowSid - 1); + } + + entry.shadow.UnSetHierachyDirty(); + } + + // This is a separated loop, as siblind index of an entry will be affected by the laters + foreach (var entry in group.sortEntries) + { + entry.shadow.ForgetSiblingIndexChanges(); + } + } + + sortGroups.Clear(); + } + + void OnApplicationQuit() + { + // make sure object are recreated when exit play mode. Otherwise it turn into some weird state. need more research + Destroy(gameObject); + } +} +} diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/ShadowSorter.cs.meta b/Assets/Le Tai's Asset/TrueShadow/Scripts/ShadowSorter.cs.meta new file mode 100644 index 0000000..7d1f482 --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/ShadowSorter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cbf4f3c805fa455abb21fbb9ad6e54d5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Structure.meta b/Assets/Le Tai's Asset/TrueShadow/Scripts/Structure.meta new file mode 100644 index 0000000..fa4e013 --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/Structure.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: f395e653641dd7442bba503cb28b07a0 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Structure/BlendMode.cs b/Assets/Le Tai's Asset/TrueShadow/Scripts/Structure/BlendMode.cs new file mode 100644 index 0000000..c970ca2 --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/Structure/BlendMode.cs @@ -0,0 +1,42 @@ +using System; +using UnityEngine; + +namespace LeTai.TrueShadow +{ +public enum BlendMode +{ + Normal, + Additive, + Screen, + Multiply, +} + +public static class BlendModeExtensions +{ + static Material matNormal; + static Material materialAdditive; + static Material matScreen; + static Material matMultiply; + + public static Material GetMaterial(this BlendMode blendMode) + { + switch (blendMode) + { + case BlendMode.Normal: + if (!matNormal) matNormal = new Material(Shader.Find("UI/TrueShadow-Normal")); + return matNormal; + case BlendMode.Additive: + if (!materialAdditive) materialAdditive = new Material(Shader.Find("UI/TrueShadow-Additive")); + return materialAdditive; + case BlendMode.Screen: + if (!matScreen) matScreen = new Material(Shader.Find("UI/TrueShadow-Screen")); + return matScreen; + case BlendMode.Multiply: + if (!matMultiply) matMultiply = new Material(Shader.Find("UI/TrueShadow-Multiply")); + return matMultiply; + default: + throw new ArgumentOutOfRangeException(); + } + } +} +} diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Structure/BlendMode.cs.meta b/Assets/Le Tai's Asset/TrueShadow/Scripts/Structure/BlendMode.cs.meta new file mode 100644 index 0000000..da65942 --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/Structure/BlendMode.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 3379d45961064912b9e67abda88f84da +timeCreated: 1594095942 \ No newline at end of file diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Structure/ColorBleedMode.cs b/Assets/Le Tai's Asset/TrueShadow/Scripts/Structure/ColorBleedMode.cs new file mode 100644 index 0000000..e5fe168 --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/Structure/ColorBleedMode.cs @@ -0,0 +1,11 @@ +namespace LeTai.TrueShadow +{ +public enum ColorBleedMode +{ + ImageColor, + ShadowColor, + Black, + White, + Plugin +} +} diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Structure/ColorBleedMode.cs.meta b/Assets/Le Tai's Asset/TrueShadow/Scripts/Structure/ColorBleedMode.cs.meta new file mode 100644 index 0000000..482339f --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/Structure/ColorBleedMode.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: e19e27572a184315b94a65c4dcbc9d98 +timeCreated: 1596027283 \ No newline at end of file diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Structure/ShadowContainer.cs b/Assets/Le Tai's Asset/TrueShadow/Scripts/Structure/ShadowContainer.cs new file mode 100644 index 0000000..8a4254e --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/Structure/ShadowContainer.cs @@ -0,0 +1,29 @@ +using UnityEngine; + +namespace LeTai.TrueShadow +{ +class ShadowContainer +{ + public RenderTexture Texture { get; } + public ShadowSettingSnapshot Snapshot { get; } + public int Padding { get; } + public Vector2 PxMisalignmentAtMinLS { get; } + + public int RefCount { get; internal set; } + + public readonly int requestHash; + + internal ShadowContainer(RenderTexture texture, + ShadowSettingSnapshot snapshot, + int padding, + Vector2 pxMisalignmentAtMinLS) + { + Texture = texture; + Snapshot = snapshot; + Padding = padding; + PxMisalignmentAtMinLS = pxMisalignmentAtMinLS; + RefCount = 1; + requestHash = snapshot.GetHashCode(); + } +} +} diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Structure/ShadowContainer.cs.meta b/Assets/Le Tai's Asset/TrueShadow/Scripts/Structure/ShadowContainer.cs.meta new file mode 100644 index 0000000..57503c1 --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/Structure/ShadowContainer.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: de9d78182ae045cfad04addb713cf2e0 +timeCreated: 1595408371 \ No newline at end of file diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/TrueShadow.Invalidator.cs b/Assets/Le Tai's Asset/TrueShadow/Scripts/TrueShadow.Invalidator.cs new file mode 100644 index 0000000..ae5b58c --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/TrueShadow.Invalidator.cs @@ -0,0 +1,208 @@ +using System; +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.UI; + +namespace LeTai.TrueShadow +{ +interface IChangeTracker +{ + void Check(); +} + +class ChangeTracker : IChangeTracker +{ + T previousValue; + readonly Func getValue; + readonly Func onChange; + readonly IEqualityComparer comparer; + + public ChangeTracker(Func getValue, + Func onChange, + IEqualityComparer comparer = null) + { + this.getValue = getValue; + this.onChange = onChange; + this.comparer = comparer ?? EqualityComparer.Default; + + previousValue = this.getValue(); + } + + public void Forget() + { + previousValue = getValue(); + } + + public void Check() + { + T newValue = getValue(); + if (!comparer.Equals(newValue, previousValue)) + { + previousValue = onChange(newValue); + } + } +} + +public partial class TrueShadow +{ + Action checkHierarchyDirtiedDelegate; + IChangeTracker[] transformTrackers; + ChangeTracker[] hierachyTrackers; + + void InitInvalidator() + { + checkHierarchyDirtiedDelegate = CheckHierarchyDirtied; + hierachyTrackers = new[] { + new ChangeTracker( + () => transform.GetSiblingIndex(), + newValue => + { + SetHierachyDirty(); + return newValue; // + 1; + } + ), + new ChangeTracker( + () => + { + if (shadowRenderer) + return shadowRenderer.transform.GetSiblingIndex(); + return -1; + }, + newValue => + { + SetHierachyDirty(); + return newValue; // + 1; + } + ) + }; + + transformTrackers = new IChangeTracker[] { + new ChangeTracker( + () => transform.position, + newValue => + { + SetLayoutDirty(); + return newValue; + } + ), + new ChangeTracker( + () => transform.rotation, + newValue => + { + SetLayoutDirty(); + if (Cutout) + SetTextureDirty(); + return newValue; + } + ), + }; + + Graphic.RegisterDirtyLayoutCallback(SetLayoutTextureDirty); + Graphic.RegisterDirtyVerticesCallback(SetLayoutTextureDirty); + Graphic.RegisterDirtyMaterialCallback(OnGraphicMaterialDirty); + + CheckHierarchyDirtied(); + CheckTransformDirtied(); + } + + void TerminateInvalidator() + { + if (Graphic) + { + Graphic.UnregisterDirtyLayoutCallback(SetLayoutTextureDirty); + Graphic.UnregisterDirtyVerticesCallback(SetLayoutTextureDirty); + Graphic.UnregisterDirtyMaterialCallback(OnGraphicMaterialDirty); + } + } + + void OnGraphicMaterialDirty() + { + SetLayoutTextureDirty(); + shadowRenderer.UpdateMaterial(); + } + + internal void CheckTransformDirtied() + { + if (transformTrackers != null) + { + for (var i = 0; i < transformTrackers.Length; i++) + { + transformTrackers[i].Check(); + } + } + } + + internal void CheckHierarchyDirtied() + { + if (ShadowAsSibling && hierachyTrackers != null) + { + for (var i = 0; i < hierachyTrackers.Length; i++) + { + hierachyTrackers[i].Check(); + } + } + } + + internal void ForgetSiblingIndexChanges() + { + for (var i = 0; i < hierachyTrackers.Length; i++) + { + hierachyTrackers[i].Forget(); + } + } + + protected override void OnTransformParentChanged() + { + base.OnTransformParentChanged(); + + if (!isActiveAndEnabled) return; + + SetHierachyDirty(); + this.NextFrames(checkHierarchyDirtiedDelegate); + } + + protected override void OnRectTransformDimensionsChange() + { + base.OnRectTransformDimensionsChange(); + + if (!isActiveAndEnabled) return; + + SetLayoutTextureDirty(); + } + + + protected override void OnDidApplyAnimationProperties() + { + if (!isActiveAndEnabled) return; + + SetLayoutTextureDirty(); + } + + public void ModifyMesh(Mesh mesh) + { + if (!isActiveAndEnabled) return; + + if (SpriteMesh) Utility.SafeDestroy(SpriteMesh); + SpriteMesh = Instantiate(mesh); + + SetLayoutTextureDirty(); + } + + public void ModifyMesh(VertexHelper verts) + { + if (!isActiveAndEnabled) return; + + // For when pressing play while in prefab mode + if (!SpriteMesh) SpriteMesh = new Mesh(); + verts.FillMesh(SpriteMesh); + + SetLayoutTextureDirty(); + } + + void SetLayoutTextureDirty() + { + SetLayoutDirty(); + SetTextureDirty(); + } +} +} diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/TrueShadow.Invalidator.cs.meta b/Assets/Le Tai's Asset/TrueShadow/Scripts/TrueShadow.Invalidator.cs.meta new file mode 100644 index 0000000..e57e775 --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/TrueShadow.Invalidator.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 8ed7fd00d57e48cdb5a496fb99282d83 +timeCreated: 1594977538 \ No newline at end of file diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/TrueShadow.Plugins.cs b/Assets/Le Tai's Asset/TrueShadow/Scripts/TrueShadow.Plugins.cs new file mode 100644 index 0000000..078ccca --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/TrueShadow.Plugins.cs @@ -0,0 +1,109 @@ +using System.Collections.Generic; +using System.Linq; +using LeTai.TrueShadow.PluginInterfaces; +using UnityEngine; +using UnityEngine.UI; + +namespace LeTai.TrueShadow +{ +public partial class TrueShadow +{ + ITrueShadowCasterMaterialProvider casterMaterialProvider; + ITrueShadowCasterMaterialPropertiesModifier casterMaterialPropertiesModifier; + ITrueShadowCasterMeshModifier casterMeshModifier; + ITrueShadowCasterClearColorProvider casterClearColorProvider; + ITrueShadowRendererMaterialProvider rendererMaterialProvider; + ITrueShadowRendererMaterialModifier rendererMaterialModifier; + ITrueShadowRendererMeshModifier rendererMeshModifier; + + public bool UsingRendererMaterialProvider => rendererMaterialProvider != null; + + void InitializePlugins() + { + casterMaterialProvider = GetComponent(); + casterMaterialPropertiesModifier = GetComponent(); + casterMeshModifier = GetComponent(); + casterClearColorProvider = GetComponent(); + if (casterClearColorProvider != null) + ColorBleedMode = ColorBleedMode.Plugin; + + rendererMaterialProvider = GetComponent(); + rendererMaterialModifier = GetComponent(); + rendererMeshModifier = GetComponent(); + } + + public virtual Material GetShadowCastingMaterial() + { + return casterMaterialProvider != null + ? casterMaterialProvider.GetTrueShadowCasterMaterial() + : Graphic.material; + } + + public virtual void ModifyShadowCastingMaterialProperties(MaterialPropertyBlock propertyBlock) + { + casterMaterialPropertiesModifier?.ModifyTrueShadowCasterMaterialProperties(propertyBlock); + } + + public virtual void ModifyShadowCastingMesh(Mesh mesh) + { + casterMeshModifier?.ModifyTrueShadowCasterMesh(mesh); + + // Caster can be semi-transparent, but cutout requires mostly opaque stencil. + // Setting alpha to 1 in fragment can't work because of antialiasing. + MakeOpaque(mesh); + } + + readonly List meshColors = new List(4); + List meshColorsOpaque = new List(4); + + void MakeOpaque(Mesh mesh) + { + if (shadowAsSibling) + return; + + mesh.GetColors(meshColors); + var meshColorCount = meshColors.Count; + + if (meshColorCount < 1) return; + + if (meshColorsOpaque.Count == meshColorCount) + { + // Assuming vertex colors are identical + // TODO: This is the case for builtin graphics, but userscript may invalidate that. + if (meshColors[0].a == meshColorsOpaque[0].a) + return; + } + else + { + // TODO: This assumed vertex count change infrequently. Is not the case with Text + meshColorsOpaque.Clear(); + meshColorsOpaque.AddRange(Enumerable.Repeat(new Color32(0, 0, 0, 0), meshColorCount)); + } + + for (var i = 0; i < meshColorCount; i++) + { + var c = meshColors[i]; + c.a = 255; + + meshColorsOpaque[i] = c; + } + + mesh.SetColors(meshColorsOpaque); + } + + public virtual Material GetShadowRenderingNormalMaterial() + { + return rendererMaterialProvider?.GetTrueShadowRendererMaterial(); + } + + public virtual void ModifyShadowRendererMaterial(Material baseMaterial) + { + rendererMaterialModifier?.ModifyTrueShadowRendererMaterial(baseMaterial); + } + + public virtual void ModifyShadowRendererMesh(VertexHelper vertexHelper) + { + rendererMeshModifier?.ModifyTrueShadowRenderMesh(vertexHelper); + } +} +} diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/TrueShadow.Plugins.cs.meta b/Assets/Le Tai's Asset/TrueShadow/Scripts/TrueShadow.Plugins.cs.meta new file mode 100644 index 0000000..12fabe9 --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/TrueShadow.Plugins.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: c652c1f825c14084a6d24c61de8f7772 +timeCreated: 1597650075 \ No newline at end of file diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/TrueShadow.cs b/Assets/Le Tai's Asset/TrueShadow/Scripts/TrueShadow.cs new file mode 100644 index 0000000..6e63dd3 --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/TrueShadow.cs @@ -0,0 +1,565 @@ +using System; +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.EventSystems; +using UnityEngine.Serialization; +using UnityEngine.UI; + +namespace LeTai.TrueShadow +{ +[RequireComponent(typeof(Graphic))] +// Doesn't seem to cause problem any more. Hmm +// [DisallowMultipleComponent] +[HelpURL("https://leloctai.com/trueshadow/docs/articles/customize.html")] +[ExecuteAlways] +public partial class TrueShadow : UIBehaviour, IMeshModifier, ICanvasElement +{ + static readonly Color DEFAULT_COLOR = new Color(0, 0, 0, .3f); + + [Tooltip("Size of the shadow")] + [SerializeField] float size = 32; + + [Tooltip("Spread of the shadow")] + [SpreadSlider] + [SerializeField] float spread = 0; + + [Tooltip("Direction to offset the shadow toward")] + [Knob] + [SerializeField] float offsetAngle = 90; + + [Tooltip("How far to offset the shadow")] + [SerializeField] float offsetDistance = 8; + + [SerializeField] Vector2 offset = Vector2.zero; + + [Tooltip("Tint the shadow")] + [SerializeField] Color color = DEFAULT_COLOR; + + [Tooltip("Inset shadow")] + [InsetToggle] + [SerializeField] bool inset = false; + + [Tooltip("Blend mode of the shadow")] + [SerializeField] BlendMode blendMode; + + [FormerlySerializedAs("multiplyCasterAlpha")] + [Tooltip("Allow shadow to cross-fade with caster")] + [SerializeField] bool useCasterAlpha = true; + + [Tooltip("Ignore the shadow caster's color, so you can choose specific color for your shadow")] + [SerializeField] bool ignoreCasterColor = false; + + [Tooltip( + "How to obtain the color of the area outside of the source image. Automatically set based on Blend Mode. You should only change this setting if you are using some very custom UI that require it")] + [SerializeField] ColorBleedMode colorBleedMode; + + [Tooltip("Position the shadow GameObject as previous sibling of the UI element")] + [SerializeField] bool shadowAsSibling; + + [Tooltip("Cut the source image from the shadow to avoid shadow showing behind semi-transparent UI")] + [SerializeField] bool cutout; + +#pragma warning disable 0649 + [Tooltip( + "Bake the shadow to a sprite to reduce CPU and GPU usage at runtime, at the cost of storage, memory and flexibility")] + [SerializeField] bool baked; +#pragma warning restore 0649 + + [SerializeField] bool modifiedFromInspector = false; + + public float Size + { + get => size; + set + { + var newSize = Mathf.Max(0, value); + if (modifiedFromInspector || !Mathf.Approximately(size, newSize)) + { + modifiedFromInspector = false; + + SetLayoutDirty(); + SetTextureDirty(); + } + + size = newSize; + if (Inset && OffsetDistance > Size) + { + OffsetDistance = Size; + } + } + } + + public float Spread + { + get => spread; + set + { + var newSpread = Mathf.Clamp01(value); + if (modifiedFromInspector || !Mathf.Approximately(spread, newSpread)) + { + modifiedFromInspector = false; + + SetLayoutDirty(); + SetTextureDirty(); + } + + spread = newSpread; + } + } + + public float OffsetAngle + { + get => offsetAngle; + set + { + var newValue = (value + 360f) % 360f; + if (modifiedFromInspector || !Mathf.Approximately(offsetAngle, newValue)) + { + modifiedFromInspector = false; + + SetLayoutDirty(); + if (Cutout) + SetTextureDirty(); + } + + offsetAngle = newValue; + offset = Math.AngleDistanceVector(offsetAngle, offset.magnitude, Vector2.right); + } + } + + public float OffsetDistance + { + get => offsetDistance; + set + { + // Limit offset distance for now. + // In order to properly render larger offset, imprint have to be rendered twice. + // TODO: Implement if no one complain about perf + var newValue = value; + if (Inset) + newValue = Mathf.Clamp(newValue, 0, Size); + else + newValue = Mathf.Max(0, newValue); + if (modifiedFromInspector || !Mathf.Approximately(offsetDistance, newValue)) + { + modifiedFromInspector = false; + + SetLayoutDirty(); + if (Cutout) + SetTextureDirty(); + } + + offsetDistance = newValue; + offset = offset.sqrMagnitude < 1e-6f + ? Math.AngleDistanceVector(offsetAngle, offsetDistance, Vector2.right) + : offset.normalized * offsetDistance; + } + } + + public Color Color + { + get => color; + set + { + if (modifiedFromInspector || value != color) + { + modifiedFromInspector = false; + + SetLayoutDirty(); + } + + color = value; + } + } + + /// + /// Allow shadow to cross-fade with caster + /// + public bool UseCasterAlpha + { + get => useCasterAlpha; + set + { + if (modifiedFromInspector || value != useCasterAlpha) + { + modifiedFromInspector = false; + + SetLayoutDirty(); + } + + useCasterAlpha = value; + } + } + + /// + /// Ignore the shadow caster's color, so you can choose specific color for your shadow. + /// When false, is multiplied with caster's color. + /// + public bool IgnoreCasterColor + { + get => ignoreCasterColor; + set + { + if (modifiedFromInspector || value != ignoreCasterColor) + { + modifiedFromInspector = false; + + SetTextureDirty(); + } + + ignoreCasterColor = value; + } + } + + public bool Inset + { + get => inset; + set + { + if (modifiedFromInspector || value != inset) + { + modifiedFromInspector = false; + + SetTextureDirty(); + } + + inset = value; + + if (Inset && OffsetDistance > Size) + { + OffsetDistance = Size; + } + } + } + + public BlendMode BlendMode + { + get => blendMode; + set + { + // Work around for Unity bug causing references loss + if (!Graphic || !CanvasRenderer) + return; + + blendMode = value; + shadowRenderer.UpdateMaterial(); + + switch (blendMode) + { + case BlendMode.Normal: + case BlendMode.Additive: + case BlendMode.Screen: + case BlendMode.Multiply: + ColorBleedMode = ColorBleedMode.Black; + break; + default: + ColorBleedMode = ColorBleedMode.Black; + break; + } + } + } + + /// + /// How to obtain the color of the area outside of the source image. Automatically set based on Blend Mode. You should only change this setting if you are using some very custom UI that require it. + /// + /// + /// + public ColorBleedMode ColorBleedMode + { + get => colorBleedMode; + set + { + if (modifiedFromInspector || colorBleedMode != value) + { + modifiedFromInspector = false; + + colorBleedMode = value; + SetTextureDirty(); + } + } + } + + /// + /// The area where the alpha channel = 0 can be either 0, or the color of the edge of the texture, depend on how the texture was authored. + /// Normally this is not visible, but when blurred, the alpha in these area will become greater than 0 + /// Depend on the blendmode, different color for this clear area may be desired. + /// + /// You can provide custom clear color by implementing , and set this to Plugin + /// + /// + public Color ClearColor + { + get + { + switch (colorBleedMode) + { + case ColorBleedMode.ImageColor: + return Graphic.color.WithA(0); + case ColorBleedMode.ShadowColor: + return Color.WithA(0); + case ColorBleedMode.Black: + return Color.clear; + case ColorBleedMode.White: + return new Color(1, 1, 1, 0); + case ColorBleedMode.Plugin: + return casterClearColorProvider?.GetTrueShadowCasterClearColor() ?? Color.clear; + default: + throw new ArgumentOutOfRangeException(); + } + } + } + + /// + /// Can't be implemented due to Unity's bug 1280465. Do not use! + /// + [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public bool ShadowAsSibling + { + get => shadowAsSibling; + set + { + shadowAsSibling = value; + ShadowRenderer.ClearMaskMaterialCache(); + if (shadowAsSibling) + { + ShadowSorter.Instance.Register(this); + } + else + { + ShadowSorter.Instance.UnRegister(this); + if (shadowRenderer) // defensive. undo & prefab make state weird sometime + { + var rendererTransform = shadowRenderer.transform; + rendererTransform.SetParent(transform, true); + rendererTransform.SetSiblingIndex(0); + } + } + } + } + + /// + /// Always true due to . Do not use! + /// + [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public bool Cutout + { + get => !shadowAsSibling || cutout; + set => cutout = value; + } + + [SerializeField] List bakedShadows; + + public Vector2 Offset => offset; + + internal ShadowRenderer shadowRenderer; + + internal Mesh SpriteMesh { get; set; } + internal Graphic Graphic { get; set; } + internal CanvasRenderer CanvasRenderer { get; set; } + internal RectTransform RectTransform { get; private set; } + + internal Texture Content + { + get + { + switch (Graphic) + { + case Image image: + var sprite = image.overrideSprite; + return sprite ? sprite.texture : null; + case RawImage rawImage: return rawImage.texture; + case Text text: return text.mainTexture; + default: return null; + } + } + } + + internal int TextureRevision { get; private set; } + +#if LETAI_TRUESHADOW_DEBUG + public bool alwaysRender; +#endif + + ShadowContainer shadowContainer; + + internal ShadowContainer ShadowContainer + { + get => shadowContainer; + private set => shadowContainer = value; + } + + bool textureDirty; + bool layoutDirty; + internal bool hierachyDirty; + + protected override void Awake() + { + if (ShadowAsSibling) + ShadowSorter.Instance.Register(this); + } + + protected override void OnEnable() + { + base.OnEnable(); + + RectTransform = GetComponent(); + Graphic = GetComponent(); + CanvasRenderer = GetComponent(); + if (!SpriteMesh) SpriteMesh = new Mesh(); + + InitializePlugins(); + + if (bakedShadows == null) + bakedShadows = new List(4); + + InitInvalidator(); + + ShadowRenderer.Initialize(this, ref shadowRenderer); + + Canvas.willRenderCanvases += OnWillRenderCanvas; + + if (Graphic) + Graphic.SetVerticesDirty(); + +#if UNITY_EDITOR + UnityEditor.Undo.undoRedoPerformed += ApplySerializedData; +#endif + +#if UNITY_EDITOR + if (!UnityEditor.EditorApplication.isPlayingOrWillChangePlaymode) + UnityEditor.EditorApplication.QueuePlayerLoopUpdate(); +#endif + } + + public void ApplySerializedData() + { + // Changes from prefab apply does not seem to call certain setters. Call manually + Size = size; + Spread = spread; + OffsetAngle = offsetAngle; + OffsetDistance = offsetDistance; + BlendMode = blendMode; + ShadowAsSibling = shadowAsSibling; + + SetHierachyDirty(); + SetLayoutDirty(); + SetTextureDirty(); + + if (shadowRenderer) shadowRenderer.SetMaterialDirty(); + } + + protected override void OnDisable() + { + Canvas.willRenderCanvases -= OnWillRenderCanvas; + TerminateInvalidator(); + + if (shadowRenderer) shadowRenderer.gameObject.SetActive(false); + +#if UNITY_EDITOR + UnityEditor.Undo.undoRedoPerformed -= ApplySerializedData; +#endif + } + + protected override void OnDestroy() + { + ShadowSorter.Instance.UnRegister(this); + if (shadowRenderer) shadowRenderer.Dispose(); + + ShadowFactory.Instance.ReleaseContainer(shadowContainer); + } + + bool ShouldPerformWorks() + { + bool areCanvasRenderersCulled = CanvasRenderer && CanvasRenderer.cull && + shadowRenderer.CanvasRenderer && shadowRenderer.CanvasRenderer.cull; + return isActiveAndEnabled && !areCanvasRenderersCulled; + } + + void LateUpdate() + { + if (!ShouldPerformWorks()) + return; + + CheckTransformDirtied(); + } + + public void Rebuild(CanvasUpdate executing) + { + // Debug.Assert(true, "This should not be called in child mode"); + if (!ShouldPerformWorks()) return; + + if (executing == CanvasUpdate.PostLayout) + { + if (layoutDirty) + { + shadowRenderer.ReLayout(); + layoutDirty = false; + } + } + } + + void OnWillRenderCanvas() + { + if (!isActiveAndEnabled) return; + +#if LETAI_TRUESHADOW_DEBUG + if (alwaysRender) textureDirty = true; +#endif + + if (!ShouldPerformWorks()) return; + + if (textureDirty && Graphic && Graphic.canvas) + { + ShadowFactory.Instance.Get(new ShadowSettingSnapshot(this), ref shadowContainer); + shadowRenderer.SetTexture(shadowContainer?.Texture); + + textureDirty = false; + } + + if (!shadowAsSibling) + { + if (shadowRenderer.transform.parent != transform) + shadowRenderer.transform.SetParent(RectTransform, true); + + if (shadowRenderer.transform.GetSiblingIndex() != 0) + shadowRenderer.transform.SetSiblingIndex(0); + + UnSetHierachyDirty(); + + if (layoutDirty) + { + shadowRenderer.ReLayout(); + layoutDirty = false; + } + } + } + + public void LayoutComplete() { } + + public void GraphicUpdateComplete() { } + + public void SetTextureDirty() + { + textureDirty = true; + unchecked + { + TextureRevision++; + } + } + + public void SetLayoutDirty() + { + layoutDirty = true; + } + + public void SetHierachyDirty() + { + hierachyDirty = true; + } + + internal void UnSetHierachyDirty() + { + hierachyDirty = false; + } +} +} diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/TrueShadow.cs.meta b/Assets/Le Tai's Asset/TrueShadow/Scripts/TrueShadow.cs.meta new file mode 100644 index 0000000..2057b64 --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/TrueShadow.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 52c162dc854d2f24fa639ba0623de5ef +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: 098c7906709c37c4bba842c34581765c, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Utilities.meta b/Assets/Le Tai's Asset/TrueShadow/Scripts/Utilities.meta new file mode 100644 index 0000000..ea81901 --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/Utilities.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: b558dc9ac9dc0944fab510f862e9f264 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Utilities/ExtensionMethods.cs b/Assets/Le Tai's Asset/TrueShadow/Scripts/Utilities/ExtensionMethods.cs new file mode 100644 index 0000000..e6cb7ad --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/Utilities/ExtensionMethods.cs @@ -0,0 +1,134 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.Rendering; + +namespace LeTai +{ +public static class ExtensionMethods +{ + public static Vector4 ToMinMaxVector(this Rect self) + { + return new Vector4( + self.xMin, + self.yMin, + self.xMax, + self.yMax + ); + } + + static Mesh fullscreenTriangle; + + /// + /// A fullscreen triangle mesh. + /// + static Mesh FullscreenTriangle + { + get + { + if (fullscreenTriangle != null) + return fullscreenTriangle; + + fullscreenTriangle = new Mesh {name = "Fullscreen Triangle"}; + fullscreenTriangle.SetVertices( + new List { + new Vector3(-1f, -1f, 0f), + new Vector3(-1f, 3f, 0f), + new Vector3(3f, -1f, 0f) + } + ); + fullscreenTriangle.SetIndices(new[] {0, 1, 2}, MeshTopology.Triangles, 0, false); + fullscreenTriangle.UploadMeshData(false); + + return fullscreenTriangle; + } + } + + public static void BlitFullscreenTriangle(this CommandBuffer cmd, + RenderTargetIdentifier source, + RenderTargetIdentifier destination, + Material material, + int pass = 0) + { + cmd.SetGlobalTexture("_MainTex", source); + +#if UNITY_2018_2_OR_NEWER + cmd.SetRenderTarget(destination, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store); +#else + cmd.SetRenderTarget(destination); +#endif + + cmd.DrawMesh(FullscreenTriangle, Matrix4x4.identity, material, 0, pass); + } + + internal static bool Approximately(this Rect self, Rect other) + { + return QuickApproximate(self.x, other.x) + && QuickApproximate(self.y, other.y) + && QuickApproximate(self.width, other.width) + && QuickApproximate(self.height, other.height); + } + + //A simpler Mathf.Approximately for our purpose + private static bool QuickApproximate(float a, float b) + { + return Mathf.Abs(b - a) < 1.175494E-38f; + } + + public static Vector3 WithZ(this Vector2 self, float z) + { + return new Vector3(self.x, self.y, z); + } + + public static Color WithA(this Color self, float a) + { + return new Color(self.r, self.g, self.b, a); + } + + public static void NextFrames(this MonoBehaviour behaviour, Action action, int nFrames = 1) + { + behaviour.StartCoroutine(NextFrame(action, nFrames)); + } + + static IEnumerator NextFrame(Action action, int nFrames) + { + for (var i = 0; i < nFrames; i++) + yield return null; + + action(); + } + + public static void SetKeyword(this Material material, string keyword, bool enabled) + { + if (enabled) + material.EnableKeyword(keyword); + else + material.DisableKeyword(keyword); + } + + public static Vector2 Frac(this Vector2 vec) + { + return new Vector2( + vec.x - Mathf.Floor(vec.x), + vec.y - Mathf.Floor(vec.y) + ); + } + + public static Vector2 LocalToScreenPoint(this RectTransform rt, + Vector3 localPoint, + Camera referenceCamera = null) + { + return RectTransformUtility.WorldToScreenPoint(referenceCamera, rt.TransformPoint(localPoint)); + } + + public static Vector2 ScreenToCanvasSize(this RectTransform rt, + Vector2 size, + Camera referenceCamera = null) + { + RectTransformUtility.ScreenPointToLocalPointInRectangle(rt, Vector2.zero, referenceCamera, out var start); + RectTransformUtility.ScreenPointToLocalPointInRectangle(rt, size, referenceCamera, out var end); + return end - start; + } +} +} diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Utilities/ExtensionMethods.cs.meta b/Assets/Le Tai's Asset/TrueShadow/Scripts/Utilities/ExtensionMethods.cs.meta new file mode 100644 index 0000000..fcdbb6a --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/Utilities/ExtensionMethods.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d7aeb90a879f07043a321b93dcd7310f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Utilities/HashCode.cs b/Assets/Le Tai's Asset/TrueShadow/Scripts/Utilities/HashCode.cs new file mode 100644 index 0000000..51d20f3 --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/Utilities/HashCode.cs @@ -0,0 +1,85 @@ +namespace LeTai +{ +// Extended from https://referencesource.microsoft.com/#mscorlib/system/tuple.cs,52 +public class HashUtils +{ + internal static int CombineHashCodes(int h1, int h2) + { + return ((h1 << 5) + h1) ^ h2; + } + + internal static int CombineHashCodes(int h1, int h2, int h3) + { + return CombineHashCodes(CombineHashCodes(h1, h2), h3); + } + + internal static int CombineHashCodes(int h1, int h2, int h3, int h4) + { + return CombineHashCodes(CombineHashCodes(h1, h2), CombineHashCodes(h3, h4)); + } + + internal static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5) + { + return CombineHashCodes(CombineHashCodes(h1, h2, h3, h4), h5); + } + + internal static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5, int h6) + { + return CombineHashCodes(CombineHashCodes(h1, h2, h3, h4), CombineHashCodes(h5, h6)); + } + + internal static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5, int h6, int h7) + { + return CombineHashCodes(CombineHashCodes(h1, h2, h3, h4), CombineHashCodes(h5, h6, h7)); + } + + internal static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5, int h6, int h7, int h8) + { + return CombineHashCodes(CombineHashCodes(h1, h2, h3, h4), CombineHashCodes(h5, h6, h7, h8)); + } + + internal static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5, int h6, int h7, int h8, int h9) + { + return CombineHashCodes(CombineHashCodes(h1, h2, h3, h4, h5, h6, h7, h8), h9); + } + + internal static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5, int h6, int h7, int h8, int h9, + int h10) + { + return CombineHashCodes(CombineHashCodes(h1, h2, h3, h4, h5, h6, h7, h8), CombineHashCodes(h9, h10)); + } + + internal static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5, int h6, int h7, int h8, int h9, + int h10, int h11) + { + return CombineHashCodes(CombineHashCodes(h1, h2, h3, h4, h5, h6, h7, h8), CombineHashCodes(h9, h10, h11)); + } + + internal static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5, int h6, int h7, int h8, int h9, + int h10, int h11, int h12) + { + return CombineHashCodes(CombineHashCodes(h1, h2, h3, h4, h5, h6, h7, h8), CombineHashCodes(h9, h10, h11, h12)); + } + + internal static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5, int h6, int h7, int h8, int h9, + int h10, int h11, int h12, int h13) + { + return CombineHashCodes(CombineHashCodes(h1, h2, h3, h4, h5, h6, h7, h8), + CombineHashCodes(h9, h10, h11, h12, h13)); + } + + internal static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5, int h6, int h7, int h8, int h9, + int h10, int h11, int h12, int h13, int h14) + { + return CombineHashCodes(CombineHashCodes(h1, h2, h3, h4, h5, h6, h7, h8), + CombineHashCodes(h9, h10, h11, h12, h13, h14)); + } + + internal static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5, int h6, int h7, int h8, int h9, + int h10, int h11, int h12, int h13, int h14, int h15) + { + return CombineHashCodes(CombineHashCodes(h1, h2, h3, h4, h5, h6, h7, h8), + CombineHashCodes(h9, h10, h11, h12, h13, h14, h15)); + } +} +} diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Utilities/HashCode.cs.meta b/Assets/Le Tai's Asset/TrueShadow/Scripts/Utilities/HashCode.cs.meta new file mode 100644 index 0000000..478b814 --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/Utilities/HashCode.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: aaf5875ff23b4286b3ab38783b8da255 +timeCreated: 1595834828 \ No newline at end of file diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Utilities/IndexedSet.cs b/Assets/Le Tai's Asset/TrueShadow/Scripts/Utilities/IndexedSet.cs new file mode 100644 index 0000000..f23ca6c --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/Utilities/IndexedSet.cs @@ -0,0 +1,138 @@ +using System; +using System.Collections; +using System.Collections.Generic; + +namespace LeTai.TrueShadow +{ +class IndexedSet : IList +{ + readonly List list = new List(); + readonly Dictionary dict = new Dictionary(); + + public void Add(T item) + { + dict.Add(item, list.Count); + list.Add(item); + } + + public bool AddUnique(T item) + { + if (dict.ContainsKey(item)) + return false; + + dict.Add(item, list.Count); + list.Add(item); + + return true; + } + + public bool Remove(T item) + { + if (!dict.TryGetValue(item, out var index)) + return false; + + RemoveAt(index); + return true; + } + + public void Remove(Predicate match) + { + int i = 0; + while (i < list.Count) + { + T item = list[i]; + if (match(item)) + Remove(item); + else + i++; + } + } + + public void Clear() + { + list.Clear(); + dict.Clear(); + } + + public bool Contains(T item) + { + return dict.ContainsKey(item); + } + + public void CopyTo(T[] array, int arrayIndex) + { + list.CopyTo(array, arrayIndex); + } + + public int Count => list.Count; + + public bool IsReadOnly => false; + + public int IndexOf(T item) + { + if (dict.TryGetValue(item, out var index)) + return index; + return -1; + } + + public void Insert(int index, T item) + { + //We could support this, but the semantics would be weird. Order is not guaranteed.. + throw new NotSupportedException( + "Random Insertion is semantically invalid, since this structure does not guarantee ordering."); + } + + public void RemoveAt(int index) + { + T item = list[index]; + dict.Remove(item); + if (index == list.Count - 1) + list.RemoveAt(index); + else + { + int replaceItemIndex = list.Count - 1; + T replaceItem = list[replaceItemIndex]; + list[index] = replaceItem; + dict[replaceItem] = index; + list.RemoveAt(replaceItemIndex); + } + } + + public T this[int index] + { + get => list[index]; + set + { + T item = list[index]; + dict.Remove(item); + list[index] = value; + dict.Add(item, index); + } + } + + //Sorts the internal list, this makes the exposed index accessor sorted as well. + //But note that any insertion or deletion, can unorder the collection again. + public void Sort(Comparison sortLayoutFunction) + { + //There might be better ways to sort and keep the dictionary index up to date. + list.Sort(sortLayoutFunction); + //Rebuild the dictionary index. + for (int i = 0; i < list.Count; ++i) + { + T item = list[i]; + dict[item] = i; + } + } + + + public IEnumerator GetEnumerator() + { + return list.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } +} +} diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Utilities/IndexedSet.cs.meta b/Assets/Le Tai's Asset/TrueShadow/Scripts/Utilities/IndexedSet.cs.meta new file mode 100644 index 0000000..3c9a507 --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/Utilities/IndexedSet.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 57517cc9ab1945abb176a2d7f6545890 +timeCreated: 1593673391 \ No newline at end of file diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Utilities/Math.cs b/Assets/Le Tai's Asset/TrueShadow/Scripts/Utilities/Math.cs new file mode 100644 index 0000000..720760d --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/Utilities/Math.cs @@ -0,0 +1,51 @@ +using System.Collections.Generic; +using UnityEngine; +using static UnityEngine.Mathf; + +namespace LeTai.TrueShadow +{ +public static class Math +{ + public static float Angle360(Vector2 from, Vector2 to) + { + float angle = Vector2.SignedAngle(from, to); + return angle < 0 ? 360 + angle : angle; + } + + public static Vector2 AngleDistanceVector(float angle, float distance, Vector2 zeroVector) + { + return Quaternion.Euler(0, 0, -angle) * zeroVector * distance; + } + + public static Vector2 Rotate(this Vector2 v, float angle) + { + var rad = angle * Deg2Rad; + var s = Sin(rad); + var c = Cos(rad); + return new Vector2(c * v.x - s * v.y, + s * v.x + c * v.y); + } +} + +public class FloatComparer : IEqualityComparer +{ + readonly float tolerant; + readonly int digits; + + public FloatComparer(int digits = 4) + { + this.digits = digits; + tolerant = 1f / Pow(10, digits); + } + + public bool Equals(float x, float y) + { + return System.Math.Abs(x - y) < tolerant; + } + + public int GetHashCode(float obj) + { + return System.Math.Round(obj, digits).GetHashCode(); + } +} +} diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Utilities/Math.cs.meta b/Assets/Le Tai's Asset/TrueShadow/Scripts/Utilities/Math.cs.meta new file mode 100644 index 0000000..6192962 --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/Utilities/Math.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 61b5b7160b6742c4bb4d5883d08e64e6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Utilities/PropertyDrawerAttributes.cs b/Assets/Le Tai's Asset/TrueShadow/Scripts/Utilities/PropertyDrawerAttributes.cs new file mode 100644 index 0000000..75c91bf --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/Utilities/PropertyDrawerAttributes.cs @@ -0,0 +1,10 @@ +using UnityEngine; + +namespace LeTai.TrueShadow +{ +public class KnobAttribute : PropertyAttribute { } + +public class ToggleButtonsAttribute : PropertyAttribute { } + +public class InsetToggleAttribute : ToggleButtonsAttribute { } +} diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Utilities/PropertyDrawerAttributes.cs.meta b/Assets/Le Tai's Asset/TrueShadow/Scripts/Utilities/PropertyDrawerAttributes.cs.meta new file mode 100644 index 0000000..3596a2c --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/Utilities/PropertyDrawerAttributes.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 60900a16da6d4f44b89f9272039ea4f1 +timeCreated: 1594637349 \ No newline at end of file diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Utilities/ShaderID.cs b/Assets/Le Tai's Asset/TrueShadow/Scripts/Utilities/ShaderID.cs new file mode 100644 index 0000000..56422e6 --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/Utilities/ShaderID.cs @@ -0,0 +1,18 @@ +using UnityEngine; + +namespace LeTai +{ +public static class ShaderId +{ + public static readonly int MAIN_TEX = Shader.PropertyToID("_MainTex"); + public static readonly int SHADOW_TEX = Shader.PropertyToID("_ShadowTex"); + public static readonly int CLIP_RECT = Shader.PropertyToID("_ClipRect"); + public static readonly int COLOR_MASK = Shader.PropertyToID("_ColorMask"); + public static readonly int STENCIL_OP = Shader.PropertyToID("_StencilOp"); + public static readonly int STENCIL_ID = Shader.PropertyToID("_Stencil"); + public static readonly int STENCIL_READ_MASK = Shader.PropertyToID("_StencilReadMask"); + public static readonly int OFFSET = Shader.PropertyToID("_Offset"); + public static readonly int OVERFLOW_ALPHA = Shader.PropertyToID("_OverflowAlpha"); + public static readonly int ALPHA_MULTIPLIER = Shader.PropertyToID("_AlphaMultiplier"); +} +} diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Utilities/ShaderID.cs.meta b/Assets/Le Tai's Asset/TrueShadow/Scripts/Utilities/ShaderID.cs.meta new file mode 100644 index 0000000..c366271 --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/Utilities/ShaderID.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: b73a242c1b944cac9af5b62106473319 +timeCreated: 1592809972 \ No newline at end of file diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Utilities/SpreadSliderAttribute.cs b/Assets/Le Tai's Asset/TrueShadow/Scripts/Utilities/SpreadSliderAttribute.cs new file mode 100644 index 0000000..d80cba6 --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/Utilities/SpreadSliderAttribute.cs @@ -0,0 +1,9 @@ +using UnityEngine; + +namespace LeTai.TrueShadow +{ +public class SpreadSliderAttribute : PropertyAttribute +{ + public SpreadSliderAttribute() { } +} +} diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Utilities/SpreadSliderAttribute.cs.meta b/Assets/Le Tai's Asset/TrueShadow/Scripts/Utilities/SpreadSliderAttribute.cs.meta new file mode 100644 index 0000000..153a4df --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/Utilities/SpreadSliderAttribute.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 97cb59689d014af2a249b20864599719 +timeCreated: 1615190395 \ No newline at end of file diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Utilities/Utility.cs b/Assets/Le Tai's Asset/TrueShadow/Scripts/Utilities/Utility.cs new file mode 100644 index 0000000..75f197c --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/Utilities/Utility.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.Text; +using UnityEngine; +using Object = UnityEngine.Object; + + +namespace LeTai +{ +public static class Utility +{ + public static void LogList(IEnumerable list, Func getData) + { + StringBuilder sb = new StringBuilder(); + + int i = 0; + foreach (T el in list) + { + sb.Append(i + ": "); + sb.Append(getData(el).ToString()); + sb.Append("\n"); + i++; + } + + Debug.Log(sb.ToString()); + } + + public static int SimplePingPong(int t, int max) + { + if (t > max) + return 2 * max - t; + return t; + } + + public static void SafeDestroy(Object obj) + { + if (obj != null) + { + if (Application.isPlaying) + { + if (obj is GameObject go) + { + go.transform.parent = null; + } + + Object.Destroy(obj); + } + else Object.DestroyImmediate(obj); + } + } +} +} diff --git a/Assets/Le Tai's Asset/TrueShadow/Scripts/Utilities/Utility.cs.meta b/Assets/Le Tai's Asset/TrueShadow/Scripts/Utilities/Utility.cs.meta new file mode 100644 index 0000000..0dd2ac2 --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/Scripts/Utilities/Utility.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e8dc67630fb04cc4dbd94a8ccc8fe620 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Le Tai's Asset/TrueShadow/changelog.txt b/Assets/Le Tai's Asset/TrueShadow/changelog.txt new file mode 100644 index 0000000..aed0e95 --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/changelog.txt @@ -0,0 +1,78 @@ +v0.9.0rc: + This is the last release of the beta cycle. Some breaking changes was introduced, please check the included migration tool for more info. + - Major re-haul of the blending system. This produce better looking shadow, especially for textured shadow. + - Added Screen blend mode. It's similar to Additive, but softer on bright background. + - Many 3rd party assets are now compatible without any additional integration. If you're using any custom integration code, please remove them. + - Shadow now fit tighter in some edge case. + - Shadow resolution now scale properly with Canvas Scaler setting. + +v0.5.1: + - Fix compatibility with "Use 32-bit Display Buffer" option + +v0.5.0: + - Shadow spread + +v0.4.4: + - Minimize gap between shadows and caster. + - Fix canvas being dirtied when not needed. + +v0.4.3: + - Fix script not compiling in certain setup + - Update documentation + +v0.4.2: + - UI Text is now supported! + - Some minor fixes and optimizations + +v0.3.6: + - Clean up: remove some buggy features, fix typos, improve wording + - Make shadow more visible by default + - Minor optimizations. + +v0.3.5: + - Ground work on supporting additional types of Graphics (Text, SVG, 3rd parties) + - Fix editor problem on non-English OS + +v0.3.3: + - Fix world space Z rotation + +v0.3.2: + - Fix inset shadow offset artifact + +v0.3.1: + - World Space Canvas is now supported. Rotated UI also work more correctly + - Allow enabling/disabling caster Graphic alpha affecting shadow + - Fix shadows being incorrectly generated when the caster Graphic is semi transparent + - Fix shadows being jaggy in certain case, including the demo scene + - Fix interaction between 0-size shadow and sprite mip-map + - Hide scene view gizmo + - Various minor fixes and improvements + +v0.2.0: + - New: Inset shadows! + - Neumorphism! + - Helper script to make shadow inset when pressed + - New: Option to ignore shadow caster's color. This mean shadow can now be brighter than the shadow caster, for example, to emulate shiny edge + - New: Multiple shadows support! Just add more True Shadow component to a single UI + + Checkout the Neumorphism demo scene to see the new features in action! + + Also: + - Added Component icon + - Fix shadows being too small + - Many other bug fixes and performance improvements + +v0.1.3: + - Fix shadow size calculation. As a result, shadow should no longer be clipped. But for real this time + - Fix 1 pixel gap between shadow and shadow caster that show up in certain cases + - Use border mip map for demo sprites to avoid artifact when shadow size is 0 + - Fix nullref error when you delete True Shadow component + +v0.1.2: + - Fix shadow size calculation. As a result, shadow should no longer be clipped + - Documentation button on True Shadow component now lead to the correct site instead of Unity's generic scripting page + - Some minor fixes and performance optimization + +v0.1.1: + - Fix Shadow not show up immediately + - Fix Additive Blend mode diff --git a/Assets/Le Tai's Asset/TrueShadow/changelog.txt.meta b/Assets/Le Tai's Asset/TrueShadow/changelog.txt.meta new file mode 100644 index 0000000..b648369 --- /dev/null +++ b/Assets/Le Tai's Asset/TrueShadow/changelog.txt.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 550f012132e9a1e49a6d198d463f7b61 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/ProjectSettings/ProjectSettings.asset b/ProjectSettings/ProjectSettings.asset index 5cd5606..1c6747a 100644 --- a/ProjectSettings/ProjectSettings.asset +++ b/ProjectSettings/ProjectSettings.asset @@ -601,7 +601,7 @@ PlayerSettings: webGLThreadsSupport: 0 webGLDecompressionFallback: 0 scriptingDefineSymbols: - 1: UNITY_POST_PROCESSING_STACK_V2;BOLT_CLOUD;BOLT_1_3_OR_NEWER + 1: UNITY_POST_PROCESSING_STACK_V2;BOLT_CLOUD;BOLT_1_3_OR_NEWER;LETAI_TRUESHADOW 4: UNITY_POST_PROCESSING_STACK_V2 7: UNITY_POST_PROCESSING_STACK_V2 13: UNITY_POST_PROCESSING_STACK_V2