Unity编辑器扩展教程提供全流程,中文翻译

Unity编辑器扩展教程提供全流程,中文翻译

Unity编辑器扩展教程(二)

本文提供全流程地图场景,中文翻译。

Chinar坚持将简单的生活方式,带给世人!

(拥有更好的阅读体验 —— 高分辨率用户请根据需求调整网页缩放比例)

二 三

此教程是在教程(一)基础上进行扩展:若是不知道如何建立编辑器按钮,推荐先看教程(一) 数组

Unity3D编辑器扩展介绍、教程 —— 建立菜单项(一)编辑器

一 Brief Introduction —— 简介

咱们在作工程的时候,须要对数据进行操做。函数

为节省时间,会使用一些快捷键,菜单栏上的功能、或是右键菜单 工具

这些便捷的功能,都是Unity官方为了方便咱们对所需数据进行操做。测试

对Unity编辑进行了一些封装处理,简化数据操做流程,封装为一个按钮/一个窗口/窗口功能。字体

这些诸如此类的功能就是编辑器的扩展,和封装spa

功能键、Inspector面板、Game视窗等等都是编辑器的功能

注意:编辑器类脚本,必须放在 Assets/Editor 资源目录中 .net

此文件夹下的脚本只对编辑器进行操做。最后资源打包,Editor文件夹下的全部资源都不会被打包到工程中 翻译

若是没有此文件夹,需自行建立:在Project视窗下,右键Create - - Folder 3d

二 ScriptableWizard —— 脚本化向导

ScriptableWizard 是一个编辑器类技能特效,继承自 EditorWindow

从这个类派生来建立一个编辑器向导

1

- - DisplayWizard —— 显示器向导

建立一个显示器向导unity 编辑器窗口,调用静态方法

DisplayWizard (“标题”, “第一个按钮”, “第二个按钮”);

便可建立一个 显示器向导

using UnityEditor; //引用Unity编辑器命名空间
using UnityEngine; //引用Unity引擎命名空间
/// 
/// 改变全部敌人脚本
/// 
public class ChangeAll : ScriptableWizard
{
    public int AddHp = 10; //每次增长血量值
    public int Num = 0;//一个数字为了测试 isValue
    /// 
    /// 菜单栏 个人工具 中,建立一个按钮
    /// 
    [MenuItem("个人工具/修改全部敌人属性")]
    static void 修改全部敌人属性()
    {
        //显示器向导 <所管控的类>( 窗口的名字,窗口中按钮的名字,第二个按钮的名字 );
        DisplayWizard("修改全部敌人血量", "确认修改血量", "第二个按钮");
    }
}

2

- - ScriptableWizard Messages Sent —— 脚本化向导的信息传递

其中内置了一些固定函数,用来传递信息

OnEnable() —————————————————– 脚本有效时就会执行

OnWizardCreate() ————————————— 在 建立 / 第一个 按钮上点击时调用

OnWizardOtherButton() ————————— 在 其余 按钮上点击时调用(容许一个动做)

OnWizardUpdate() ————————————– 在向导被打开 / 向导中数据发生变化时被调用

OnSelectionChange() ——————————— 当选择发生改变,调用此函数

(此函数在EditorWindow中,而ScriptableWizard继承自EditorWindow,因此能够在其中直接调用)

using UnityEditor; //引用Unity编辑器命名空间
using UnityEngine; //引用Unity引擎命名空间
/// 
/// 改变全部敌人脚本
/// 
public class ChangeAll : ScriptableWizard
{
    public int AddHp = 10; //每次增长血量值
    public int Num   = 0;  //一个数字为了测试 isValue
    /// 
    /// 菜单栏 个人工具 中,建立一个按钮
    /// 
    [MenuItem("个人工具/修改全部敌人属性")]
    static void 修改全部敌人属性()
    {
        //显示器向导 <所管控的类>( 窗口的名字,窗口中按钮的名字,第二个按钮的名字 );
        DisplayWizard("修改全部敌人血量", "确认修改血量", "第二个按钮");
    }
    /// 
    /// 固定函数名:窗口开始时执行
    /// 
    void OnEnable()
    {
        AddHp = EditorPrefs.GetInt("ChangeAll_health", AddHp); //取值,默认为初始值 并赋值给AddHp
    }
    /// 
    /// 固定函数名:对应现实向导中的第一个按钮 —— 确认修改血量
    /// 
    void OnWizardCreate()
    {
        //进度条
        EditorUtility.DisplayProgressBar("修改进度", "0/" + Selection.gameObjects.Length + "完成修改", 1);
        int count = 0;
        foreach (var gameObject in Selection.gameObjects) //遍历选中的物体
        {
            CompleteProject.EnemyHealth health = gameObject.GetComponent(); //获取其身上脚本组件
            Undo.RecordObject(health, "Change health");                                                  //记录变量 health 以后作的更改
            health.startingHealth += AddHp;                                                              //自增 设置的值 //须要修改其余属性,本身往下写
            count++;
            //进度条
            EditorUtility.DisplayProgressBar("修改进度", count + "/" + Selection.gameObjects.Length + "完成修改", progress: count / Selection.gameObjects.Length);
        }
        EditorUtility.ClearProgressBar();//清除进度条
    }
    /// 
    /// 固定函数名:对应现实向导中的第二按钮 —— 第二个按钮
    /// 
    void OnWizardOtherButton()
    {
        //弹出通知(新建一个 GUI内容(被选中物体的个数)+“字符” )
        ShowNotification(new GUIContent(Selection.gameObjects.Length + "个元素被选中"));
    }
    /// 
    /// 当属性值被修改时,每帧调用。 / 当界面开启时,会调用一次
    /// 
    void OnWizardUpdate()
    {
        helpString  = null; //每次调用就归零一次,不然会出现字体不消除的状况
        errorString = null;
        if (Selection.gameObjects.Length > 0)
        {
            helpString = "当前选择了" + Selection.gameObjects.Length + "个敌人"; //及时更新选择的数量
        }
        else
        {
            errorString = "最少选择一个啊"; //错误提示
        }
        EditorPrefs.SetInt("ChangeAll_health", AddHp); //修改后存入一个值,就是记录一下。
    }
    /// 
    /// 当选择的物体发生改变,调用此函数
    /// 
    void OnSelectionChange()
    {
        OnWizardUpdate();
    }
}

3

- - DisplayProgressBar —— 进度条

在显示器向导中建立一个进度条

EditorUtility.DisplayProgressBar( 进度条标题,进度信息,进度比例 )

EditorUtility.ClearProgressBar() 调用此函数unity 编辑器窗口,进度条才会被删除

using UnityEditor; //引用Unity编辑器命名空间
using UnityEngine; //引用Unity引擎命名空间
/// 
/// 改变全部敌人脚本
/// 
public class ChangeAll : ScriptableWizard
{
    public int AddHp = 10; //每次增长血量值
    public int Num   = 0;  //一个数字为了测试 isValue
    /// 
    /// 菜单栏 个人工具 中,建立一个按钮
    /// 
    [MenuItem("个人工具/修改全部敌人属性")]
    static void 修改全部敌人属性()
    {
        //显示器向导 <所管控的类>( 窗口的名字,窗口中按钮的名字,第二个按钮的名字 );
        DisplayWizard("修改全部敌人血量", "确认修改血量", "第二个按钮");
    }
    /// 
    /// 固定函数名:对应现实向导中的第二按钮 —— 第二个按钮
    /// 
    void OnWizardOtherButton()
    {
        EditorUtility.DisplayProgressBar("修改进度", "0/" + Selection.gameObjects.Length + "完成修改", 1); //进度条
        int count = 0;                                                                             //计数
        foreach (var gameObject in Selection.gameObjects)                                          //遍历选中的物体
        {
            CompleteProject.EnemyHealth health = gameObject.GetComponent();                                         //获取其身上脚本组件
            Undo.RecordObject(health, "Change health");                                                                                          //记录变量 health 以后作的更改
            health.startingHealth += AddHp;                                                                                                      //自增 设置的值 //须要修改其余属性,本身往下写
            count++;                                                                                                                             //计数自增1
            EditorUtility.DisplayProgressBar("修改进度", count + "/" + Selection.gameObjects.Length + "完成修改", count / Selection.gameObjects.Length); //进度条
        }
        //EditorUtility.ClearProgressBar(); //清除进度条(只有调用此方法,进度条才会删除)
    }
}

三 EditorWindow —— 编辑器窗口

建立一个编辑器窗口,在咱们的Unity编辑器中

GetWindow(bool, 窗口名字)

bool 值为: false 窗口能够与其余窗口合并

bool 值为: true 窗口独立,不可合并

如下是我写的一个简单的梨子,用于批量修改物体的名称(选择物体内数组,并无进行内部处理)

using UnityEditor; //引用Unity编辑器命名空间
using UnityEngine; //引用Unity引擎命名空间
/// 
/// 建立一个窗口类
/// 
public class ChinarWindow : EditorWindow//继承自 EditorWindow
{
    string      CustomName = "CustomName"; //自定义名字
    private int ChinarNum  = 0;            //空物体数量
    /// 
    /// 建立一个菜单项
    /// 
    [MenuItem("个人工具/显示新窗口")]
    static void 显示新窗口()
    {
        ChinarWindow chinar = GetWindow(false, "Chinar窗口"); //获取到一个窗口,赋值给当前编辑器类的对象
        chinar.Show();                                                    //显示对象的窗口
    }
    /// 
    /// 此函数中实现编辑器界面的定义/绘制
    /// 
    void OnGUI()
    {
        GUILayout.Label("这是Chianr窗口");                                     //标题
        CustomName = GUILayout.TextField(CustomName);                      //文本框
        ChinarNum  = int.Parse(GUILayout.TextField(ChinarNum.ToString())); //数字框
        //能够直接判断按钮的点击
        if (GUILayout.Button("修改全部物体名字"))
        {
            for (int i = 0; i < Selection.transforms.Length; i++) //遍历选中的元素
            {
                Undo.RecordObjects(Selection.gameObjects as GameObject[], "ChinarWindow_GameObject[]"); //Selection.gameObjects 返回一个GameObject[] ,并记录键(用于回退)
                Selection.transforms[i].SetSiblingIndex(i);                                             //为选择的物体设置下标
                Selection.transforms[i].name = CustomName + i;                                          //设置名字+i
            }
        }
        //判断按钮的点击
        if (GUILayout.Button("建立多个空物体"))
        {
            if (ChinarNum <= 0) //若是数字 小于等于 0
            {
                ShowNotification(new GUIContent("请写入建立空物体数量")); //提示 输入
            }
            else //不为0
            {
                for (int i = 0; i < ChinarNum; i++) //遍历个数
                {
                    Undo.RegisterCreatedObjectUndo(new GameObject(CustomName), "Chinar Create gameobject"); //建立一个名为 CustomName 的空物体
                }
            }
        }
    }
}

END

本博客为非营利性我的原创,除部分有明确署名的做品外,所刊登的全部做品的著做权均为本人所拥有,本人保留全部法定权利。违者必究 对于须要复制、转载、连接和传播博客文章或内容的,请及时和本博主进行联系,留言,Email: 对于经本博主明确受权和许可以使用文章及内容的,使用时请注明文章或内容出处并注明网址

文章来源:http://www.noobyard.com/article/p-efhlkekh-bg.html