Unity ComboBox(下拉框)實現

在擴展編輯器、繪製窗口等情況下我們需要用到ComboBox來進行多項選擇,但是GUI中沒有DropList的實現,所以需要自己做一個ComboBox的效果。

效果如下:

當點擊Prefabs時,會更新出Prefabs下的所有預製體進行選擇,然後進行地圖編輯。

源碼:

using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;

#if UNITY_EDITOR
public class ResourcesComboBox {
    public bool isChoice = false;
    public bool isDirComboBoxOpen = false;
    public bool isResComboBoxOpen = false;
    public GameObject[] resGameObjectArray;
    private Vector2 start_pos = new Vector2(0, 0);

    public string DirectoryComboList(string path) {
        string[] names = Directory.GetDirectories(path);
        string[] new_names = new string[names.Length + 1];
        for (int i = 0; i < names.Length; i++) {
            new_names[i] = names[i];
        }
        new_names[names.Length] = path;
        names = new_names;

        GUIStyle buttonStyle = new GUIStyle("button");
        buttonStyle.alignment = TextAnchor.MiddleLeft;

        int index = 0;
        string name = "";
        if (isDirComboBoxOpen) {
            start_pos = GUI.BeginScrollView(new Rect(0, 25, 200, 200), start_pos, new Rect(0, 25, 160, names.Length * 35), false, true);
            GUI.Box(new Rect(0, 25, 200, names.Length * 35), "");
            for (int i = 0; i < names.Length; i++) {
                GUIContent itemContent = new GUIContent(names[i].Substring(names[i].LastIndexOf('\\') + 1));
                if (GUI.Button(new Rect(0, 25 + i * 35, 200, 35), itemContent, buttonStyle)) {
                    isDirComboBoxOpen = false;
                    isResComboBoxOpen = true;
                    isChoice = true;
                    index = i;
                    name = itemContent.text;
                }
            }
            GUI.EndScrollView();
        }

        if (isChoice)
            return name.Equals("Prefabs") ? "" : name;
        else
            return "";
    }

    public GameObject ResComboList() {
        // Set list style
        // GUIStyle listStyle = new GUIStyle();
        // listStyle.normal.textColor = Color.white;
        // listStyle.normal.background = new Texture2D(0, 0);
        // listStyle.onHover.background = new Texture2D(2, 2);
        // listStyle.hover.background = new Texture2D(2, 2);
        // listStyle.padding.bottom = 4;
        // End

        GUIStyle buttonStyle = new GUIStyle("button");
        buttonStyle.alignment = TextAnchor.MiddleLeft;
        
        int index = 0;
        if (isResComboBoxOpen) {
            start_pos = GUI.BeginScrollView(new Rect(0, 25, 200, 200), start_pos, new Rect(0, 25, 160, resGameObjectArray.Length * 35), false, true);
            GUI.Box(new Rect(0, 25, 200, resGameObjectArray.Length * 35), "");
            for (int i = 0; i < resGameObjectArray.Length; i++) {
                GUIContent itemContent = new GUIContent(resGameObjectArray[i].name, UnityEditor.AssetPreview.GetAssetPreview(resGameObjectArray[i]));
                if (GUI.Button(new Rect(0, 25 + i * 35, 200, 35), itemContent, buttonStyle)) {
                    isResComboBoxOpen = false;
                    isChoice = true;
                    index = i;
                }
            }
            GUI.EndScrollView();
        }

        if (isChoice)
            return ComboElementInstance(index);
        else
            return null;
    }
    
    private GameObject ComboElementInstance(int index) {
        var go = GameObject.Instantiate(resGameObjectArray[index]);
        go.name = resGameObjectArray[index].name;

        for (int i = 0; i < go.transform.childCount; i++) {
            Transform child = go.transform.GetChild(i);
            if (child.GetComponent<Collider2D>() == null)
                child.gameObject.AddComponent<BoxCollider2D>();
        }

        return go;
    }
}
#endif

可以根據需要,將ComboBox封裝,也可以擴展方法去調用。

使用方式:

        if (GUI.Button(new Rect(40, 0, 120, 25), new GUIContent("Open List"))) {
            comboBox.isDirComboBoxOpen = !comboBox.isDirComboBoxOpen;
            comboBox.isResComboBoxOpen = false;
        }
        
        if (comboBox.isDirComboBoxOpen) {
            string path = comboBox.DirectoryComboList(".\\Assets\\Sunnyland\\Resources\\Prefabs");
            if (comboBox.isChoice) {
                comboBox.isChoice = !comboBox.isChoice;
                comboBox.resGameObjectArray = catch_terrain_resources.TerrainResources(path);
            }
        }

        if (comboBox.isResComboBoxOpen) {
            var go = comboBox.ResComboList();
            if (comboBox.isChoice && go) {
                comboBox.isChoice = !comboBox.isChoice;
                data_utility._instance.CacheTerrainData(go.transform, go.transform);
                auto_calc_size size = go.AddComponent<auto_calc_size>();
                BoxCollider collider = go.AddComponent<BoxCollider>();
                collider.size = new Vector3(size.width, size.height, 1);
                collider.center = new Vector3(size.center_x, size.center_y, 0);
            }
        }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章