当前位置:   article > 正文

Unity编辑器控件的使用(—)_unity 重写 project 右键菜单

unity 重写 project 右键菜单

自动布局占空格
  • 在写编辑器的时候可能需要从右边开始,所以要用空格占满剩余空间
    在这里插入图片描述
  • 就可以使用GUILayout.flexibleSpace
设置自动布局控件的宽高
  • 例如GUILayout.TextField,它默认是没有宽度的,这时候我们就可以通过以下设定来设置
    在这里插入图片描述

  • 这些设置会重写style里面的宽高设定

  • GUILayout.Width用来设置控件宽度

  • GUILayout.Height用来设置空间高度

  • GUILayout.MinWidthGUILayout.MaxHeight设定该控件的最大宽度和最小宽度,当拖拽窗口进行缩放的时候,该控件会缩小到最小宽度后不再变化。GUILayout.MinHeight和GUILayout.MaxHeight也是同样的道理
    请添加图片描述

  • GUILayout.ExpandWidth是否允许控件进行水平方向的扩展,我测试了后发现,自动布局的所有控件默认是进行水平扩展的,因此会平分整个水平宽度

	GUILayout.BeginHorizontal();
		createFileName = GUILayout.TextField(createFileName);
		GUILayout.Button("新建"); //所有宽度平分
		GUILayout.Button("重命名");
		GUILayout.Button("复制");
		GUILayout.Button("删除");
		GUILayout.EndHorizontal();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

-在这里插入图片描述

  • 更改代码如下
	GUILayout.BeginHorizontal();
		createFileName = GUILayout.TextField(createFileName,GUILayout.ExpandWidth(true));//会占据所有剩余空间
		GUILayout.Button("新建",GUILayout.ExpandWidth(false));//按照style固有宽度渲染
		GUILayout.Button("重命名", GUILayout.ExpandWidth(false));
		GUILayout.Button("复制", GUILayout.ExpandWidth(false));
		GUILayout.Button("删除", GUILayout.ExpandWidth(false));
		GUILayout.EndHorizontal();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

在这里插入图片描述

打开文件的回调
  • 当我们双击某个asset文件时候,可以使用UnityEditor.Callbacks.OnOpenAsset(0)
  • 来打开窗口,代码如下
	[UnityEditor.Callbacks.OnOpenAsset(0)]
	static bool OpenAsset(int id, int line)
	{
		var obj = EditorUtility.InstanceIDToObject(id);
		if (obj.GetType() == typeof(UnitSettingObject))
		{
			OpenWindow();
			return true;
		}
		return false;
	}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

请添加图片描述

常用控件
  • 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
  • 这样就不会忘记结尾了
	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
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 具体使用
using (GUIScope.Horizontal.New (FlexibleTypes.Begin))
{
}
  • 1
  • 2
  • 3
SerializeObject
  • unity 推荐在自定义Editor中使用这个对象来编辑数据
  • 在绘制UI的时候EditorGUI.PropertyField(),传入SerializeProperty即可
  • 通过stages = serializedObject.FindProperty ("stages"); 可以查找到对应属性
  • 这个序列化对象相当于一个流,他可以用来对多个对象的编辑,他本身会处理Undo, prefab保存这些。
serializeObject.update();
//draw UI

serializedObject.ApplyModifiedProperties();
  • 1
  • 2
  • 3
  • 4
  • 可实际上用起来十分麻烦,代码量会增加一倍,而且用字符串的方法来索引属性,如果属性更改名字了要怎么办。
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窗口中显示
	private void OnDrawGizmos ()
	{
		foreach (var pos in allCube)
		{
			Gizmos.DrawCube (pos, Vector3.one);
		}
	}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
OnValidate
  • 在monobehaviour中,如果你在Inspector面板上修改了他的数据,那么就会被触发,经常用来校验数据
使用Gizmos选中场景物体
  • 我们可以看到Camera在Scene场景里面绘制了一个相机的小图标,而且可以用来选中,移动相机的Transform
  • 那么他是如何实现的呢?

public class PosEditCom : MonoBehaviour
{
}

public class PosEditComGizmoDrawer
{
	[DrawGizmo (GizmoType.Pickable|GizmoType.Selected|GizmoType.NonSelected)]
	static void DrawGizmoForMyScript (PosEditCom scr, GizmoType gizmoType)
	{
		Gizmos.DrawCube (scr.transform.position, Vector3.one);
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 只要给物体挂载上PosEditCom组件就可以实现绘制相应的Gizmos
自定义右键菜单menu
  • 参考链接自定义
  • unity自身有一个类是GenericMenu
  • 在Editor窗口中调用menu.ShowAsContext()就可以显示出来
  • menu.AddSeperator()添加分隔符
  • menu.AddItem()添加右键菜单的选项
  • 所以我们可以利用反射和特性来实现自定义的右键menu
关于EventType的使用
if (Event.current.type == EventType.MouseDown && Event.current.button == 1)
		{
			menu.ShowMenu ();
			Event.current.Use ();
		}
  • 1
  • 2
  • 3
  • 4
  • 5
重写Project 右键和Hierachy右键
  • Project右键其实是和Menu的Asset菜单一样的。
  • 而Hierachy的右键其实是和GameObject一样的
  • 所以我们要扩展的时候,只要给类的静态方法添加MenuItem("Assets/")
  • 如果要重写,则用到EditorApplication.projectWindowItemOnGUI+=OnProjectGUI
  • EditorApplication.hierarchyWindowItemOnGUI += OnHierarchyGUI;
  • 代码如下:

	[MenuItem ("Assets/TestMenu01/TestMenu04")]
	static void TestMenu04 ()
	{
		Debug.Log ("点击了TestMenu04");
	}

	[In
	itializeOnLoadMethod]
	static void StartInitializeOnLoadMethod ()
	{
		EditorApplication.hierarchyWindowItemOnGUI += OnHierarchyGUI;
	}
	
	static void OnHierarchyGUI (int instanceID, Rect selectionRect)
	{
		if (Event.current != null && selectionRect.Contains (Event.current.mousePosition)
			&& Event.current.button == 1 && Event.current.type <= EventType.MouseUp)
		{
			GameObject selectedGameObject = EditorUtility.InstanceIDToObject (instanceID) as GameObject;
			//这里可以判断selectedGameObject的条件
			if (selectedGameObject)
			{
				Vector2 mousePosition = Event.current.mousePosition;

				EditorUtility.DisplayPopupMenu (new Rect (mousePosition.x, mousePosition.y, 0, 0), "Window/Test", null);
				Event.current.Use ();
			}
		}
	}
  • 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
右键创建ScriptObject
[CreateAssetMenu (menuName = "xuhaitao/personInfo")]
public class shishi : ScriptableObject
{
	public string namee;
	public int age;
	public Image img;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
OnOpenAsset的使用
  • OnOpenAssetAttribute是一个特性
  • 当你双击某个asset文件的时候就会调用这个特性修饰的静态方法
 [OnOpenAssetAttribute(1)]
    public static bool step1(int instanceID, int line)
    {
        string name = EditorUtility.InstanceIDToObject(instanceID).name;
        Debug.Log("Open Asset step: 1 (" + name + ")");
        return false; // we did not handle the open
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/80326
推荐阅读
相关标签
  

闽ICP备14008679号