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