unity editor 编辑器插件制作基础:三、自定义窗口组件

一 说明

  1. unity edtor的自定义窗口属于独立组件,必须继承EditorWindow类
  2. 窗口的打开方式可以通过定义静态方法,来通过菜单栏、inspector面板以及scene中的方法启动
  3. 窗口组件的脚本有自己的生命周期,灵活运用生命周期及unity编辑器的开放接口可以实现unity中所有的功能。

二 unity editor自定义窗口的实现

2.1 依赖库
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
2.2 定义脚本
// 定义类必须继承EditorWindow
public class MapTools : EditorWindow
{
    
    
	// 窗口启动方式  也可以通过从其他脚本中调用该静态方法来打开
    [MenuItem("GameObject/MyWindow")]
    static void BuildWindow()
    {
    
    
        // 创建窗口  脚本;位置尺寸;名
        MapTools window = (MapTools)EditorWindow.GetWindowWithRect(typeof(MapTools), new Rect(0, 0, 500, 800), true, "My Window");
        // 显示窗口
        window.Show();
    }
 }
2.3 生命周期

满足条件时,生命周期函数会被调用,且在状态未发生变化时,只调用一次。


    //窗口获得焦点时调用
    void OnFocus()
    {
    
    
        Debug.Log("窗口获得焦点时调用");
    }
    //窗口丢失焦点时调用
    void OnLostFocus()
    {
    
    
        Debug.Log("窗口丢失焦点时调用");
    }
    // Hierarchy窗口有变化时调用
    void OnHierarchyChange()
    {
    
    
        Debug.Log("Hierarchy窗口有变化时调用");
    }
    // Project项目资源窗口有变化时调用
    void OnProjectChange()
    {
    
    
        Debug.Log("Project项目资源窗口有变化时调用");
    }

    // inspector窗口有变化时调用  保证数据同步用
    void OnInspectorUpdate()
    {
    
    
        Debug.Log("inspector窗口有变化时调用 ");
        //重绘窗口,保证数据同步
        this.Repaint();
    }
    //选择物体时调用 重复点击相同物体不调用
    void OnSelectionChange()
    {
    
    
         Debug.Log("窗口打开时,在Hierarchy视图中选择对象或在scene中选择物体时调用");
        // 捕获所有被选择的物体
        foreach (Transform t in Selection.transforms)
        {
    
    
            Debug.Log("当前选择的物体名:" + t.name);
        }
    }

    // 打开窗口时调用
    public void Awake(){
    
    
         Debug.Log("打开窗口时调用");
    }
    // 关闭窗口调用
    void OnDestroy()
    {
    
    
        Debug.Log("关闭窗口时调用");
    }
2.4 UI组件
	// 普通变量重新打开窗口就会恢复默认值。如果变量设置为static,那么再打开窗口时仍然可以看到数据
	// 用于存储输入文字数据。
    static private string text;
    //用于存储贴图
    static private Texture texture;
    static bool toggleGroupStatus = false;
    static bool fadeGroupStatus = false;
    static float fadeValue =0.5f;
    static bool foldGroupStatus = false;
    private enum MyType{
    
    
        A,B,C
    }
    private MyType myType;
    //绘制ui组件需要在OnGUI 周期中调用。  因为窗口属于Unity editor的 刷新
    void OnGUI()
    {
    
    
        // unity编辑器界面中的所有控件都可以用这种方式创建出来
        //输入框控件
        text = EditorGUILayout.TextField("文字框:", text);
        text = GUILayout.TextField(text);
        //创建曲线控件
        EditorGUILayout.CurveField(new AnimationCurve());
        //颜色空间
        // GUILayout.
        EditorGUILayout.ColorField(new Color32(), GUILayout.Width(300));
        // 下拉按钮
        EditorGUILayout.DropdownButton(new GUIContent("dropdown button"),FocusType.Keyboard);
        // 枚举选择框
        EditorGUILayout.EnumFlagsField(myType);
        // 渐变色
        EditorGUILayout.GradientField(new Gradient());
        // 帮助信息盒
        EditorGUILayout.HelpBox("help", MessageType.Error);
        // 滑竿,能设置类型
        EditorGUILayout.IntSlider(1,1,2); //EditorGUILayout.Slider
        EditorGUILayout.LabelField("label");
        // 获取游戏图层信息
        EditorGUILayout.LayerField(1);
        // 获取rect组件
        EditorGUILayout.RectField( new Rect(0, 0, 500, 500));
        // v3组件
        EditorGUILayout.Vector3Field("v3",Vector3.zero);
        //勾选
        EditorGUILayout.Toggle("toggle",true);
        // 游戏标签组件
        EditorGUILayout.TagField("tag");
        EditorGUILayout.Separator();
        // 有范围的滑竿
        //EditorGUILayout.MinMaxSlider();

        // 可选标签
        EditorGUILayout.SelectableLabel("label");
        // 勾选框 作为群组开关
        toggleGroupStatus=EditorGUILayout.BeginToggleGroup("启用",toggleGroupStatus);
        EditorGUILayout.Toggle(true);
        EditorGUILayout.EndToggleGroup();

        // 可以控制显示高度的组  0是完全不显示,1是完全显示
        fadeValue = EditorGUILayout.Slider(fadeValue, 0f,1f);
        fadeGroupStatus = EditorGUILayout.BeginFadeGroup(fadeValue);
        EditorGUILayout.Toggle(true);
        EditorGUILayout.EndFadeGroup();
        // 下箭头节点组    与BeginFadeGroup组合 就能做出伸缩菜单
        foldGroupStatus = EditorGUILayout.BeginFoldoutHeaderGroup(foldGroupStatus,"节点组件");
        
        // 二级 下箭头加文字
        EditorGUILayout.Foldout(foldGroupStatus,"剪头组件");

        if(foldGroupStatus){
    
    
            EditorGUILayout.Toggle(true);
        }
        // foldGroupStatus = EditorGUILayout.Foldout(foldGroupStatus,"剪头组件");
        EditorGUILayout.EndFoldoutHeaderGroup();

        // 使用通知栏
        if (GUILayout.Button("打开通知"))
        {
    
    
            //打开通知
            this.ShowNotification(new GUIContent("通知你续费"));
        }
        if (GUILayout.Button("关闭通知"))
        {
    
    
            //关闭通知
            this.RemoveNotification();
        }

        //文本框显示鼠标在窗口的位置
        EditorGUILayout.LabelField("鼠标在窗口的位置", Event.current.mousePosition.ToString());

        //选择贴图 ,如果值是静态的,那么关闭再打开依然可以看到上次的选择
        texture = EditorGUILayout.ObjectField("添加贴图", texture, typeof(Texture), true) as Texture;

        if (GUILayout.Button("关闭窗口", GUILayout.Width(200)))
        {
    
    
            //关闭窗口
            this.Close();
        }
        // EditorGUILayout.Knob(new Vector2(),01f,11f,111f,"ss",Color.blue,Color.cyan ,true);
    }

三 完整脚本

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;

public class MapTools : EditorWindow
{
    
     
    //用于存储输入文字数据。重新打开窗口就会清零。如果变量设置为static,那么再打开窗口时仍然可以看到数据
    static private string text;
    //用于存储贴图
    static private Texture texture;
    static bool toggleGroupStatus = false;
    static bool fadeGroupStatus = false;
    static float fadeValue =0.5f;
    static bool foldGroupStatus = false;
    private enum MyType{
    
    
        A,B,C
    }
    private MyType myType;
    // 窗口启动方式  也可以通过从其他脚本中调用该静态方法来打开
    [MenuItem("GameObject/MyWindow")]
    static void BuildWindow()
    {
    
    
        // 创建窗口 脚本;位置尺寸;名
        MapTools window = (MapTools)EditorWindow.GetWindowWithRect(typeof(MapTools), new Rect(0, 0, 500, 800), true, "My Window");
        // 显示窗口
        window.Show();
    }
    // 绘制窗口时调用
    void OnGUI()
    {
    
    
        // unity编辑器界面中的所有控件都可以用这种方式创建出来
        //输入框控件
        text = EditorGUILayout.TextField("文字框:", text);
        text = GUILayout.TextField(text);
        //创建曲线控件
        EditorGUILayout.CurveField(new AnimationCurve());
        //颜色空间
        // GUILayout.
        EditorGUILayout.ColorField(new Color32(), GUILayout.Width(300));
        // 下拉按钮
        EditorGUILayout.DropdownButton(new GUIContent("dropdown button"),FocusType.Keyboard);
        // 枚举选择框
        EditorGUILayout.EnumFlagsField(myType);
        // 渐变色
        EditorGUILayout.GradientField(new Gradient());
        // 帮助信息盒
        EditorGUILayout.HelpBox("help", MessageType.Error);
        // 滑竿,能设置类型
        EditorGUILayout.IntSlider(1,1,2); //EditorGUILayout.Slider
        EditorGUILayout.LabelField("label");
        // 获取游戏图层信息
        EditorGUILayout.LayerField(1);
        // 获取rect组件
        EditorGUILayout.RectField( new Rect(0, 0, 500, 500));
        // v3组件
        EditorGUILayout.Vector3Field("v3",Vector3.zero);
        //勾选
        EditorGUILayout.Toggle("toggle",true);
        // 游戏标签组件
        EditorGUILayout.TagField("tag");
        EditorGUILayout.Separator();
        // 有范围的滑竿
        //EditorGUILayout.MinMaxSlider();

        // 可选标签
        EditorGUILayout.SelectableLabel("label");
        // 勾选框 作为群组开关
        toggleGroupStatus=EditorGUILayout.BeginToggleGroup("启用",toggleGroupStatus);
        EditorGUILayout.Toggle(true);
        EditorGUILayout.EndToggleGroup();

        // 可以控制显示高度的组  0是完全不显示,1是完全显示
        fadeValue = EditorGUILayout.Slider(fadeValue, 0f,1f);
        fadeGroupStatus = EditorGUILayout.BeginFadeGroup(fadeValue);
        EditorGUILayout.Toggle(true);
        EditorGUILayout.EndFadeGroup();
        // 下箭头节点组    与BeginFadeGroup组合 就能做出伸缩菜单
        foldGroupStatus = EditorGUILayout.BeginFoldoutHeaderGroup(foldGroupStatus,"节点组件");
        
        // 二级 下箭头加文字
        EditorGUILayout.Foldout(foldGroupStatus,"剪头组件");

        if(foldGroupStatus){
    
    
            EditorGUILayout.Toggle(true);
        }
        // foldGroupStatus = EditorGUILayout.Foldout(foldGroupStatus,"剪头组件");
        EditorGUILayout.EndFoldoutHeaderGroup();

        // 使用通知栏
        if (GUILayout.Button("打开通知"))
        {
    
    
            //打开通知
            this.ShowNotification(new GUIContent("通知你续费"));
        }
        if (GUILayout.Button("关闭通知"))
        {
    
    
            //关闭通知
            this.RemoveNotification();
        }

        //文本框显示鼠标在窗口的位置
        EditorGUILayout.LabelField("鼠标在窗口的位置", Event.current.mousePosition.ToString());

        //选择贴图 ,如果值是静态的,那么关闭再打开依然可以看到上次的选择
        texture = EditorGUILayout.ObjectField("添加贴图", texture, typeof(Texture), true) as Texture;

        if (GUILayout.Button("关闭窗口", GUILayout.Width(200)))
        {
    
    
            //关闭窗口
            this.Close();
        }

        // EditorGUILayout.Knob(new Vector2(),01f,11f,111f,"ss",Color.blue,Color.cyan ,true);
    }

    //窗口获得焦点时调用
    void OnFocus()
    {
    
    
        Debug.Log("窗口获得焦点时调用");
    }
    //窗口丢失焦点时调用
    void OnLostFocus()
    {
    
    
        Debug.Log("窗口丢失焦点时调用");
    }
    // Hierarchy窗口有变化时调用
    void OnHierarchyChange()
    {
    
    
        Debug.Log("Hierarchy窗口有变化时调用");
    }
    // Project项目资源窗口有变化时调用
    void OnProjectChange()
    {
    
    
        Debug.Log("Project项目资源窗口有变化时调用");
    }

    // inspector窗口有变化时调用  保证数据同步用
    void OnInspectorUpdate()
    {
    
    
        Debug.Log("inspector窗口有变化时调用 ");
        //重绘窗口,保证数据同步
        this.Repaint();
    }
    //选择物体时调用 重复点击相同物体不调用
    void OnSelectionChange()
    {
    
    
         Debug.Log("窗口打开时,在Hierarchy视图中选择对象或在scene中选择物体时调用");
        // 捕获所有被选择的物体
        foreach (Transform t in Selection.transforms)
        {
    
    
            Debug.Log("当前选择的物体名:" + t.name);
        }
    }

    // 打开窗口时调用
    public void Awake(){
    
    
         Debug.Log("打开窗口时调用");
    }
    // 关闭窗口调用
    void OnDestroy()
    {
    
    
        Debug.Log("关闭窗口时调用");
    }
}

四 子窗口

子窗口可以存在于任何地方,最容易说明的例子就是inspector中的tag和layer列表,其实是两个子窗口
子窗口的是想方法在https://docs.unity3d.com/ScriptReference/PopupWindow.html 中

猜你喜欢

转载自blog.csdn.net/lengyoumo/article/details/113133320
今日推荐