UEDL3-8——动画曲线、布局
本章代码关键字
1 2 3 4 5 6 7 8 9 EditorGUILayout.CurveField() AnimationCurve EditorGUILayout.BeginHorizontal() EditorGUILayout.EndHorizontal() EditorGUILayout.BeginVertical() EditorGUILayout.EndVertical() EditorGUILayout.BeginScrollView() EditorGUILayout.EndScrollView() EditorGUILayout.GetControlRect()
动画曲线控件
动画曲线控件可以让我们在编辑器窗口上设置一个动画曲线
它需要配套一个 AnimationCurve
(动画曲线)变量,该变量必须初始化才可用于控件内,否则报空
需要将该变量传入到方法内,再由该变量接收本帧设置的动画曲线
参数一:文本标题(可选,可改为GUIContent
)
参数二:AnimationCurve
本帧要显示的动画曲线变量
参数三:曲线颜色(可选)
参数四:位置范围(可选)
参数五:GUILayoutOption
(使用EditorGUI
绘制时可选)
返回值:本帧设置的AnimationCurve
动画曲线
1 2 3 4 5 6 AnimationCurve curve = new AnimationCurve(); private void OnGUI (){ curve = EditorGUILayout.CurveField("曲线控件" , curve); }
显示效果:
布局相关API
水平布局
编辑器窗口默认的垂直布局的,我们可以通过BeginHorizontal
方法和EndHorizontal
方法来包裹需要水平布局的控件
1 2 3 4 5 6 7 8 private void OnGUI (){ EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("文本控件1" ); EditorGUILayout.LabelField("文本控件2" ); EditorGUILayout.LabelField("文本控件3" ); EditorGUILayout.EndHorizontal(); }
显示效果:
垂直布局
和水平布局一样,我们需要BeginHorizontal
方法和EndHorizontal
方法来包裹需要垂直布局的控件
编辑器窗口默认是垂直布局的,因此一般不使用这对方法
但是我们可以在被水平布局语句包裹的语句块内使用它,使得水平布局的控件内可以有一部分控件是垂直布局的
1 2 3 4 5 6 7 8 9 10 11 12 private void OnGUI (){ EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("文本控件1" ); EditorGUILayout.BeginVertical(); EditorGUILayout.LabelField("文本控件2" ); EditorGUILayout.LabelField("文本控件2-1" ); EditorGUILayout.LabelField("文本控件2-2" ); EditorGUILayout.EndVertical(); EditorGUILayout.LabelField("文本控件3" ); EditorGUILayout.EndHorizontal(); }
显示效果:
滚动视图布局
可以用BeginScrollView
方法和EndScrollView
方法包裹编辑器窗口内的控件
使得控件被排布在滚动视图内,可以滚动显示控件,适用于控件很多而窗口较小的情况
需要配套一个Vector2
变量来表示滚动到的位置,该变量需要传入到BeginScrollView
方法内,并接收BeginScrollView
方法的返回值
参数一:当前滚动到的位置(Vector2
变量)
参数二:是否总是显示水平滚动条(可选)
参数三:是否总是显示垂直滚动条(可选)
参数四:GUIStyle
(可以对水平滚动条,垂直滚动条以及背景都设置其对应的GUIStyle
)
参数五:GUILayoutOption
(使用EditorGUI
绘制时可选)
返回值:本帧滚动到的位置(Vector2
变量)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 int i, i1, i2; long l; float f; double d; string s;Vector2 vector2; Vector3 vector3; Vector4 vector4; Rect rect; Bounds bounds; BoundsInt boundsInt; Vector2 vec2Pos; Vector2 vec2Pos2; private void OnGUI (){ vec2Pos2 = EditorGUILayout.BeginScrollView(vec2Pos2); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("文本控件1" ); EditorGUILayout.BeginVertical(); EditorGUILayout.LabelField("文本控件2" ); EditorGUILayout.LabelField("文本控件2-1" ); EditorGUILayout.LabelField("文本控件2-2" ); EditorGUILayout.EndVertical(); EditorGUILayout.LabelField("文本控件3" ); EditorGUILayout.EndHorizontal(); EditorGUILayout.EndScrollView(); vec2Pos = EditorGUILayout.BeginScrollView(vec2Pos); i = EditorGUILayout.IntField("Int输入框" , i); l = EditorGUILayout.LongField("long输入框" , l); f = EditorGUILayout.FloatField("Float 输入:" , f); d = EditorGUILayout.DoubleField("double 输入:" , d); s = EditorGUILayout.TextField("Text输入:" , s); vector2 = EditorGUILayout.Vector2Field("Vec2输入: " , vector2); vector3 = EditorGUILayout.Vector3Field("Vec3输入: " , vector3); vector4 = EditorGUILayout.Vector4Field("Vec4输入: " , vector4); rect = EditorGUILayout.RectField("rect输入: " , rect); bounds = EditorGUILayout.BoundsField("Bounds输入: " , bounds); boundsInt = EditorGUILayout.BoundsIntField("BoundsInt输入: " , boundsInt); EditorGUILayout.EndScrollView(); }
显示效果:
获取在编辑器上自动布局的矩形
如果需要在编辑器上自动布局某个不能直接通过 EditorGUILayout
绘制的控件(通常是自己实现的自定义控件,如 PropertyDrawer
的派生类)
可以先通过 EditorGUILayout.GetControlRect()
来获取自动布局的 Rect
矩形,根据 Rect
矩形即可控制控件的位置
参数一 hasLabel
:(可选)用于指定控件是否有标签。默认值为 true
参数二 height
:(可选)控件的高度(以像素为单位)。默认值为 EditorGUIUtility.singleLineHeight
EditorGUIUtility.singleLineHeight
即单个控件的高度,如单行 EditorGUI.TextField
当创建自己的多行控件(例如具有多个字段的自定义类的控件)时,可以使用 EditorGUIUtility.singleLineHeight
的倍数
具体可见:EditorGUIUtility.singleLineHeight
参数三 style
:(可选)用于控件的 GUIStyle
参数四 options
:(可选,且可以填入多个)控件的布局选项:GUILayoutOption
代码示例(来自:US5L2——MaterialPropertyDrawer类,这里是实现了一个自带范围的滑动条):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 using UnityEditor;using UnityEngine;public class Lesson127_CustomShaderInspector : ShaderGUI { private bool isShow; private Lesson128 floatDrawer = new (-2 , 2 ); public override void OnGUI (MaterialEditor materialEditor, MaterialProperty[] properties ) { if (GUILayout.Button(isShow ? "隐藏所有属性设置" : "显示所有属性设置" )) { isShow = !isShow; } Material material = materialEditor.target as Material; if (GUILayout.Button("重置材质球属性" )) { material.SetTexture("_MainTex" , null ); material.SetFloat("_TestFloat" , 0 ); } if (isShow) { MaterialProperty property = FindProperty("_MainTex" , properties); materialEditor.ShaderProperty(property, property.displayName); property = FindProperty("_TestFloat" , properties); floatDrawer.OnGUI(EditorGUILayout.GetControlRect(), property, property.displayName, materialEditor); material.renderQueue = EditorGUILayout.IntField("渲染队列" , material.renderQueue); } } } public class Lesson128 : MaterialPropertyDrawer { private float _min; private float _max; public Lesson128 (float min, float max ) { _min = min; _max = max; } public override void OnGUI (Rect position, MaterialProperty prop, string label, MaterialEditor editor ) { if (prop.type != MaterialProperty.PropType.Float) { EditorGUILayout.LabelField(label, "请使用float或者数值,否则无法使用此控件" ); return ; } prop.floatValue = EditorGUILayout.Slider($"{label} ({_min} ,{_max} )" , prop.floatValue, _min, _max); } }
显示效果: