對Unity Editor 控制元件的封裝 (4.3.2f1)
阿新 • • 發佈:2019-02-09
/// <summary> /// 編輯器控制元件基類 /// </summary> public class EditorControlBase { public string Name; public float Width { private set; get; } public float Height{ private set; get; } protected List<GUILayoutOption> guiLayout = new List<GUILayoutOption>(); public EditorControlBase(string name) { this.Name = name; } public void SetSize(float width, float height) { this.Width = width; this.Height = height; guiLayout.Clear(); guiLayout.Add(GUILayout.Width(Width)); guiLayout.Add(GUILayout.Height(Height)); } public virtual void OnGUIUpdate() { } }
/// <summary> /// 編輯器控制元件 - 按鍵 /// </summary> public class ECButton : EditorControlBase { public delegate void ECButtonDel(); public ECButtonDel OnClick; public ECButton(string name) : base(name) { } public override void OnGUIUpdate() { if (GUILayout.Button(this.Name, guiLayout.ToArray())) { if (OnClick != null) { OnClick(); } } } }
/// <summary> /// 編輯器控制元件 - 文字框 /// </summary> public class ECLabel : EditorControlBase { public string Text; public ECLabel(string name) : base(name) { Text = name; } public override void OnGUIUpdate() { EditorGUILayout.LabelField(this.Text,guiLayout.ToArray()); } }
/// <summary>
/// 編輯器控制元件 - 下拉框
/// </summary>
public class ECPopup<T> : EditorControlBase
{
int popup = 0;
public List<T> Items = new List<T>();
/// <summary>
/// 當前選中的
/// </summary>
public T SelectItem { private set; get; }
/// <summary>
/// 當前選中的
/// </summary>
public int SelectItemIndex { private set; get; }
public ECPopup(string name)
: base(name)
{
}
/// <summary>
/// 返回選中的專案
/// </summary>
public override void OnGUIUpdate()
{
List<string> names = new List<string>();
foreach (T i in Items)
names.Add(i.ToString());
popup = EditorGUILayout.Popup(this.Name, popup, names.ToArray(),guiLayout.ToArray());
if (popup >= 0 && popup < Items.Count)
{
SelectItem = Items[popup];
SelectItemIndex = popup;
}
}
}
/// <summary>
/// 編輯器控制元件 - 空白
/// </summary>
public class ECSpace : EditorControlBase
{
float pixels;
public ECSpace(float pixels)
: base("")
{
this.pixels = pixels;
}
public override void OnGUIUpdate()
{
GUILayout.Space(pixels);
}
}
/// <summary>
/// 編輯器控制元件 - 文字框
/// </summary>
public class ECText : EditorControlBase
{
public string Text { private set; get; }
public ECText(string name,string text)
: base(name)
{
this.Text = text;
}
/// <summary>
/// 返回選中的專案
/// </summary>
public override void OnGUIUpdate()
{
Text = EditorGUILayout.TextField(this.Name, Text,guiLayout.ToArray());
}
}
/// <summary>
/// 編輯器控制元件 - 多選框
/// </summary>
public class ECToggle : EditorControlBase
{
public delegate void ECToggleDel(bool isbool);
public ECToggleDel OnClick;
ECLabel ecLabel;
bool nowbool = false;
bool lastbool = false;
public bool IsCheck
{
get { return nowbool; }
set { nowbool = value; }
}
public new string Name { set { this.ecLabel.Text = value; } }
public ECToggle(string name, bool initBool)
: base(name)
{
this.nowbool = initBool;
this.lastbool = initBool;
ecLabel = new ECLabel(name);
}
public override void OnGUIUpdate()
{
GUILayout.BeginHorizontal();
nowbool = EditorGUILayout.Toggle(nowbool, GUILayout.Width(30), GUILayout.Height(20));
ecLabel.OnGUIUpdate();
GUILayout.EndHorizontal();
if (nowbool != lastbool)
{
if (OnClick != null)
OnClick(nowbool);
lastbool = nowbool;
}
}
}
/// <summary>
/// 編輯器控制元件 - 資料表
/// </summary>
public class ECTable : EditorControlBase
{
public List<DataRow> DataRows = new List<DataRow>(); //DataRow 類存放一行的所有資料
protected ECSpace ecSpace;
protected Dictionary<string, int> columnName_Width = new Dictionary<string, int>(); // 列名和寬度
//事件
public delegate void OnDeleteRowDel(int ID);
public OnDeleteRowDel OnDeleteRow;
//資料快取. 針對每個LevelEnemyOneRow鍵一個快取字典, int is LevelEnemyOneRow.ID, string is columnName
protected Dictionary<int, Dictionary<string, ValueCache>> inputDataCache = new Dictionary<int, Dictionary<string, ValueCache>>();
public ECTable(string name)
: base(name)
{
}
protected class ValueCache
{
public Type Type;
public object ObjValue;
public ValueType ValueType = ValueType.Assigned;
public ValueCache(object objValue, Type type)
{
this.ObjValue = objValue;
this.Type = type;
}
}
/// <summary>
/// 值衝突型別
/// </summary>
protected enum ValueType
{
Assigned, //正常值,已經賦值了的
BeModify, //被修改了還沒有賦值的
Error, //錯誤資料, 還沒有賦值
}
protected Color GetColor(ValueType v)
{
if (v == ValueType.Error)
return Color.red;
if (v == ValueType.BeModify)
return Color.yellow;
return Color.green;
}
protected void DisplayText<T>(int rowID, T _value, string colName)
{
//找出快取中對應的項
ValueCache vc;
if (inputDataCache[rowID].ContainsKey(colName) == true)
vc = inputDataCache[rowID][colName];
else
vc = new ValueCache(_value, typeof(T));
GUI.color = GetColor(vc.ValueType);
string temp = vc.ObjValue.ToString();
vc.ObjValue = GUILayout.TextField(vc.ObjValue.ToString(), GUILayout.Width(columnName_Width[colName]));
if (vc.ValueType == ValueType.Assigned && temp != vc.ObjValue.ToString())
vc.ValueType = ValueType.BeModify;
//更新快取
if (inputDataCache[rowID].ContainsKey(colName) == true)
inputDataCache[rowID][colName] = vc;
else
inputDataCache[rowID].Add(colName, vc);
GUI.color = Color.white;
}
protected void DisplayText<T>(T _value, string colName)
{
GUILayout.TextField(_value.ToString(), GUILayout.Width(columnName_Width[colName]));
}
//_value為要賦值的真正資料
protected static void ConvertData<T>(ValueCache vc, ref T _value, float min, float max)
{
try
{
//限制必須是數字
T temp = (T)Convert.ChangeType(vc.ObjValue, typeof(T));
//限制數字的大小, 超過限制就走 catch
if (Helper.IsNumericalLimits(float.Parse(temp.ToString()), max, min) == false)
throw new Exception();
_value = temp;
vc.ValueType = ECTable.ValueType.Assigned;
}
catch
{
vc.ValueType = ECTable.ValueType.Error;
}
}
}
/// <summary>
///編輯器控制元件 - 資料表 使用例項 繼承ECTable
/// </summary>
public class ECTable_test : ECTable
{
public List<EditorSModel> SoldierModels = new List<EditorSModel>();
//事件
public delegate void OnDeleteSoldierDel(EditorSModel esm);
public OnDeleteSoldierDel OnDeleteSoldier;
public ECTable_test(string name, float backspace)
: base(name)
{
ecSpace = new ECSpace(backspace);
columnName_Width.Add("單位ID", 50);
columnName_Width.Add("士兵等級", 60);
columnName_Width.Add("X", 40);
columnName_Width.Add("Y", 40);
}
public override void OnGUIUpdate()
{
Display();
}
public void ClearAll()
{
for (int i = 0; i < SoldierModels.Count; i++)
{
GameObject.DestroyImmediate(SoldierModels[i].gameObject);
}
SoldierModels.Clear();
}
void Display()
{
//列名
GUILayout.BeginHorizontal();
ecSpace.OnGUIUpdate();
foreach (var col in columnName_Width)
{
GUILayout.Label(col.Key, GUILayout.Width(col.Value));
}
GUILayout.EndHorizontal();
for (int i = 0; i < SoldierModels.Count; i++)
{
EditorSModel esm = SoldierModels[i];
GUILayout.BeginHorizontal();
ecSpace.OnGUIUpdate();
DisplayText<int>(esm.SoldierID, "單位ID");
DisplayText<int>(esm.SoldierLevel, "士兵等級");
DisplayText<float>(esm.LayPosition.x, "X");
DisplayText<float>(esm.LayPosition.y, "Y");
//刪除一行
if (GUILayout.Button("刪除", GUILayout.Width(38)))
{
if (OnDeleteSoldier != null)
OnDeleteSoldier(esm);
SoldierModels.RemoveAt(i);
i--;
}
GUILayout.EndHorizontal();
}
}
}