From 38650cc53699f0db404c67d916d8820ded8c8d5a Mon Sep 17 00:00:00 2001 From: "Simon (darkside) Jackson" Date: Tue, 15 Dec 2015 22:43:35 +0000 Subject: [PATCH] Update SoftMaskAlpha with new "fix" Patched UISelectableExtension from issue #47 Added new UI Polygon control --HG-- branch : develop_5.2 --- Scripts/Effects/SoftMaskScript.cs | 5 + Scripts/Primitives/UIPolygon.cs | 277 ++++++++++++++------------- Scripts/Primitives/UIPolygon.cs.meta | 12 ++ Scripts/UISelectableExtension.cs | 119 ++++++------ Shaders/SoftMaskShader.shader | 9 +- Shaders/SoftMaskShaderText.shader | 7 +- 6 files changed, 234 insertions(+), 195 deletions(-) create mode 100644 Scripts/Primitives/UIPolygon.cs.meta diff --git a/Scripts/Effects/SoftMaskScript.cs b/Scripts/Effects/SoftMaskScript.cs index 4eae262..e8cb169 100644 --- a/Scripts/Effects/SoftMaskScript.cs +++ b/Scripts/Effects/SoftMaskScript.cs @@ -30,6 +30,9 @@ namespace UnityEngine.UI.Extensions [Tooltip("Flip the masks alpha value")] public bool FlipAlphaMask = false; + [Tooltip("If Mask Scals Rect is given, and this value is true, the area around the mask will not be clipped")] + public bool DontClipMaskScalingRect = false; + Vector3[] worldCorners; Vector2 AlphaUV; @@ -173,6 +176,8 @@ namespace UnityEngine.UI.Extensions mat.SetTexture("_AlphaMask", AlphaMask); mat.SetInt("_FlipAlphaMask", FlipAlphaMask ? 1 : 0); + mat.SetInt("_NoOuterClip", DontClipMaskScalingRect && maskScalingRect != null ? 1 : 0); + if (!isText) // No mod needed for Text mat.SetVector("_AlphaUV", AlphaUV); diff --git a/Scripts/Primitives/UIPolygon.cs b/Scripts/Primitives/UIPolygon.cs index f5feb2a..30156cb 100644 --- a/Scripts/Primitives/UIPolygon.cs +++ b/Scripts/Primitives/UIPolygon.cs @@ -1,136 +1,143 @@ -/// Credit CiaccoDavide -/// Sourced from - http://ciaccodavi.de/unity/UIPolygon - -using System.Collections.Generic; - -namespace UnityEngine.UI.Extensions -{ - [AddComponentMenu("UI/Extensions/Primitives/UI Polygon")] - public class UIPolygon : MaskableGraphic - { - [SerializeField] - Texture m_Texture; - public bool fill = true; - public float thickness = 5; - [Range(3, 360)] - public int sides = 3; - [Range(0, 360)] - public float rotation = 0; - [Range(0, 1)] - public float[] VerticesDistances = new float[3]; - private float size = 0; - - public override Texture mainTexture - { - get - { - return m_Texture == null ? s_WhiteTexture : m_Texture; - } - } - public Texture texture - { - get - { - return m_Texture; - } - set - { - if (m_Texture == value) return; - m_Texture = value; - SetVerticesDirty(); - SetMaterialDirty(); - } - } - public void DrawPolygon(int _sides) - { - sides = _sides; - VerticesDistances = new float[_sides + 1]; - for (int i = 0; i < _sides; i++) VerticesDistances[i] = 1; ; - rotation = 0; - } - public void DrawPolygon(int _sides, float[] _VerticesDistances) - { - sides = _sides; - VerticesDistances = _VerticesDistances; - rotation = 0; - } - public void DrawPolygon(int _sides, float[] _VerticesDistances, float _rotation) - { - sides = _sides; - VerticesDistances = _VerticesDistances; - rotation = _rotation; - } - void Update() - { - size = rectTransform.rect.width; - if (rectTransform.rect.width > rectTransform.rect.height) - size = rectTransform.rect.height; - else - size = rectTransform.rect.width; - thickness = (float)Mathf.Clamp(thickness, 0, size / 2); - } - protected UIVertex[] SetVbo(Vector2[] vertices, Vector2[] uvs) - { - UIVertex[] vbo = new UIVertex[4]; - for (int i = 0; i < vertices.Length; i++) - { - var vert = UIVertex.simpleVert; - vert.color = color; - vert.position = vertices[i]; - vert.uv0 = uvs[i]; - vbo[i] = vert; - } - return vbo; - } - protected override void OnPopulateMesh(VertexHelper vh) - { - vh.Clear(); - Vector2 prevX = Vector2.zero; - Vector2 prevY = Vector2.zero; - Vector2 uv0 = new Vector2(0, 0); - Vector2 uv1 = new Vector2(0, 1); - Vector2 uv2 = new Vector2(1, 1); - Vector2 uv3 = new Vector2(1, 0); - Vector2 pos0; - Vector2 pos1; - Vector2 pos2; - Vector2 pos3; - float degrees = 360f / sides; - int vertices = sides + 1; - if (VerticesDistances.Length != vertices) - { - VerticesDistances = new float[vertices]; - for (int i = 0; i < vertices - 1; i++) VerticesDistances[i] = 1; - } - // last vertex is also the first! - VerticesDistances[vertices - 1] = VerticesDistances[0]; - for (int i = 0; i < vertices; i++) - { - float outer = -rectTransform.pivot.x * size * VerticesDistances[i]; - float inner = -rectTransform.pivot.x * size * VerticesDistances[i] + thickness; - float rad = Mathf.Deg2Rad * (i * degrees + rotation); - float c = Mathf.Cos(rad); - float s = Mathf.Sin(rad); - uv0 = new Vector2(0, 1); - uv1 = new Vector2(1, 1); - uv2 = new Vector2(1, 0); - uv3 = new Vector2(0, 0); - pos0 = prevX; - pos1 = new Vector2(outer * c, outer * s); - if (fill) - { - pos2 = Vector2.zero; - pos3 = Vector2.zero; - } - else - { - pos2 = new Vector2(inner * c, inner * s); - pos3 = prevY; - } - prevX = pos1; - prevY = pos2; - vh.AddUIVertexQuad(SetVbo(new[] { pos0, pos1, pos2, pos3 }, new[] { uv0, uv1, uv2, uv3 })); - } - } - } +/// Credit CiaccoDavide +/// Sourced from - http://ciaccodavi.de/unity/UIPolygon + +using System.Collections.Generic; + +namespace UnityEngine.UI.Extensions +{ + [AddComponentMenu("UI/Extensions/Primitives/UI Polygon")] + public class UIPolygon : MaskableGraphic + { + [SerializeField] + Texture m_Texture; + public bool fill = true; + public float thickness = 5; + [Range(3, 360)] + public int sides = 3; + [Range(0, 360)] + public float rotation = 0; + [Range(0, 1)] + public float[] VerticesDistances = new float[3]; + private float size = 0; + + public override Texture mainTexture + { + get + { + return m_Texture == null ? s_WhiteTexture : m_Texture; + } + } + public Texture texture + { + get + { + return m_Texture; + } + set + { + if (m_Texture == value) return; + m_Texture = value; + SetVerticesDirty(); + SetMaterialDirty(); + } + } + public void DrawPolygon(int _sides) + { + sides = _sides; + VerticesDistances = new float[_sides + 1]; + for (int i = 0; i < _sides; i++) VerticesDistances[i] = 1; ; + rotation = 0; + } + public void DrawPolygon(int _sides, float[] _VerticesDistances) + { + sides = _sides; + VerticesDistances = _VerticesDistances; + rotation = 0; + } + public void DrawPolygon(int _sides, float[] _VerticesDistances, float _rotation) + { + sides = _sides; + VerticesDistances = _VerticesDistances; + rotation = _rotation; + } + void Update() + { + size = rectTransform.rect.width; + if (rectTransform.rect.width > rectTransform.rect.height) + size = rectTransform.rect.height; + else + size = rectTransform.rect.width; + thickness = (float)Mathf.Clamp(thickness, 0, size / 2); + } + protected UIVertex[] SetVbo(Vector2[] vertices, Vector2[] uvs) + { + UIVertex[] vbo = new UIVertex[4]; + for (int i = 0; i < vertices.Length; i++) + { + var vert = UIVertex.simpleVert; + vert.color = color; + vert.position = vertices[i]; + vert.uv0 = uvs[i]; + vbo[i] = vert; + } + return vbo; + } + protected override void OnPopulateMesh(Mesh toFill) + { + toFill.Clear(); + var vbo = new VertexHelper(toFill); + + Vector2 prevX = Vector2.zero; + Vector2 prevY = Vector2.zero; + Vector2 uv0 = new Vector2(0, 0); + Vector2 uv1 = new Vector2(0, 1); + Vector2 uv2 = new Vector2(1, 1); + Vector2 uv3 = new Vector2(1, 0); + Vector2 pos0; + Vector2 pos1; + Vector2 pos2; + Vector2 pos3; + float degrees = 360f / sides; + int vertices = sides + 1; + if (VerticesDistances.Length != vertices) + { + VerticesDistances = new float[vertices]; + for (int i = 0; i < vertices - 1; i++) VerticesDistances[i] = 1; + } + // last vertex is also the first! + VerticesDistances[vertices - 1] = VerticesDistances[0]; + for (int i = 0; i < vertices; i++) + { + float outer = -rectTransform.pivot.x * size * VerticesDistances[i]; + float inner = -rectTransform.pivot.x * size * VerticesDistances[i] + thickness; + float rad = Mathf.Deg2Rad * (i * degrees + rotation); + float c = Mathf.Cos(rad); + float s = Mathf.Sin(rad); + uv0 = new Vector2(0, 1); + uv1 = new Vector2(1, 1); + uv2 = new Vector2(1, 0); + uv3 = new Vector2(0, 0); + pos0 = prevX; + pos1 = new Vector2(outer * c, outer * s); + if (fill) + { + pos2 = Vector2.zero; + pos3 = Vector2.zero; + } + else + { + pos2 = new Vector2(inner * c, inner * s); + pos3 = prevY; + } + prevX = pos1; + prevY = pos2; + vbo.AddUIVertexQuad(SetVbo(new[] { pos0, pos1, pos2, pos3 }, new[] { uv0, uv1, uv2, uv3 })); + } + + if (vbo.currentVertCount > 3) + { + vbo.FillMesh(toFill); + } + } + } } \ No newline at end of file diff --git a/Scripts/Primitives/UIPolygon.cs.meta b/Scripts/Primitives/UIPolygon.cs.meta new file mode 100644 index 0000000..0aecf98 --- /dev/null +++ b/Scripts/Primitives/UIPolygon.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: fcd1b8078a416f844b695454a4358409 +timeCreated: 1450200166 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/UISelectableExtension.cs b/Scripts/UISelectableExtension.cs index 0f73cf1..17733b8 100644 --- a/Scripts/UISelectableExtension.cs +++ b/Scripts/UISelectableExtension.cs @@ -2,6 +2,7 @@ /// Sourced from - http://forum.unity3d.com/threads/scripts-useful-4-6-scripts-collection.264161/page-2#post-1796783 /// Extended to include a HELD state that continually fires while the button is held down. /// Refactored so it can be added to any button and expose the events in the editor. +/// Unselect fix by @Sfyne using UnityEngine.Events; using UnityEngine.EventSystems; @@ -21,27 +22,27 @@ namespace UnityEngine.UI.Extensions #endregion #region Events - [Tooltip("Event that fires when a button is initially pressed down")] + [Tooltip("Event that fires when a button is initially pressed down")] public UIButtonEvent OnButtonPress; - [Tooltip("Event that fires when a button is released")] + [Tooltip("Event that fires when a button is released")] public UIButtonEvent OnButtonRelease; - [Tooltip("Event that continually fires while a button is held down")] + [Tooltip("Event that continually fires while a button is held down")] public UIButtonEvent OnButtonHeld; #endregion - - private bool _pressed; + + private bool _pressed; private PointerEventData _heldEventData; void IPointerDownHandler.OnPointerDown(PointerEventData eventData) { //Can't set the state as it's too locked down. - //DoStateTransition(SelectionState.Pressed, false); + //DoStateTransition(SelectionState.Pressed, false); if (OnButtonPress != null) { OnButtonPress.Invoke(eventData.button); } - _pressed = true; + _pressed = true; _heldEventData = eventData; } @@ -54,59 +55,65 @@ namespace UnityEngine.UI.Extensions { OnButtonRelease.Invoke(eventData.button); } - _pressed = false; + _pressed = false; _heldEventData = null; } - - void Update() - { - if (!_pressed) - return; - - if (OnButtonHeld != null) + + void Update() + { + if (!_pressed) + return; + + if (OnButtonHeld != null) { OnButtonHeld.Invoke(_heldEventData.button); } - } - - /// - /// Test method to verify a control has been clicked - /// - public void TestClicked() - { - #if DEBUG || UNITY_EDITOR - Debug.Log("Control Clicked"); - #endif - } - - /// - /// Test method to verify a controll is pressed - /// - public void TestPressed() - { - #if DEBUG || UNITY_EDITOR - Debug.Log("Control Pressed"); - #endif - } - - /// - /// est method to verify if a control is released - /// - public void TestReleased() - { - #if DEBUG || UNITY_EDITOR - Debug.Log("Control Released"); - #endif - } - - /// - /// est method to verify if a control is being held - /// - public void TestHold() - { - #if DEBUG || UNITY_EDITOR - Debug.Log("Control Held"); - #endif - } + } + + /// + /// Test method to verify a control has been clicked + /// + public void TestClicked() + { + #if DEBUG || UNITY_EDITOR + Debug.Log("Control Clicked"); + #endif + } + + /// + /// Test method to verify a controll is pressed + /// + public void TestPressed() + { + #if DEBUG || UNITY_EDITOR + Debug.Log("Control Pressed"); + #endif + } + + /// + /// est method to verify if a control is released + /// + public void TestReleased() + { + #if DEBUG || UNITY_EDITOR + Debug.Log("Control Released"); + #endif + } + + /// + /// est method to verify if a control is being held + /// + public void TestHold() + { + #if DEBUG || UNITY_EDITOR + Debug.Log("Control Held"); + #endif + } + + //Fixed UISelectableExtension inactive bug (if gameObject becomes inactive while button is held down it never goes back to _pressed = false) + void OnDisable () + { + _pressed = false; + } } } \ No newline at end of file diff --git a/Shaders/SoftMaskShader.shader b/Shaders/SoftMaskShader.shader index bf44fb0..333016f 100644 --- a/Shaders/SoftMaskShader.shader +++ b/Shaders/SoftMaskShader.shader @@ -21,6 +21,7 @@ [MaterialToggle] _HardBlend("HardBlend",Float) = 0 _FlipAlphaMask("Flip Alpha Mask",int) = 0 + _NoOuterClip("Outer Clip",int) = 0 } SubShader @@ -43,6 +44,8 @@ WriteMask[_StencilWriteMask] } + LOD 0 + Cull Off Lighting Off ZWrite Off @@ -120,13 +123,14 @@ float _CutOff; bool _HardBlend = false; + bool _NoOuterClip = false; fixed4 frag(v2f IN) : SV_Target { half4 color = (tex2D(_MainTex, IN.texcoord) + _TextureSampleAdd) * IN.color; // Do we want to clip the image to the Mask Rectangle? - if (IN.texcoord.x < _Min.x || IN.texcoord.x > _Max.x || IN.texcoord.y < _Min.y || IN.texcoord.y > _Max.y) // Yes we do + if (!_NoOuterClip && (IN.texcoord.x < _Min.x || IN.texcoord.x > _Max.x || IN.texcoord.y < _Min.y || IN.texcoord.y > _Max.y)) // Yes we do color.a = 0; else // It's in the mask rectangle, so apply the alpha of the mask provided. { @@ -143,7 +147,8 @@ if (_FlipAlphaMask == 1) a = 1 - a; - color.a = a; + if(!(IN.texcoord.x < _Min.x || IN.texcoord.x > _Max.x || IN.texcoord.y < _Min.y || IN.texcoord.y > _Max.y)) + color.a *= a; } if (_UseClipRect) diff --git a/Shaders/SoftMaskShaderText.shader b/Shaders/SoftMaskShaderText.shader index 9f7eb13..85d0fad 100644 --- a/Shaders/SoftMaskShaderText.shader +++ b/Shaders/SoftMaskShaderText.shader @@ -91,7 +91,7 @@ float _Value; int _LeftToRight; - bool _HardBlend = false; + int _HardBlend = false; int _FlipAlphaMask = 0; @@ -122,6 +122,7 @@ float2 _Mul; float _CutOff; + int _NoOuterClip; fixed4 frag(v2f IN) : SV_Target { @@ -134,6 +135,7 @@ else // It's in the mask rectangle, so apply the alpha of the mask provided. { float a = tex2D(_AlphaMask, (IN.worldPosition2.xy - _Max) / (_Max-_Min)).a; + if (a <= _CutOff) a = 0; else @@ -145,7 +147,8 @@ if (_FlipAlphaMask == 1) a = 1 - a; - color.a = a * color.a; + if(!(IN.worldPosition2.x <= _Min.x || IN.worldPosition2.x >= _Max.x || IN.worldPosition2.y <= _Min.y || IN.worldPosition2.y >= _Max.y)) + color *= a; } if (_UseClipRect)