Unity GUI的一些使用


常用控件

  • GUI.Toggle(pos, value, label, "button")最后的GUIStyle设置为button就可以变成toggle形式的button了
  • EditorGUI.BeginChangeCheck()EditorGUI.EndChangeCheck()可以用来检测control控件是否修改
  • EditorGUI.DelayedDoubleField()EditorGUI.DoubleField()的区别在于前者只有当鼠标移出输入框的时候才会返回值
  • EditorGUILayout.Foldout()是一个带标签的折叠箭头
  • EditorGUILayout.BeginFoldoutHeaderGroup()EditorGUILayout.EndFoldoutHeaderGroup相比于Foldout(),有一个HeaderTitle,而且是一个折叠块
  • EditorUtility.OpenFolderPanel ("excel路径", LoadCenter.RootDir, "C:\\"); 用于选定一个文件路径
  • obj = EditorGUILayout.ObjectField (label, obj, typeof (T), allowSceneObjects) as T; 用来选择资源

Scope的简写形式

  • 通过一个结构体实现IDisposable在末尾实现EndScope
  • 这样就不会忘记结尾了
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
    public struct Vertical : IDisposable
        {
            public Rect Rect { get; private set; }
            FlexibleTypes flexible;

            public static Vertical New (FlexibleTypes flexible, GUIStyle style, params GUILayoutOption[] options)
            {
                var rect = EditorGUILayout.BeginVertical (style, options);
                if (flexible.FlexibleBegin ())
                {
                    GUILayout.FlexibleSpace ();
                }
                return new Vertical () { flexible = flexible, Rect = rect };
            }
            public void Dispose ()
            {
                if (flexible.FlexibleEnd ())
                {
                    GUILayout.FlexibleSpace ();
                }
                EditorGUILayout.EndVertical ();
            }
        }

  • 具体使用
1
2
3
using (GUIScope.Horizontal.New (FlexibleTypes.Begin))
{
}

SerializeObject

  • unity 推荐在自定义Editor中使用这个对象来编辑数据
  • 在绘制UI的时候EditorGUI.PropertyField(),传入SerializeProperty即可
  • 通过stages = serializedObject.FindProperty ("stages"); 可以查找到对应属性
  • 这个序列化对象相当于一个流,他可以用来对多个对象的编辑,他本身会处理Undo, prefab保存这些。
1
2
3
4
serializeObject.update();
//draw UI

serializedObject.ApplyModifiedProperties();
  • 可实际上用起来十分麻烦,代码量会增加一倍,而且用字符串的方法来索引属性,如果属性更改名字了要怎么办。

includeChildren

  • public static bool PropertyField (Rect position, SerializedProperty property, [DefaultValue ("false")] bool includeChildren);
  • includeChildren设置为true会绘制该属性的内部字段

PropertyDrawer

  • 继承PropertyDrawer后重写OnGUI在内部是无法使用Layout自动布局的。会导致报错

ReOrderableList

  • Unity 内部有一个ReOrderableList,但其实并不好用
  • 对于每个Item的Height只能设定为固定值或者实现其回调GetItemHeight()

在场景中绘制Gizmos

  • 在editor模式下我们有时候需要在Scene中绘制一些形状测试用
  • 这些形状不会在Game窗口中显示
1
2
3
4
5
6
7
    private void OnDrawGizmos ()
    {
        foreach (var pos in allCube)
        {
            Gizmos.DrawCube (pos, Vector3.one);
        }
    }

OnValidate

  • 在monobehaviour中,如果你在Inspector面板上修改了他的数据,那么就会被触发,经常用来校验数据