看來是時候是要來記錄EditorGUILayout要怎麼寫了。
『 EditorWindow 』
一般來說會看起來像是這樣:
public class CreateSkill : EditorWindow
{
[MenuItem("創造/新技能")]
public static void CreateSkills()
{
EditorWindow window = EditorWindow.CreateInstance<CreateSkill>();
window.Show();
}
private bool isOK = false;
private GUIStyle gs = new GUIStyle();
public string Index;
void OnGUI()
{
EditorGUIUtility.labelWidth = 100;
gs.alignment = TextAnchor.UpperCenter;
if (!isOK)
{
//do something
isOK = true;
}
EditorGUILayout.LabelField("<----技能資料---->", gs);
Index = EditorGUILayout.TextField("技能ID", Index);
if(GUILayout.Button("確定"))
{
this.Close();
}
}
}
以下容我來介紹一下:
【作為EditorWindow的入口】
[MenuItem("上面工具列/子選單")]
裡面是實體化EditorWindow:
EditorWindow.CreateInstance<CreateSkill>();
及顯示視窗
window.Show(); //window是EditorWindow的物件
接著就會使用OnGUI內的東西,簡單來說每一禎都會渲染視窗,所以使用區域變數是無法跨禎使用,請多加注意。
另外,是由上至下渲染的,所以無法回頭改變已經渲染完的東西。
【然後第一行】
EditorGUIUtility.labelWidth = 100; //指定EditorGUILayout的Label的寬度都預設100
這是我最常用到的哈哈,其他很少碰到,以後碰到再介紹~
GUIStyle客製化樣式:
GUIStyle gs = new GUIStyle(); //必須先New出一個GUIStyle
gs.alignment = TextAnchor.UpperCenter; //設定要改變的參數
EditorGUILayout.LabelField("<----技能資料---->", gs); //指定給要使用此GUIStyle的物件
isOK是因為我不想每一禎都渲染作為初始化用的部分,在此省略。哈哈哈哈。
【內容】
在製作工具或等等的東西時,有時候會需要自定義輸入的畫面,所以有了EditorWindow,裡面可以客製化各式各樣的輸入及顯示部分。
GUILayout及EditorGUILayout是可以混用的,非常方便。
以下介紹一些我常用的一些輸入框:
variable = EditorGUILayout.TextField(variable); //variable為string
一般的字串輸入框
variable = EditorGUILayout.TextArea(variable); //variable為string
一般的字串輸入區域
variable = EditorGUILayout.PasswordField(variable); //variable為string
一般的密碼的輸入區域,你懂得
variable = EditorGUILayout.IntField(variable); //variable為int
一般的數字輸入框,如要限制最大值及最小值,幾乎只能額外寫限制數值下方有小提如何限制
variable = EditorGUILayout.IntSlider(variable); //variable為int
數字輸入框,旁邊送你一個可以拖曳調整數值的組件;
也可以額外設定最小值及最大值EditorGUILayout.IntSlider(variable,Min,Max); //variable為int
variable = EditorGUILayout.IntPopup(variable,new string[] { "一", "二", "三" },new int[] { 1, 2, 3 }); //variable為int
數字輸入框,為下拉式的數字選擇框,new string[] { }放的是顯示的選項,new int[] { }是對應string[]{ }的數值
variable = EditorGUILayout.Popup(variable, new string[] { "零", "一", "二" }); //variable為int
跟上面很像,不過這個是純選項,回傳的是選擇到的索引值
variable = (variableEnum)EditorGUILayout.EnumPopup(variable); //variable為variableEnum
列舉選擇框,我認為非常好用,就是直接給列舉選項就是了,記得要轉回列舉型態
variable = EditorGUILayout.LongField(variable); //variable為long
一般的Long輸入框
variable = EditorGUILayout.FloatField(variable); //variable為float
一般的float的輸入框
variable = EditorGUILayout.DoubleField(variable); //variable為Double
一般的double的輸入框
variable = EditorGUILayout.Vector2Field(variable); //variable為Vector2
一般的Vector2輸入框,有x,y向量
variable = EditorGUILayout.Vector3Field(variable); //variable為Vector3
一般的Vector3輸入框,有x,y,z向量
variable = EditorGUILayout.RectField(variable); //variable為Rect
一般的Rect輸入框,有x,y,w,h向量
variable = EditorGUILayout.ColorField(variable); //variable為Color
回傳Color的輸入框,會出現一個顏色選擇框,有r,g,b,a值,順帶一提,其數值皆為0~1
variable = EditorGUILayout.Toggle(variable); //variable為bool
就是平常用的CheckBox那樣的東西,嘛
variable = EditorGUILayout.ToggleLeft(variable); //variable為bool
就是上面的那個東西,不過如果有Label的話就會把勾選的選項放在左邊
EditorGUILayout.LabelField("這裡寫想顯示的東西");
就是有必需顯示的訊息就用此組件
EditorGUILayout.PrefixLabel("這裡寫想顯示的東西");
如果有需要顯示在輸入框之前的文字就寫在此
EditorGUILayout.Space();
單純就是排版用的空白,
有時候我也會用EditorGUILayout.LabelField(""); 來空格
【特別介紹(物件輸入框)】
variable = EditorGUILayout.ObjectField(variable,typeof(System.Type),false) as System.Type; //variable為某種物件,該物件是個Type都可以
但是...這很難用...
先介紹一下,variable就是物件,typeof(System.Type)就是指定是甚麼Type,false是指是否能選取場景中的物件
原則上各位朋友們會遇到的,應該最常使用莫過於材質或精靈圖吧!
variable = EditorGUILayout.ObjectField(variable, typeof(Sprite), false) as Sprite; //variable為Sprite
variable = (Material)EditorGUILayout.ObjectField(variable, typeof(Material), false); //variable為Material
也可以寫成這樣轉換,但轉換失敗會出錯就是了。不過一般來說指定type就已經會過濾非該type的物件不能選入,但是還是有特殊狀況。
Sprite有正方形(可預覽),以及跟物件一樣的輸入面板,可以透過指定GUILayout的高度Height低於高於60來切換。
如果你想用自定義的物件,可以這樣用:
variable = (MyClass)EditorGUILayout.ObjectField(variable, typeof(MyClass), false); //variable為MyClass
原則上這樣就可以實現,但是還要記得在該MyClass裡面指定:
public class SceneA : ScriptableObject //繼承父物件,設定為客製的Asset
如果想要直接選擇某些Script,就要再多做一些處理:
MonoScript variable; //先宣告一個MonoScript
variable = EditorGUILayout.ObjectField("額外動畫", variable, typeof(MonoScript), false) as MonoScript; //variable為MonoScript
然後再選擇完後,如果是要加到遊戲物件的話就用:
(MyClass)MyGameObject.AddComponent(variable.GetClass()); //加入Script物件給遊戲物件
【較沒機會碰到】
variable = EditorGUILayout.BoundsField(variable); //variable為Bounds
將會回傳Bounds,是指三維的方框邊界,一個類似Box的物件的邊界值
variable = EditorGUILayout.CurveField(variable); //variable為AnimationCurve
將會回傳一個AnimationCurve,動畫曲線,目前我還沒實際使用的機會,需要用到的各位朋友們,就請自己去研究啦!
另外,以上的所有EditorGUILayout都可以加上其"Label"說明文字,及GUILayoutOption[],如下:
variable = EditorGUILayout.IntField("說明文字", variable,GUILayout.Width(100));
【排版】
//最後須要介紹的就是排版的部分了,請容我緩緩道來:
將元素都橫向排列
EditorGUILayout.BeginHorizontal();
需要排列的元素們
EditorGUILayout.EndHorizontal();
將元素都縱向排列
EditorGUILayout.BeginVertical();
需要排列的元素們
EditorGUILayout.EndVertical();
將區域設定成可滑動區域
scrollPos = EditorGUILayout.BeginScrollView(scrollPos); //scrollPos是捲動的位置
需要排列的元素們
EditorGUILayout.EndHorizontal();
將區域設定成可展開/回收區域
foldbool = EditorGUILayout.Foldout(foldbool); //foldbool是展開/回收狀態
if(foldbool)
{
需要排列的元素們
}
聽說有個甚麼EditorGUILayout.BeginFadeGroup();但我不會用所以跳過
另外還有一個EditorGUILayout.BeginToggleGroup;CheckBox群組也可以設為區域
而以上,沒錯,都有另一個使用方式,如下:
using (var v = new EditorGUILayout.VerticalScope()) //將元素都縱向排列
{
需要排列的元素們
}
using (var h = new EditorGUILayout.HorizontalScope()) //將元素都橫向排列
{
需要排列的元素們
}
using (var scrollView = new EditorGUILayout.ScrollViewScope()) //將區域設定成可滑動區域
{
scrollPos = scrollView.scrollPosition;
需要排列的元素們
}
備註: 在區域中也可以使用GUILayout,例:
using (var v = new EditorGUILayout.VerticalScope(GUILayout.Height(60))) //將元素都縱向排列
{
需要排列的元素們
}
【按鈕】
if(GUILayout.Button("確定"))
{
//要做的事情
}
EditorGUILayout沒有按鈕,所以只能使用GUILayout的按鈕,因為通用性蠻高的所以EditorWindow就沒額外的按鈕了吧。
if裡面指的是按下按鈕後要做的事情,如果要加上額外的樣式也是可以加在後面,如if(GUILayout.Button("確定"),GUILayout.Width(60))
【關閉】
this.Close();
關閉目前的EditorWindow
『 同場加映 』
【如何限制數值】
目前我比較常用以下兩個簡單的方法
1.
int temp = EditorGUILayout.IntField(variable); //variable為int
if (temp > Max) temp = Max;
if (temp > Min) temp = Min;
variable = temp;
2.
variable = Mathf.Clamp(EditorGUILayout.IntField(variable),Min,Max);
【如何存出檔案】
如我要存成Prefab(遊戲物件)可以使用PrefabUtility:
PrefabUtility.CreatePrefab("Assets/prefab/" + prefabName + ".prefab", newGameObject); //儲存預置物到外部
如果要存成一般的Asset物件,可以用AssetDatabase:
AssetDatabase.CreateAsset(MyAsset, string.Format("Assets/{0}.asset", MyAssetName));
【讀取檔案】
不論prefab還是Asset我幾乎都使用:
(GameObject)AssetDatabase.LoadAssetAtPath(string.Format("Assets/{0}.prefab", newGameObject), typeof(GameObject));
或把GameObject換成要讀取的東西。
【Unity.Object】
基本上Sprite,GameObject,Material都屬於Unity.Object,而我特別拿來介紹是有個特別的Asset要備註。
SceneAsset,
沒錯,這是場景物件,副檔名是".unity",而這個物件只能使用在UnityEditor,
各位朋友們肯定想問,那如果在遊戲中要使用場景資源怎麼辦?
只能 -- 使用string記住Scene的名稱,這是我這邊目前的辦法。
以上是這篇筆記的全部內容,如果有任何一段有幫助到你就太好了。
留言
張貼留言