ugui unity 取消选择_UGUI中几种不规则按钮的实现方式
前言
UGUI中的按鈕默認(rèn)是矩形的,若要實(shí)現(xiàn)非矩形按鈕該怎么做呢?比如這樣的按鈕:
本文將介紹兩種實(shí)現(xiàn)方式供大家選擇。
使用alphaHitTestMinimumThreshold
Image類的alphaHitTestMinimumThreshold是一個浮點(diǎn)值,Raycast檢測時只有圖片中高于該值的部分會拋出點(diǎn)擊事件。因此我們可以使用一張alpha通道的值高于該設(shè)置值的Sprite用于自定義按鈕的點(diǎn)擊相應(yīng)區(qū)域。
我們準(zhǔn)備一張點(diǎn)擊區(qū)域alpha高于某值,非點(diǎn)擊區(qū)域alpha低于某值的Sprite用于Button的Image組件的Sprite。然后給這個Button掛上如下腳本組件即可:
using UnityEngine; using UnityEngine.UI;public class AlphaButton : MonoBehaviour {public float alphaThreshold = 0.1f;void Start() {GetComponent<Image>().alphaHitTestMinimumThreshold = alphaThreshold;} }但這種方法有幾個問題:
如果可以接受這些缺點(diǎn),可以使用這個方法。
使用IsRaycastLocationValid
通過繼承Image并重寫IsRaycastLocationValid方法可以自定義按鈕的可點(diǎn)擊區(qū)域。
將如下代碼放置于項目中:
using UnityEngine; using UnityEngine.UI; #if UNITY_EDITOR using UnityEditor;#endif [RequireComponent(typeof(PolygonCollider2D))] public class NonRectangularButtonImage : Image {private PolygonCollider2D areaPolygon;protected NonRectangularButtonImage() {useLegacyMeshGeneration = true;}private PolygonCollider2D Polygon{get{if (areaPolygon != null)return areaPolygon;areaPolygon = GetComponent<PolygonCollider2D>();return areaPolygon;}}protected override void OnPopulateMesh(VertexHelper vh) {vh.Clear();}public override bool IsRaycastLocationValid(Vector2 screenPoint, Camera eventCamera) {return Polygon.OverlapPoint(eventCamera.ScreenToWorldPoint(screenPoint));}#if UNITY_EDITOR protected override void Reset() {base.Reset();transform.localPosition = Vector3.zero;var w = rectTransform.sizeDelta.x * 0.5f + 0.1f;var h = rectTransform.sizeDelta.y * 0.5f + 0.1f;Polygon.points = new[]{new Vector2(-w, -h),new Vector2(w, -h),new Vector2(w, h),new Vector2(-w, h)};} #endif } #if UNITY_EDITOR [CustomEditor(typeof(NonRectangularButtonImage), true)] public class CustomRaycastFilterInspector : Editor {public override void OnInspectorGUI() {} }public class NonRectAngularButtonImageHelper {[MenuItem("GameObject/UI/NonRectangularButtonImage")]public static void CreateNonRectAngularButtonImage() {var goRoot = Selection.activeGameObject;if (goRoot == null)return;var button = goRoot.GetComponent<Button>();if (button == null){Debug.Log("Selecting Object is not a button!");return;}// 關(guān)閉原來button的射線檢測var graphics = goRoot.GetComponentsInChildren<Graphic>();foreach (var graphic in graphics){graphic.raycastTarget = false;}var polygon = new GameObject("NonRectangularButtonImage");polygon.AddComponent<PolygonCollider2D>();polygon.AddComponent<NonRectangularButtonImage>();polygon.transform.SetParent(goRoot.transform, false);polygon.transform.SetAsLastSibling();} }#endif這段代碼大部分參考自雨松大神的這篇文章:
UGUI研究院之不規(guī)則按鈕的響應(yīng)區(qū)域(十四)
還額外寫了一個自動添加組件和設(shè)置raycastTarget屬性的菜單項。創(chuàng)建完一個普通的按鈕后,右鍵執(zhí)行命令:
這將自動創(chuàng)建一個名為“NonRectangularButtonImage”的子節(jié)點(diǎn),并添加一個同名的腳本組件和一個PolygonCollider2D組件。編輯PolygonCollider2D組件即可設(shè)置按鈕的點(diǎn)擊區(qū)域,調(diào)整起來也十分方便,既簡單又節(jié)省內(nèi)存。
我的Github中這兩種方式都有實(shí)現(xiàn),供大家參考:
共三組按鈕,點(diǎn)擊后可以在Console窗口中看到響應(yīng)Log。
第一組是沒有任何處理的普通按鈕,由于在Hierarchy中RightButton在下,點(diǎn)擊Left的右下角還是右邊按鈕響應(yīng),用于對照。
第二組使用了設(shè)置alphaHitTestMinimumThreshold的方式。
第三組使用了重寫IsRaycastLocationValid的方式,并故意調(diào)整了Button在Hierarchy中的順序。
如果可以,也希望大家點(diǎn)個Star。
專欄文章繼續(xù)更新,歡迎關(guān)注微信公眾號:Unity與圖形學(xué)
參考
使用alphaHitTestMinimumThreshold的方式
UGUI研究院之不規(guī)則按鈕的響應(yīng)區(qū)域(十四)
使用mask的方式
Image.alphaHitTestMinimumThreshold
ICanvasRaycastFilter.IsRaycastLocationValid
總結(jié)
以上是生活随笔為你收集整理的ugui unity 取消选择_UGUI中几种不规则按钮的实现方式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 减肥天天吃鸡胸肉行吗
- 下一篇: 中connect怎么用_烘焙中的各种酒,