Unity Editor Window
EditorGUILayout:提供Unity内置类或结构体的布局组件,能够实现在Inspcctor和EditorWindow中自定义编辑器。
EditorGUILayout是对GUILayout的扩展,它主要用于Inspector和EditorWindow。
EditorGUI是Fixed排列,EditorGUILayout则是Automatic;
基本控件
所提供的控件多以Field为后缀,主要用于属性字段
1.数值输入控件
FloatFiled / IntFiled/ Vector2Field / Vector2IntField / Vector3Field / Vector3IntField / Vector4Field / RectField
float sizeMultiplier = EditorGUILayout.FloatField("Increase scale by:", sizeMultiplier);
滑动条:FloatSlider() / IntSlider():数值的输入
cloneTimesX = EditorGUILayout.IntSlider(cloneTimesX, 1, 10);
2.文本输入:String变量
TextArea / TextField / PasswordFiled
3.Lable
LabelField():显示只读信息
EditorGUILayout.LabelField("Time since start: ", EditorApplication.timeSinceStartup.ToString());
4.Toggle:Bool型变量
isFPSOpen = EditorGUILayout.Toggle("Is OpenFPS",isFPSOpen);
5.PropertyFiled()
用于自定义属性面板中,定义各个字段的布局;使用该函数就会根据属性来使用unity自动的布局;
EditorGUILayout.PropertyField(m_GameObjectProp, new GUIContent("Game Object"));
6.ObjectField()
支持unity提供的各种类型的对象
source = EditorGUILayout.ObjectField(source, typeof(Object), true)
7.一些类类型:Color、Curve等
ColorFiled / CurveFileld / TagFiled
8.其它常用类型
PasswordFiled /
组织控件
通常以Beginxxx()和Endxxx()形式成对出现,其代码包含的控件将被统一组织;
1.Group
将控件以分组形式排列(Group相当于一个Panel),当Group移动时,组内成员也会跟随;
BeginFadeGroup(float val) / EndFadeGroup() / BeginToggleGroup() / EndToggleGroup()
BeginFoldoutHeaderGroup(bool foldout,GUIContent,) / EndFoleoutHeaderGroup()
在EditorGUI中:BeginDisableGroup(bool) /
2.Horizontal / Vertical
管理控件的水平和竖直布局方式
3.ScrollView
管理滚动视图内的控件,BeginScrollView()和EndScrollView()
4.Space()
插入一个空行
具体用法:
标签 Label
GUILayout.Label("--------Label-------");
文本框 TextField
string myString = ""; myString = EditorGUILayout.TextField("TrackName", myString);
下拉列表 Popup
public string[] options = new string[] { "A", "B", "C", "D", }; public int m_trackIndex = 0; m_trackIndex = EditorGUILayout.Popup("TrackName", m_trackIndex,options);
按钮 Button
if (GUILayout.Button("搜索")) { Debug.Log("------Search click-------"); }
批量创建按钮
// for(int i = 0; i < resList.Count; i++) { // 创建按钮 if (GUILayout.Button(resList[i])) { // 根据文件名在Project下选中文件 Selection.activeObject = AssetDatabase.LoadAssetAtPath<GameObject>(m_path+resList[i]); } } // update foreach (var filename in resList) { if (GUILayout.Button(filename)) { Selection.activeObject = AssetDatabase.LoadAssetAtPath<GameObject>(m_path+filename); } }
进度条 Slider
float myFloat; myFloat = EditorGUILayout.Slider("Slider", myFloat, -3, 3);
文本区域
public string output = "A \n B \n"; EditorGUILayout.TextArea(output);
水平布局
Rect r = EditorGUILayout.BeginHorizontal("Button"); if (GUI.Button(r, GUIContent.none)) Debug.Log("Go here"); GUILayout.Label("I'm inside the button"); GUILayout.Label("So am I"); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); GUILayout.Label("第一个内容"); GUILayout.Label("第二个内容"); if (GUILayout.Button("第三个按钮")) { Debug.Log("GUILayout的按钮"); } EditorGUILayout.EndHorizontal();
垂直布局
EditorGUILayout.BeginVertical(); GUILayout.Label("第一个内容"); GUILayout.Label("第二个内容"); if (GUILayout.Button("第三个按钮")) { Debug.Log("GUILayout的按钮"); } EditorGUILayout.EndVertical();
选择区域 Toggle Group
bool groupEnabled; groupEnabled = EditorGUILayout.BeginToggleGroup("Optional Settings", groupEnabled); m_para = EditorGUILayout.TextField("参数", m_para); EditorGUILayout.EndToggleGroup();
折叠区域 Fold out
bool showFoldout; showFoldout = EditorGUILayout.Foldout(showFoldout, "折叠子物体:"); if (showFoldout) { // 缩进 EditorGUI.indentLevel++; EditorGUILayout.LabelField("A"); EditorGUI.indentLevel++; EditorGUILayout.LabelField("B"); EditorGUI.indentLevel--; EditorGUI.indentLevel--; EditorGUILayout.LabelField("C"); }
滚动区域 Scroll View
Vector2 scroll; scroll =EditorGUILayout.BeginScrollView(scroll); EditorGUILayout.EndScrollView();
分割线
// splitter float splitterWidth = 5; // vertical GUILayout.Box ("", GUILayout.Width(splitterWidth), GUILayout.MaxWidth (splitterWidth), GUILayout.MinWidth(splitterWidth), GUILayout.ExpandHeight(true)); // horizontal GUILayout.Box ("", GUILayout.Height(splitterWidth), GUILayout.Height (splitterWidth), GUILayout.Height(splitterWidth), GUILayout.ExpandWidth(true));
空行
EditorGUILayout.Space(); // GUILayout.FlexibleSpace();
Inspector 面板自定义 实例
1.基础类 -- 使用默认布局
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Player : MonoBehaviour { public int id; public string playerName; public string backStory; public float health; public float damage; public float weaponDamage1, weaponDamage2; public string shoeName; public int shoeSize; public string shoeType; void Start() { health = ; } }
2.编辑器扩展脚本 -- 自定义布局
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEditor; //CustomEditor(typeof()) 用于关联你要自定义的脚本 [CustomEditor(typeof(Player))] //必须要让该类继承自Editor,且不需要导入UnityEditor程序集 public class PlayerInspector : Editor { Player player; bool showWeapons; void OnEnable() { //获取当前编辑自定义Inspector的对象 player = (Player)target; } //执行这一个函数来一个自定义检视面板 public override void OnInspectorGUI() { //设置整个界面是以垂直方向来布局 EditorGUILayout.BeginVertical(); //空两行 EditorGUILayout.Space(); EditorGUILayout.Space(); //绘制palyer的基本信息 EditorGUILayout.LabelField("Base Info"); player.id = EditorGUILayout.IntField("Player ID", player.id); player.playerName = EditorGUILayout.TextField("PlayerName", player.playerName); //空三行 EditorGUILayout.Space(); EditorGUILayout.Space(); EditorGUILayout.Space(); //绘制Player的背景故事 EditorGUILayout.LabelField("Back Story"); player.backStory = EditorGUILayout.TextArea(player.backStory, GUILayout.MinHeight()); //空三行 EditorGUILayout.Space(); EditorGUILayout.Space(); EditorGUILayout.Space(); //使用滑块绘制 Player 生命值 player.health = EditorGUILayout.Slider("Health", player.health, , ); //根据生命值设置生命条的背景颜色 if (player.health < ) { GUI.color = Color.red; } else if (player.health > ) { GUI.color = Color.green; } else { GUI.color = Color.gray; } //指定生命值的宽高 Rect progressRect = GUILayoutUtility.GetRect(, ); //绘制生命条 EditorGUI.ProgressBar(progressRect, player.health / 100.0f, "Health"); //用此处理,以防上面的颜色变化会影响到下面的颜色变化 GUI.color = Color.white; //空三行 EditorGUILayout.Space(); EditorGUILayout.Space(); EditorGUILayout.Space(); //使用滑块绘制伤害值 player.damage = EditorGUILayout.Slider("Damage", player.damage, , ); //根据伤害值的大小设置显示的类型和提示语 if (player.damage < ) { EditorGUILayout.HelpBox("伤害太低了吧!!", MessageType.Error); } else if (player.damage > ) { EditorGUILayout.HelpBox("伤害有点高啊!!", MessageType.Warning); } else { EditorGUILayout.HelpBox("伤害适中!!", MessageType.Info); } //空三行 EditorGUILayout.Space(); EditorGUILayout.Space(); EditorGUILayout.Space(); //设置内容折叠 showWeapons = EditorGUILayout.Foldout(showWeapons, "Weapons"); if (showWeapons) { player.weaponDamage1 = EditorGUILayout.FloatField("Weapon 1 Damage", player.weaponDamage1); player.weaponDamage2 = EditorGUILayout.FloatField("Weapon 2 Damage", player.weaponDamage2); } //空三行 EditorGUILayout.Space(); EditorGUILayout.Space(); EditorGUILayout.Space(); //绘制鞋子信息 EditorGUILayout.LabelField("Shoe"); //以水平方向绘制 EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Name", GUILayout.MaxWidth()); player.shoeName = EditorGUILayout.TextField(player.shoeName); EditorGUILayout.LabelField("Size", GUILayout.MaxWidth()); player.shoeSize = EditorGUILayout.IntField(player.shoeSize); EditorGUILayout.LabelField("Type", GUILayout.MaxWidth()); player.shoeType = EditorGUILayout.TextField(player.shoeType); EditorGUILayout.EndHorizontal(); EditorGUILayout.EndVertical(); } }
Gui 实例
拖动调节分割线
public class GUISplitter: EditorWindow { Vector2 posLeft; Vector2 posRight; GUIStyle styleLeftView; GUIStyle styleRightView; float splitterPos; Rect splitterRect; Vector2 dragStartPos; bool dragging; float splitterWidth = 5; // Add menu named "My Window" to the Window menu [MenuItem ("GUI/GUISplitter")] static void Init () { GUISplitter window = (GUISplitter)EditorWindow.GetWindow ( typeof (GUISplitter)); window.position = new Rect(200, 200, 200,200); window.splitterPos = 100; } void OnGUI (){ if (styleLeftView == null) styleLeftView = new GUIStyle(GUI.skin.box); if (styleRightView == null) styleRightView = new GUIStyle(GUI.skin.button); GUILayout.BeginHorizontal (); // Left view posLeft = GUILayout.BeginScrollView (posLeft, GUILayout.Width (splitterPos), GUILayout.MaxWidth(splitterPos), GUILayout.MinWidth(splitterPos)); GUILayout.Box ("Left View", styleLeftView, GUILayout.ExpandWidth(true), GUILayout.ExpandHeight(true)); GUILayout.EndScrollView (); // Splitter GUILayout.Box ("", GUILayout.Width(splitterWidth), GUILayout.MaxWidth (splitterWidth), GUILayout.MinWidth(splitterWidth), GUILayout.ExpandHeight(true)); splitterRect = GUILayoutUtility.GetLastRect (); // Right view posRight = GUILayout.BeginScrollView (posRight, GUILayout.ExpandWidth(true)); GUILayout.Box ("Right View", styleRightView, GUILayout.ExpandWidth(true), GUILayout.ExpandHeight(true)); GUILayout.EndScrollView (); GUILayout.EndHorizontal (); // Splitter events if (Event.current != null) { // rawType 可以在屏幕外运行 switch (Event.current.rawType) { case EventType.MouseDown: if (splitterRect.Contains (Event.current.mousePosition)) { Debug.Log ("Start dragging"); dragging = true; } break; case EventType.MouseDrag: if (dragging){ Debug.Log ("moving splitter"); splitterPos += Event.current.delta.x; Repaint (); } break; case EventType.MouseUp: if (dragging){ Debug.Log ("Done dragging"); dragging = false; } break; } } }
参考资料
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)