Unity ComboBox(下拉框)实现

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_37245458/article/details/98048040

在扩展编辑器、绘制窗口等情况下我们需要用到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);
            }
        }

猜你喜欢

转载自blog.csdn.net/qq_37245458/article/details/98048040