Unity3D Editor 扩展细节

作者: 小小小小小丶敏 | 来源:发表于2017-09-27 11:56 被阅读19次

    1.首先来个Inspector面板Editor的实现
    要实现一个组件在Inspector中的Editor功能,首先需要写一个编辑器类:


    要点
    1.继承Editor
    2.放在Editor文件夹中
    3.在类的头部写[CustomEditor(typeof(你要实现编辑的组件的类名))]
    4.复写OnInspectorGUI函数(此函数仅在Inspector刷新时自动调用),然后在函数里实现编辑器功能的拓展实现。例如GUILayout.Label("Hello World");
    5.通过target as ‘你的类名’ 来实现引用你要扩展的组件的类的具体对象。

    2.GUILayoutOption
    EditorGUILayout 与 EditorGUI功能基本差不多,它是EditorGUI的自动布局版本,用它可以快速创建默认UI,若要自定义UI样式,应该使用EditorGUI并传入GUIStyle等参数
    GUILayoutOption是一种GUI布局方式的设置,常在GUILayout的具体控件中看到,
    例如,


    的最后一个参数便是一些GUILayoutOption不定参,表示可以有多个设置方案。
    注意:GUILayoutOption只是表示是设置方案的意思,并不是代表有GUILayoutOption这种设置方法,GUILayoutOption其实是个空类,
    具体的设置方案由具体决定。
    例如:
    GUILayout.Label("Hello World"), EditorStyles.helpBox);
    GUILayout.Label("Hello World")表示在面板上显示一条内容为“Hello World”的Label,(下图第一条)
    而EditorStyles.helpBox则表示此Label的显示方式是以帮助框的形式显示(下图第二条)

    更多的GUILayoutOption:

    EditorStyles.boldLabel
    EditorStyles.centeredGreyMiniLabel
    EditorStyles.radioButton
    EditorStyles.whiteBoldLabel

    3.GUILayout 之 SelectionGrid
    设置一个网格按钮,并返回按钮的序号。
    string[] text = { "1", "2", "3", "4" };Debug.Log(GUILayout.SelectionGrid(-1, text, 2) + " has been choose.");
    按钮可以是文字(上面的1,2,3,4四个按钮),也可以是图片等。
    第一参数的-1表示按钮哪个被按下,如果为0,则表示第一按钮显示为被按下,-1表示没有。
    第三个参数的2表示此网格分为2列,具体如图:

    4.折页
    首先用这句:
    showState = EditorGUILayout.Foldout(showState, "State List"); 参数分别为是否打开,显示标签的名字
    其实折页就相当于一个toggle按钮,并不做任何事,只是你按下它,它会返回一个是否折开或者合并的结果,
    然后自己再根据这个结果显示对应内容来达到折页效果。

    if (showState){  GUILayout.Label("内容", EditorStyles.inspectorDefaultMargins);}
    // 为了模拟折页后的子层级的树状缩进结构,我门用EditorStyles.inspectorDefaultMargins这中设置来将内容向右缩进。
    

    5.自定义自己的GUIStyle
    在2中我们知道了如何用GUIStyle扩展GUILayout的各种控件的样式,但我们用的都是EditorStyles附带的风格,
    这个EditorStyles是系统用的,我们只能用里面的风格,不能修改(其实也可以改,但改后会将系统其他所以使用该风格的地方都改)。
    为了定制我们自己的风格,其实我们可以自己创建一个GUIStyle。

    GUIStyle topStyle = new GUIStyle(EditorStyles.centeredGreyMiniLabel);  // 这里我用EditorStyles的centeredGreyMiniLabel来初始化我的新风格
    topStyle.fontStyle = FontStyle.Bold;                       // 新Style的字体为粗体
    topStyle.fontSize = 20;
    topStyle.richText = true;                              // 允许富文本
    

    6.再来个Scene面板的Editor实现
    基本与Inspector面板Editor的写法一样,只不过Scene面板的更新函数是OnSceneGUI,与之对应的是
    Inspector面板的更新函数OnInspectorGUI。
    甚至可以在同一个脚本里同时实现Inspector与Scene面板的Editor功能。
    要点:
    1.在OnSceneGUI()中只能通过Handles来绘制新视图,如果你想引入GUI的元素哪么就需要使用BeginGUI()和EndGUI()组合的使用。
    2.同Inspector一样,仅在持有该脚本的对象被选择时才激活。

    void OnSceneGUI() 
    {
      //得到test脚本的对象
      Test test = (Test) target;
      //在Scene视图中,在该对象本身的位置画一个坐标轴,但画自身坐标轴的意义不大,因为自身坐标轴在被选中时本来就会画出来。但可以用来显示其他对象的坐标轴。
      Handles.PositionHandle(fsm.test.transform.position, Quaternion.identity);
      //在场景中GameObject所在的位置绘制文本框,内容为该GO的坐标
      Handles.Label(test.transform.position + Vector3.up*2, test.transform.name +" : "+ test.transform.position.ToString() );
      //开始绘制GUI
      Handles.BeginGUI();
      //规定GUI显示区域
      GUILayout.BeginArea(new Rect(100, 100, 100, 100));
      //GUI绘制一个按钮
      if(GUILayout.Button("这是一个按钮!"))
          Debug.Log("test");
      //GUI绘制文本框
      GUILayout.Label("我在编辑Scene视图");    
      GUILayout.EndArea();
      Handles.EndGUI();
     }
    

    7.利用Gizmos在Editor里绘制图形
    Gizmos是常见的DebugDraw方式之一,可方便地在Editor里绘制线段,射线,方块之类的
    用法:Gizmos只能用于OnDrawGizmos函数里,该函数跟Start,Update一样会自动调用


    但是一般情况下,绘制函数里的参数只有'center','size'之类的,绘制出来的图形是没有角度的,
    如果有需要绘制旋转过的图形,例如一个跟随摄影机旋转的Cube

    那么就需要利用Gizmos的重要参数——matirx,
    这是Gimos的绘制矩阵,绘制的图形信息在这里,要缩放,旋转Gizmos绘制出来的图形,
    只需要改变矩阵即可。
    void OnSceneGUI() 
    {
      //得到test脚本的对象
      Test test = (Test) target;
      //在Scene视图中,在该对象本身的位置画一个坐标轴,但画自身坐标轴的意义不大,因为自身坐标轴在被选中时本来就会画出来。但可以用来显示其他对象的坐标轴。
      Handles.PositionHandle(fsm.test.transform.position, Quaternion.identity);
      //在场景中GameObject所在的位置绘制文本框,内容为该GO的坐标
      Handles.Label(test.transform.position + Vector3.up*2, test.transform.name +" : "+ test.transform.position.ToString() );
      //开始绘制GUI
      Handles.BeginGUI();
      //规定GUI显示区域
      GUILayout.BeginArea(new Rect(100, 100, 100, 100));
      //GUI绘制一个按钮
      if(GUILayout.Button("这是一个按钮!"))
          Debug.Log("test");
      //GUI绘制文本框
      GUILayout.Label("我在编辑Scene视图");    
      GUILayout.EndArea();
      Handles.EndGUI();
     }
    

    8.Editor菜单栏快捷键



    %代表 Ctrl

    代表 Shift

    9.手动将Scene标志为“修改过的”
    有时候会动态在Editor脚本里创建对象在Scene里,但是动态创建之后Scene默认是认为场景没被修改过的,
    这个时候是没法保存场景的,就算你强制Ctrl + S,重载场景后之前动态生成的对象也会丢失(除非你在生成对象后,又手动在场景里做一些修改)
    那么我需要手动调用场景管理器里的一个方法,将当前所有打开的场景标志为“脏的”,即被改动过的,这个时候在就可以Ctrl + S保存了。
    EditorSceneManager.MarkAllScenesDirty();
    同理,如果你通过代码改过资源,那么也需要手动调用AssetDatabase.Refresh 刷新下编辑器。

    文章转自:http://www.cnblogs.com/jeason1997/p/5109541.html

    相关文章

      网友评论

        本文标题:Unity3D Editor 扩展细节

        本文链接:https://www.haomeiwen.com/subject/pexuextx.html