当前位置:   article > 正文

拓展自定义编辑器窗口(EditorGUILayout类)_editorguilayout.objectfield

editorguilayout.objectfield

对于编辑器中的GUI系统,我们可以分为四大类: 

1、UnityEngine.GUI 

2、UnityEngine.GUILayout (最常用) 

3、UnityEditor.EditorGUI 

4、UnityEditor.EditorGUILayout

 

Unity支持自行创建窗口,也支持自定义窗口布局。 

EditorGUILayout类是带自动布局的EditorGUI系统,所属命名空间UnityEditor,用其绘制的所有控件都带有自动布局效果,跟GUILayout系统的差别是其拥有部分编辑器专用控件,且其只能运行在编辑器内,自适应性较强,但开发自由度较低。

注意:EditorGUILayout系统不可以在发布后使用,只能在编辑器中使用

在Project视图中创建一个Editor文件夹,在文件夹中再创建一条脚本。

自定义窗口需要让脚本继承EditorWindow再设置MenuItem,此时在Unity导航菜单栏中GameObjec->window就可创建一个自定义窗口。

0.窗口:

 

  1. using UnityEngine;
  2. using UnityEditor; //引入编辑器命名空间
  3. public class MyEditor:EditorWindow
  4. {
  5. [MenuItem("GameObject/caymanwindow")]
  6. static void AddWindow()
  7. {
  8. //创建窗口
  9. Rect wr = newRect(0,0,500,500);
  10. //另一种方式:myEditor window = (myEditor)EditorWindow.GetWindow(typeof(myEditor), true, "cayman");
  11. MyEditor window = (MyEditor)EditorWindow.GetWindowWithRect(typeof(MyEditor),wr,true,"widow name");
  12. window.Show();
  13. }
  14. //[MenuItem("GameObject/caymanwindow", true)] //如果没有选择物体,禁用菜单
  15. //static bool ValidateSelection()
  16. //{
  17. // return Selection.activeGameObject != null;
  18. //}
  19. }

 

1.LabelField制作一个标签字段(通常用于显示只读信息)

LabelField(string label1,string label2,GUILayoutOption[] options)

//参数:label1标签字段前面的标签  label2显示在右侧的标签  options额外布局属性可选列表  --无返回值

1

2

3

4

5

6

7

8

9

10

11

12

13

14

public class myEditor3 :EditorWindow{

//在编辑器显示一个标签,带有自编辑器开始的秒数

[MenuItem("cayman/tempShow")]

static void newWelcome()

{

myEditor3 window3 =(myEditor3)EditorWindow.GetWindow(typeof(myEditor3),true,"Eam");

window3.Show();

}

voidOnGUI()

{

EditorGUILayout.LabelField("Time since start: ",EditorApplication.timeSinceStartup.ToString());

this.Repaint();//实时刷新

}

}

  

效果:

 

2.Toggle开关按钮

Toggle(bool value,GUILayoutOption[] options)

Toggle(string label,bool value,GUILayoutOption[] options)

//参数:label开关按钮前面的可选标签  value开关按钮的显示状态 options额外布局属性的可选列表  

//返回:bool,开关按钮的选择状态

复制代码

  1. //如果开关控件被选择,显示一个按钮。
  2. bool showBtn =true;
  3. voidOnGUI()
  4. {
  5. showBtn =EditorGUILayout.Toggle("Show Button", showBtn);
  6. if(showBtn)
  7. {
  8. if(GUILayout.Button("Close"))
  9. this.Close();
  10. }
  11. }

复制代码

 

效果:

 

3.TextField文本字段

TextField(string text,GUILayoutOption[] options)                                 TextField(string label,string text,GUIStyle style,GUILayoutOption[] options)

TextField(string text,GUIStyle style,GUILayoutOption[] options)           TextField(GUIContent label,string text,GUILayoutOption[] options)

TextField(string label,string text,GUILayoutOption[] options)                TextField(GUIContent label,string text,GUIStyle style,GUILayoutOption[] options)

//参数:label可选标签  text编辑的文本  style可选样式  options额外布局属性的可选列表

//返回:string,用户输入的文本

复制代码

  1. //通过字段,自动改变选择物体的名字
  2. string objectName ="";
  3. voidOnGUI()
  4. {
  5. GUILayout.Label("Select an object in the hierarchy view");
  6. if(Selection.activeGameObject)
  7. Selection.activeGameObject.name =EditorGUILayout.TextField("Object Name: ",Selection.activeGameObject.name);
  8. this.Repaint();//实时刷新
  9. }
  10. }

复制代码

效果:

 

4.TextArea文本区域

TextArea(string text,GUILayoutOption[] options)

TextArea(string text,GUIStyle style,GUILayoutOption[] options)

//参数:text可编辑的文本  style可选样式 options额外布局属性的可选列表

//返回:string,用户输入的文本

复制代码

  1. //在编辑器窗口可视化脚本,这可扩展保存脚本
  2. string text ="Nothing Opened...";
  3. TextAsset txtAsset;
  4. Vector2 scroll;
  5. voidOnGUI()
  6. {
  7. TextAsset newTxtAsset =EditorGUILayout.ObjectField("添加", txtAsset,typeof(TextAsset),true)asTextAsset;
  8. if(newTxtAsset != txtAsset)
  9. ReadTextAsset(newTxtAsset);
  10. scroll =EditorGUILayout.BeginScrollView(scroll);
  11. text =EditorGUILayout.TextArea(text,GUILayout.Height(position.height -30));
  12. EditorGUILayout.EndScrollView();
  13. }
  14. voidReadTextAsset(TextAsset txt){
  15. text = txt.text;
  16. txtAsset = txt;
  17. }
  18. }

复制代码

 

效果:

 

5.SelectableLabel 可选择标签(通常用于显示只读信息,可以被复制粘贴)

SelectableLabel(string text,GUILayoutOption[] options)

SelectableLabel(string text,GUIStyle style,GUILayoutOption[] options)

//参数:text显示的文本 style可选样式 options额外布局属性的可选列表   无返回值

  1. string text="123";
  2. voidOnGUI()
  3. {
  4. EditorGUILayout.SelectableLabel(text); //文本:可以选择然后复制粘贴
  5. }

 

6.PasswordField 密码字段

PasswordField (string password, GUILayoutOption[] options)    PasswordField (string password,GUIStyle style, GUILayoutOption[] options)

PasswordField (string label,string password,GUILayoutOption[] options)    PasswordField (string password,GUIStyle style,GUILayoutOption[] options)

PasswordField (GUIContent label,string password, GUILayoutOption[] options)    PasswordField (GUIContent label,string password,GUIStyle style,GUILayoutOption[] options)

//参数:label开关按钮前面的可选标签  password编辑的密码  style可选样式   options指定额外布局属性的可选列表

//返回:string,用户输入的密码

 

复制代码

  1. //创建密码字段并可视化在密码字段有什么键入。
  2. string text ="Some text here";
  3. function OnGUI(){
  4. text =EditorGUILayout.PasswordField("Type Something:",text);
  5. EditorGUILayout.LabelField("Written Text:", text);
  6. }
  7. }

复制代码

 

效果:

 

7.制作一个文本字段用于输入小数/整数。

FloatField 浮点数字段:返回小数,由用户输入的值

 IntField   整数字段:返回整数,由用户输入的值

1

2

3

4

5

6

7

8

int clones=1;

voidOnGUI(){

clones=EditorGUILayout.IntField("Number of clones:", clones);

if(GUILayout.Button("Clone!"))

for(var i =0; i < clones; i++)//复制选择物体的次数。

Instantiate(Selection.activeGameObject,Vector3.zero,Quaternion.identity);

}

}

  

 

8.Slider 滑动条

--IntSlider 整数滑动条

MinMaxSlider 最小最大滑动条

Slider(float leftValue,float rightValue,GUILayoutOption[] options)

Slider(string label,float leftValue,float rightValue,GUILayoutOption[] options)

Slider(GUIContent label,float value,float leftValue,float rightValue,GUILayoutOption[] options)

//参数:label开关按钮前的可选标签  value编辑的值  leftValue滑动条最左边的值  rightValue滑动条最右边的值  options。。。

//返回:float,由用户设置的值

1

2

3

4

5

6

7

8

9

10

11

//缩放选择的游戏物体,在1-100之间

float scale =0.0f;

voidOnGUI()

{

scale =EditorGUILayout.Slider(scale,1,100);

}

voidOnInspectorUpdate()

{

if(Selection.activeTransform)

Selection.activeTransform.localScale =newVector3(scale, scale, scale);

}

  

复制代码

  1. //随机放置选择的物体在最小最大滑动条之间
  2. float minVal =-10.0f;
  3. float minLimit =-20.0f;
  4. float maxVal =10.0f;
  5. float maxLimit =20.0f;
  6. voidOnGUI()
  7. {
  8. EditorGUILayout.LabelField("Min Val:", minVal.ToString());
  9. EditorGUILayout.LabelField("Max Val:", maxVal.ToString());
  10. EditorGUILayout.MinMaxSlider(ref minVal,ref maxVal, minLimit, maxLimit);
  11. if(GUILayout.Button("Move!"))
  12. PlaceRandomly();
  13. }
  14. voidPlaceRandomly()
  15. {
  16. if(Selection.activeTransform)
  17. Selection.activeTransform.position =
  18. newVector3(Random.Range(minVal, maxVal),
  19. Random.Range(minVal, maxVal),
  20. Random.Range(minVal, maxVal));
  21. else
  22. Debug.LogError("Select a GameObject to randomize its position.");
  23. }

复制代码

 

效果:  

 

9.Popup弹出选择菜单

Popup(int selectedIndex,string[] displayOptions,GUILayoutOption[] paroptions)                          Popup(int selectedIndex,string[] displayOptions,GUIStyle style,GUILayoutOption[] paroptions)

Popup(string label,int selectedIndex,string[] displayOptions,GUILayoutOption[] paroptions)         Popup(GUIContent label,int selectedIndex,string[] displayOptions,GUILayoutOption[] paroptions)。。。。

//参数:label字段前面可选标签  selectedIndex字段选项的索引  displayedOptions弹出菜单选项的数组  style可选样式 options。。

//返回:int,用户选择的选项索引

复制代码

  1. string[] options ={"Cube","Sphere","Plane"};
  2. int index =0;
  3. voidOnGUI()
  4. {
  5. index =EditorGUILayout.Popup(index, options);
  6. if(GUILayout.Button("Create"))
  7. InstantiatePrimitive();
  8. }
  9. voidInstantiatePrimitive(){
  10. switch(index){
  11. case0:
  12. GameObject cube=GameObject.CreatePrimitive(PrimitiveType.Cube);
  13. cube.transform.position =Vector3.zero;
  14. break;
  15. case1:
  16. GameObject sphere=GameObject.CreatePrimitive(PrimitiveType.Sphere);
  17. sphere.transform.position =Vector3.zero;
  18. break;
  19. case2:
  20. GameObject plane=GameObject.CreatePrimitive(PrimitiveType.Plane);
  21. plane.transform.position =Vector3.zero;
  22. break;
  23. default:
  24. Debug.LogError("Unrecognized Option");
  25. break;
  26. }
  27. }
  28. }

复制代码

 

效果:

 

10.EnumPopup 枚举弹出选择菜单(效果同上)

//返回System.Enum,用户选择的枚举选项。

复制代码

  1. enum OPTIONS
  2. {
  3. CUBE =0,
  4. SPHERE =1,
  5. PLANE =2
  6. }
  7. publicclass myEditor3 :EditorWindow{
  8. OPTIONS op=OPTIONS.CUBE;
  9. [MenuItem("cayman/tempShow")]
  10. staticvoid newWelcome()
  11. {
  12. myEditor3 window3 =(myEditor3)EditorWindow.GetWindow(typeof(myEditor3),true,"Eam");
  13. window3.Show();
  14. }
  15. voidOnGUI()
  16. {
  17. op =(OPTIONS)EditorGUILayout.EnumPopup("Primitive to create:", op);
  18. }
  19. }

复制代码

 

 

11.IntPopup 整数弹出选择菜单

IntPopup(string label,int selectedValue,string[] displayOptions,int[] optionValues,GUIStyle style,GUILayoutOption[] paramsOptions).....

//参数:label字段前面的可选标签  selectedValue字段选项的索引 displayOptions弹出菜单項数组 optionValues每个选项带有值的数组。。

//返回:int,用户选择的选项的值

复制代码

  1. int selectedSize =1;
  2. string[] names ={"Normal","Double","Quadruple"};
  3. int[] sizes ={1,2,4};
  4. voidOnGUI()
  5. {
  6. selectedSize =EditorGUILayout.IntPopup("Resize Scale: ", selectedSize, names, sizes);
  7. if(GUILayout.Button("Scale"))
  8. ReScale();
  9. }
  10. voidReScale()
  11. {
  12. if(Selection.activeTransform)
  13. Selection.activeTransform.localScale =newVector3(selectedSize, selectedSize, selectedSize);
  14. elseDebug.LogError("No Object selected, please select an object to scale.");
  15. }

复制代码

 

效果:

 

12.TagField 标签字段   LayerField层字段

1/ TagField(string label,string tag,GUIStyle style,GUILayoutOption[] paramsOptions)...

//参数:label字段前面的可选标签  tag显示字段的标签 。。

//返回:string,用户选择的标签

2/ LayerField(string label,int layer,GUIStyle style,GUILayoutOption[] paramsOptions)...

参数:label字段前面的可选标签 layer显示在该字段的层。。

//返回:int,用户选择的层

复制代码

  1. string tagStr ="";
  2. int selectedLayer=0;
  3. voidOnGUI()
  4. { //为游戏物体设置
  5. tagStr =EditorGUILayout.TagField("Tag for Objects:", tagStr);
  6. if(GUILayout.Button("Set Tag!"))
  7. SetTags();
  8. if(GUILayout.Button("Set Layer!"))
  9. SetLayer();
  10. }
  11. voidSetTags(){
  12. foreach(GameObject go inSelection.gameObjects)
  13. go.tag = tagStr;
  14. }
  15. voidSetLayer(){
  16. foreach(GameObject go inSelection.gameObjects)
  17. go.laye= tagStr;
  18. }

复制代码

 

效果:

 

13.ObjectField 物体字段(拖拽物体或拾取器选择物体)

ObjectField(string label,Object obj,Type objType,bool allowSceneObjects,GUILayoutOption[] paramsOptions)

//label字段前面的可选标签   obj字段显示的物体   objType物体的类型    allowSceneObjects允许指定场景物体..

//返回:Object,用户设置的物体

复制代码

  1. Object source;
  2. Texture myme;
  3. voidOnGUI()
  4. {
  5. EditorGUILayout.BeginHorizontal();
  6. source =EditorGUILayout.ObjectField("hiahia",source,typeof(Object));
  7. myme= (Texture)EditorGUILayout.ObjectField("hehe",myme,typeof(Texture));//注意类型转换
  8. EditorGUILayout.EndHorizontal();
  9. }

复制代码

效果:

 

14.Vector2Field 二维向量字段  Vector3Field 三维向量字段(略,同2维)

Vector2Field (string label,Vector2 value,GUILayoutOption[] options)

//参数:label字段前面的可选标签  value编辑的值  options...

//返回:Vector2,由用户输入的值

复制代码

  1. float distance =0;
  2. Vector2 p1, p2;
  3. voidOnGUI()
  4. {
  5. p1 =EditorGUILayout.Vector2Field("Point 1:", p1);
  6. p2 =EditorGUILayout.Vector2Field("Point 2:", p2);
  7. EditorGUILayout.LabelField("Distance:", distance.ToString());
  8. }
  9. voidOnInspectorUpdate()//面板刷新
  10. {
  11. distance =Vector2.Distance(p1, p2);
  12. this.Repaint();
  13. }

复制代码

 

效果:

 

15.ColorField 颜色字段

ColorField (string label,Color value,...)

//参数:label字段前面的可选标签  value编辑的值

//返回:Color,由用户输入的值

复制代码

  1. Color matColor =Color.white;
  2. voidOnGUI()
  3. {
  4. matColor =EditorGUILayout.ColorField("New Color", matColor);
  5. if(GUILayout.Button("Change!"))
  6. ChangeColors();
  7. }
  8. voidChangeColors(){
  9. if(Selection.activeGameObject)
  10. foreach(var t inSelection.gameObjects)
  11. if(t.GetComponent<Renderer>())
  12. t.GetComponent<Renderer>().sharedMaterial.color = matColor;
  13. }

复制代码

 

效果:

 

16.

 

 

EditorWindow.GetWindowWithRect() 和 EditorWindow.GetWindow()都可以创建一个窗口。前者可以规定窗口的区域,后者可通过鼠标动态的延伸窗口。参数1表示窗口的对象,参数2表示窗口的区域,参数3表示窗口类型true表示窗口不会被别的窗口覆盖,参数4表示窗口的名称。

  1. using UnityEngine;
  2. using UnityEditor;
  3. publicclassMyEditor:EditorWindow
  4. {
  5.  
  6. [MenuItem("GameObject/caymanwindow")]
  7. staticvoidAddWindow()
  8. {
  9. //创建窗口
  10. Rect wr =newRect(0,0,500,500);
  11. MyEditor window =(MyEditor)EditorWindow.GetWindowWithRect(typeof(MyEditor),wr,true,"widown name");
  12. window.Show();
  13. }
  14.  
  15. //输入文字的内容
  16. privatestring text;
  17. //选择贴图的对象
  18. privateTexture texture;
  19. float myFloat =1.23f;
  20. private bool kaiguan;//开关
  21. private bool groupEnabled;//区域开关
  22.  
  23. publicvoidAwake()
  24. {
  25. //在资源中读取一张贴图
  26. texture =Resources.Load("1")asTexture;
  27. }
  28.  
  29. //绘制窗口时调用
  30. voidOnGUI()
  31. {
  32. //输入框控件
  33. text =EditorGUILayout.TextField("输入文字:",text);//3.制作一个文本字段
  34.  
  35. if(GUILayout.Button("打开通知",GUILayout.Width(200)))
  36. {
  37. //打开一个通知栏
  38. this.ShowNotification(newGUIContent("This is a Notification"));
  39. }
  40.  
  41. if(GUILayout.Button("关闭通知",GUILayout.Width(200)))
  42. {
  43. //关闭通知栏
  44. this.RemoveNotification();
  45. }
  46.  
  47. //文本框显示鼠标在窗口的位置
  48. EditorGUILayout.LabelField("鼠标在窗口的位置",Event.current.mousePosition.ToString());//1.制作一个标签字段(通常用于显示只读信息)
  49. showBtn = EditorGUILayout.Toggle("开关", showBtn);

     

            groupEnabled = EditorGUILayout.BeginToggleGroup("Optional Settings", groupEnabled);

            text21 = EditorGUILayout.TextField("请输入帐号:", text21);

            text3 = EditorGUILayout.PasswordField("请输入密码",text3); //密码输入

            if (GUILayout.Button("登录", GUILayout.Width(400)))

            {

                //

            }

            int01 = EditorGUILayout.IntField("输入实例化份数:",int01);

            if (GUILayout.Button("实例化"))   //根据份数,实例化选择的物体

            {

                for (int i = 0; i < int01; i++)

                {

                    Instantiate(Selection.activeGameObject,Vector3.zero,Quaternion.identity);

                }

            }

     

            EditorGUILayout.EndToggleGroup();

            scale1 = EditorGUILayout.Slider(scale1,1,100); //滑动条

            index = EditorGUILayout.Popup(index,options); //弹出选择菜单

            if(GUILayout.Button("创建一个")){

                switch (index)

                {

                    case 0:

                        GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube);

                        cube.transform.position = Vector3.zero;

                        break;

                    case 1:

                        GameObject sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere);

                        sphere.transform.position = Vector3.zero;

                        break;

                    case 2:

                        GameObject plane = GameObject.CreatePrimitive(PrimitiveType.Plane);

                        plane.transform.position = Vector3.zero;

                        break;

                    default:

                        break;

                }

            }

     

            showPosition = EditorGUILayout.Foldout(showPosition, status);     //制作一个左侧带有箭头的折叠标签

            if (showPosition)

            {

                if (Selection.activeTransform)

                {

                    Selection.activeTransform.position =

                        EditorGUILayout.Vector3Field("Position", Selection.activeTransform.position);

                    status = Selection.activeTransform.name;

                }

     

                if (!Selection.activeTransform)

                {

                    status = "Select a GameObject";

                    showPosition = false;

                }

            }

  50.  
  51. //选择贴图
  52. texture =EditorGUILayout.ObjectField("添加贴图",texture,typeof(Texture),true)asTexture;
  53.  
  54. groupEnabled =EditorGUILayout.BeginToggleGroup("Optional Settings", groupEnabled);//起始----------------------------
  55. //这里放开关区域内内容
  56. myFloat =EditorGUILayout.Slider("Slider", myFloat,-3,3);//滑动条
  57. kaiguan=EditorGUILayout.Toggle("开关", kaiguan);//2.开关
  58.  
  59. EditorGUILayout.EndToggleGroup();//结束-------------------------------------
  60.  
  61. if(GUILayout.Button("关闭窗口",GUILayout.Width(200)))
  62. {
  63. //关闭窗口
  64. this.Close();
  65. }
  66.  
  67. }
  68.  
  69.  
  70.  
  71.  
  72.  
  73.  
  74. voidOnFocus()
  75. {
  76. Debug.Log("当窗口获得焦点时调用一次");
  77. }
  78.  
  79. voidOnLostFocus()
  80. {
  81. Debug.Log("当窗口丢失焦点时调用一次");
  82. }
  83.  
  84. voidOnHierarchyChange()
  85. {
  86. Debug.Log("当Hierarchy视图中的任何对象发生改变时调用一次");
  87. }
  88.  
  89. voidOnProjectChange()
  90. {
  91. Debug.Log("当Project视图中的资源发生改变时调用一次");
  92. }
  93.  
  94. voidOnInspectorUpdate()//实时刷新面板
  95. {
  96. //Debug.Log("窗口面板的更新");
  97. //这里开启窗口的重绘,不然窗口信息不会刷新
  98. this.Repaint();
  99. }
  100.  
  101. voidOnSelectionChange()
  102. {
  103. //当窗口出去开启状态,并且在Hierarchy视图中选择某游戏对象时调用
  104. foreach(Transform t inSelection.transforms)
  105. {
  106. //有可能是多选,这里开启一个循环打印选中游戏对象的名称
  107. Debug.Log("OnSelectionChange"+ t.name);
  108. }
  109. }
  110.  
  111. voidOnDestroy()
  112. {
  113. Debug.Log("当窗口关闭时调用");
  114. }
  115. }
  116.  
  117.  
  118. //http://www.ceeger.com/Script/EditorGUILayout/EditorGUILayout.html

 

然后我们在扩充一下自定义窗口,仔细看看窗口的生命周期。

  1.  

 

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/92941
推荐阅读
  

闽ICP备14008679号