Unity3D 重寫下拉菜單/Dropdown組件、開啟每個按鈕可用


Override Dropdown Component


本文提供全流程,中文翻譯。

Chinar 堅持將簡單的生活方式,帶給世人!

(擁有更好的閱讀體驗 —— 高分辨率用戶請根據需求調整網頁縮放比例)



Chinar —— 心分享、心創新!

為實現下拉菜單/ Dropdown 每個按鈕可用性,提供解決方案

為新手節省寶貴的時間,避免采坑!


Chinar 教程效果:



全文高清圖片,點擊即可放大觀看 (很多人竟然不知道)


1

Description —— 說明


Unity UGUI 之后提供了下拉菜單、簡單的解決方案使我們可以快速的創建下拉菜單

但在有些情況下,無法滿足需求

例如:下拉菜單彈出時,首選項是被選中狀態

當我們點擊首選項的時候永遠不會調用首選項的方法/函數

同樣,當我們選擇了某個選項,例如第三項,那么下次我們再次點擊第三項,同樣不會調用方法

本教程就是專門來解決此類問題,提供解決方案
舉個栗子黑白88


2


以下腳本,是繼承自 Dropdown 類的

也就是在 Dropdown 的基礎上,對其內部函數進行了擴展

所以使用的時候,只需要創建一個下拉菜單UI元素,並移除其上的 Dropdown 組件

替換為 ChinarDropdown 腳本即可
舉個栗子黑白88

using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;


/// <summary>
/// 將下拉菜單上的 Dropdown組件移除,替換為該腳本
/// </summary>
public class ChinarDropdown : Dropdown
{
    public bool AlwaysCallback = false;//是否開啟 點擊選項按鈕總是回調


    public void Show()
    {
        base.Show();
        Transform toggleRoot = transform.Find("Dropdown List/Viewport/Content");
        Toggle[]  toggleList = toggleRoot.GetComponentsInChildren<Toggle>(false);
        for (int i = 0; i < toggleList.Length; i++)
        {
            Toggle temp = toggleList[i];
            temp.onValueChanged.RemoveAllListeners();
            temp.isOn = false;
            temp.onValueChanged.AddListener(x => OnSelectItemEx(temp));
        }
    }


    public override void OnPointerClick(PointerEventData eventData)
    {
        Show();
    }


    public void OnSelectItemEx(Toggle toggle)
    {
        if (!toggle.isOn)
        {
            toggle.isOn = true;
            return;
        }

        int       selectedIndex = -1;
        Transform tr            = toggle.transform;
        Transform parent        = tr.parent;
        for (int i = 0; i < parent.childCount; i++)
        {
            if (parent.GetChild(i) == tr)
            {
                selectedIndex = i - 1;
                break;
            }
        }

        if (selectedIndex < 0)
            return;
        if (value == selectedIndex && AlwaysCallback)
            onValueChanged.Invoke(value);
        else
            value = selectedIndex;
        Hide();
    }
}

3


細心的朋友已經注意到,2中的代碼多了一個 AlwaysCallback 的布爾值變量

在層次面板中直接控制這個變量的對錯,我們就需要一個編輯器類

進而控制下拉菜單是否開啟函數,總是回調

如果不開啟 / AlwaysCallback為:false;反之亦然!
舉個栗子黑白88

using UnityEditor; //引用編輯器的腳本,需要放在 Editor 目錄中
using UnityEditor.UI;


/// <summary>
/// 此編輯器腳本:用於在層次面板中添加一個可控屬性AlwaysCallback
/// </summary>
[CustomEditor(typeof(ChinarDropdown), true)]
[CanEditMultipleObjects]
public class DropdownExEditor : DropdownEditor
{
    SerializedProperty AlwaysCallback;


    protected override void OnEnable()
    {
        base.OnEnable();
        AlwaysCallback = serializedObject.FindProperty("AlwaysCallback");
    }


    public override void OnInspectorGUI()
    {
        base.OnInspectorGUI();
        EditorGUILayout.PropertyField(AlwaysCallback);
        serializedObject.ApplyModifiedProperties();
    }
}

這里寫圖片描述


支持

May Be —— 搞開發,總有一天要做的事!


擁有自己的服務器,無需再找攻略!

Chinar 提供一站式教程,閉眼式創建!

為新手節省寶貴時間,避免采坑!


先點擊領取 —— 阿里全產品優惠券 (享受最低優惠)


1 —— 雲服務器超全購買流程 (新手必備!)

2 —— 阿里ECS雲服務器自定義配置 - 購買教程(新手必備!)

3—— Windows 服務器配置、運行、建站一條龍 !

4 —— Linux 服務器配置、運行、建站一條龍 !





技術交流群:806091680 ! Chinar 歡迎你的加入


END

本博客為非營利性個人原創,除部分有明確署名的作品外,所刊登的所有作品的著作權均為本人所擁有,本人保留所有法定權利。違者必究

對於需要復制、轉載、鏈接和傳播博客文章或內容的,請及時和本博主進行聯系,留言,Email: ichinar@icloud.com

對於經本博主明確授權和許可使用文章及內容的,使用時請注明文章或內容出處並注明網址
>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM