Unity Editor 学习笔记
自定义Inspector面板
- //设置水平布局开始和结尾都需要(垂直布局类似)
- EditorGUILayout.BeginHorizontal();
- EditorGUILayout.EndHorizontal();
- EditorGUILayout.Space() 可在两个元素之间空出一行。
- EditorGUILayout.LabelField()标签字段
- EditorGUILayout.IntField() 整数字段
- EditorGUILayout.FloatField() 浮点数字段
- EditorGUILayout.TextField() 文本字段
- EditorGUILayout.Vector2Field() 二维向量字段
- EditorGUILayout.Vector3Field() 三维向量字段
- EditorGUILayout.Vector4Field() 四维向量字段
- EditorGUILayout.Slider()用于绘制一个滑块(滑块名字,滑块要改变的值,滑块的位置)
- EditorGUI.ProgressBar() 进度条(进度条的大小(类型是一个Rect),显示的值,进度条的名字)
- EditorGUILayout.HeplBox() 帮助框(用于绘制一个盒子,然后在盒子的里面显示提示信息)(传入提示信息,提示信息的类型)
自定义窗口
- GUIContent(界面内容类) EditorWindow.titleContent用于设置一个窗口的名字
- [MenuItem()] 必须是放在Assets/Editor文件夹下的类,且使用了Using UnityEditor;调用的函数必须是静态函数
- EditorWindow.GetWindow()获取屏幕上当前的第一个编辑器窗口,没有则创建并显示新的窗口并返回实例
- 绘制窗口 GUI
- GUILayout.Space(10) 让两个元素之间空10个元素的距离
- GUI.skin.label.fontSize、GUI.skin.label.alignment用于设置标题的字体大小和对齐格式
- GUILayout.Label() 绘制标题
- SceneManager.GetActiveScen() 返回当前编辑的场景信息
- EditorGUILayout.ObjectField 绘制对象槽 (设置卡槽的标题名字,设置字段显示的物体,设置显示的类型,设置是否允许指定场景中的物件)
- GUILayout.Button 绘制按钮
- Application.CaptureScreenshot API已过期,此处要使用ScreenCapture.CaptureScreenshot
Handles
//1.在场景中显示的位置(一物体的中心位置为基准)
//2.显示的名字
//3.在场景中显示设置的名字
Handles.Label(myHandles.transform.position + new Vector3(0, 1, 0), "My Handles");
//1.该旋转操作柄的初始旋转角度
//2.操作柄显示的位置(以物体的旋转位置为基准)
//3.设置操作柄的半径
//用于在场景中显示半径操作柄,多用于制作AI,用于判断和指定UI影响范围用。
myHandles.areaRadius = Handles.RadiusHandle(Quaternion.identity, myHandles.transform.position, myHandles.areaRadius);
设置大小
//1.可以通过Inspector面板修改的值,也是该函数的返回值
//2.操作柄的位置
//3.操作柄的指向
//4.操作柄的大小
//5.操作柄显示的方式(箭头ArrowHandleCap 矩形RectangleCap 圆形CircleCap只要是末尾带Cap的方法都能做当做参数传入)
//多用于绘制一些自定义的操作,比如Unity粒子系统用到很多自定义的操作柄,如粒子系统的Shape参数
myHandles.size = Handles.ScaleValueHandle(myHandles.size,
myHandles.transform.position,
Quaternion.identity,
myHandles.size,
Handles.ArrowHandleCap,
0.5f);
//1.该操作并与世界坐标的位置
//2.该操作柄的旋转方向
// myHandles.nodePoints[i] = Handles.PositionHandle(myHandles.nodePoints[i],Quaternion.identity);
myHandles.nodePoints[i] = Handles.PositionHandle(myHandles.nodePoints[i], myHandles.nodePointsRotation[i]);
//Mathf.Repeat重复i+1到length之间的值,为了防止下标越界
Handles.DrawLine(myHandles.nodePoints[i], myHandles.nodePoints[(int)Mathf.Repeat(i + 1, myHandles.nodePoints.Length)]);
Gizmos
public float areaRadius;
public float size;
public Vector3[] nodePoints;
/// <summary>
/// 场景的每一帧调用(在scene视图有操作时)
/// </summary>
private void OnDrawGizmos()
{
//绘制线框球体(中心点位置,半径大小)
Gizmos.DrawWireSphere(transform.position, areaRadius);
//设置颜色基本都是.color
Gizmos.color = Color.red;
//绘制线,从起点到指定位置绘制一条线(起点位置,指定的位置)
Gizmos.DrawLine(transform.position, transform.position + transform.forward * size);
Gizmos.color = Color.blue;
for(int i=0;i<nodePoints.Length;i++)
{
//绘制球体(中心点位置,球体半径)
Gizmos.DrawSphere(nodePoints[i], 0.5f);
}
for(int i=0;i<nodePoints.Length;i++)
{
Gizmos.DrawLine(nodePoints[i], nodePoints[(int)Mathf.Repeat(i + 1, nodePoints.Length)]);
}
//该API在Gizmos文件夹下查找,设置图标在该位置。
Gizmos.DrawIcon(transform.position, "timg.jpg");
}
/// <summary>
/// 点击附有该函数脚本的物体时调用
/// </summary>
private void OnDrawGizmosSelected()
{
Debug.Log("you click on me!");
}
Property Drawers
/*
* OnGUI和GetPropertyHeight里的property参数是同一个参数,参数里存放的是Persion里的属性信息
* OnGUI和GetPropertyHeight里的Label参数是同一个参数,参数里存放的是Persion类的类名
* OnGUI中的position指的是在Inspector面板该组件绘制的区域信息,(x,y)三角形的位置 w宽度 h高度
* */
[CustomPropertyDrawer(typeof(Persion))]//指定Persion类是用于自定义属性的绘制
public class PersionPropertiesDrawer : PropertyDrawer
{
Rect top, middleRight, middleLeft, bottom;//用于绘制指定的区域
/// <summary>
/// 获取对应的序列化属性
/// </summary>
SerializedProperty persionName, sex, age, description;
/// <summary>
/// 绘制属性
/// </summary>
/// <param name="position"></param>
/// <param name="property"></param>
/// <param name="label"></param>
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
//顶部区域
top = new Rect(position.x, position.y, position.width, position.height / 4.0f);
//左中部区域
middleLeft = new Rect(position.x, position.y + (position.height / 4.0f), position.width / 2.0f, position.height / 4.0f);
//右中部区域
middleRight = new Rect(position.x + position.width / 2.0f, position.y + (position.height / 4.0f), position.width / 2.0f, position.height / 4.0f);
//底部区域
bottom = new Rect(position.x, position.y + (position.height / 4.0f) * 2, position.width, (position.height / 4.0f) * 2);
//通过属性的名字获取对应的序列化属性
persionName = property.FindPropertyRelative("name");
sex = property.FindPropertyRelative("sex");
age = property.FindPropertyRelative("age");
description = property.FindPropertyRelative("description");
//绘制属性(绘制在Inspector面板的位置,需要绘制的序列化属性,属性的标签 default:null)
EditorGUI.PropertyField(top, persionName, label);
EditorGUI.PropertyField(middleLeft, sex);
EditorGUI.PropertyField(middleRight, age);
description.stringValue = EditorGUI.TextArea(bottom, description.stringValue);
}
/// <summary>
/// 绘制属性的高度
/// </summary>
/// <param name="property"></param>
/// <param name="label"></param>
/// <returns>抽象类中返回16f(在Inspector面板中的一行高度为16)</returns>
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
while(property.NextVisible(true))
{
Debug.Log("GetPropertyHeight:" + property.name);
}
return base.GetPropertyHeight(property, label)*4;
}
}
Property Attributes
SerializedProertyType:存放序列化属性的类型,使用该枚举为value获取对应类型的值,然后使用一个Label在Inspector面板中绘制出来
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
string value;
switch (property.propertyType)
{
case SerializedPropertyType.Integer:
value = property.intValue.ToString();
break;
case SerializedPropertyType.String:
value = property.stringValue;
break;
case SerializedPropertyType.Color:
value = property.colorValue.ToString();
break;
case SerializedPropertyType.Vector3:
value = property.vector3Value.ToString();
break;
case SerializedPropertyType.Rect:
value = property.rectValue.ToString();
break;
default:
throw new ArgumentOutOfRangeException();
}
//EditorGUI.LabelField(position, property.name + "\t\t:\t" + value);
ReadOnlyAttribute myAttribute = (ReadOnlyAttribute)attribute;
Debug.Log(attribute.GetType().Name);
GUI.color = myAttribute.textColor;
Debug.Log(property.name + ":" + myAttribute.textColor);
GUI.Label(position, property.displayName + "\t\t:\t" + value);
GUI.color = Color.white;
}
Decorator Drawers
/*
* 调用顺序:GetHeight在OnGUI之前
* */
[CustomPropertyDrawer(typeof(DrawerImageAttribute))]
public class DrawerImageAttributeDrawer : DecoratorDrawer//用于装饰的
{
private Texture2D image;
private DrawerImageAttribute _attribute=new DrawerImageAttribute();
public override void OnGUI(Rect position)
{
if(image==null)
{
image = Resources.Load<Texture2D>("Tim");
}
_attribute = (DrawerImageAttribute)attribute;
GUI.DrawTexture(position, image);
}
public override float GetHeight()
{
return base.GetHeight()+_attribute.height;
}
}