日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

ugui unity 取消选择_UGUI中几种不规则按钮的实现方式

發(fā)布時間:2023/12/4 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ugui unity 取消选择_UGUI中几种不规则按钮的实现方式 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

前言

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;} }

但這種方法有幾個問題:

  • 由于是代碼中需要讀取圖片的alpha值用于比較,因此圖片在導(dǎo)入時需要開啟Readable/Write Enable,這樣會使運(yùn)行時貼圖大小翻倍,內(nèi)存中會額外存儲一份貼圖數(shù)據(jù),增大內(nèi)存開銷。
  • 如果是點(diǎn)擊區(qū)域內(nèi)部需要有一些低于設(shè)置值的透明樣式則無法滿足。
  • 點(diǎn)擊區(qū)域的調(diào)整需要修改圖片資源,十分不便。
  • 如果可以接受這些缺點(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)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。