Unity 编辑器扩展

可以在unity做窗口啊 编辑器啊 还有菜单栏自己的功能实现 一般都放在Editor文件里


image.png

在这个文件里面的东西不会被打包

using UnityEditor;
using UnityEngine;
public class Tools
{
    [MenuItem("Tools/test/test1")]//在菜单栏Tools 的test点击使用方法
    static void Test()//要用静态才能被调用到
    {
        Debug.Log("Test1");
    }

    [MenuItem("Tools/test/test2")]
    static void Test2()
    {
        Debug.Log("Test2");
    }
    //每一个类都有横线分割 默认是第四类 如果在第一类就也可以在Hierarchy右键出来
    //每一个菜单栏的priority优先级默认为1000 小于10按大小排序 大于10是分到另外一组
    [MenuItem("GameObject/my tool",false,10)]
    static void Test3()
    {
        Debug.Log("Test3");
    }

    [MenuItem("Assets/assetbtn"]
    static void Test4()
    {
        Debug.Log("Test4");
    }
}

接下来是效果图



image.png

image.png

然后下个Unity官方的项目方便 做编辑器扩展 需要一个unity账号申请一个就可以了 不用翻墙


image.png

搜索Survival 就是下面这个官方教学
image.png
image.png

点击下载
然后提示加载覆盖
没有提示的话可以再C盘固定目录找到 要显示隐藏的项目 用户后面的名字是你的当前计算机用户的名字默认就我这个
这下面就是每一个下载的package


image.png

image.png

找到sence试玩一下还算不错

using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
public class PlayerEditor
{
    //CONTEXT 组件名 PlayerHealth脚本名 第三个组件btn名
    [MenuItem("CONTEXT/PlayerHealth/InitHealthAndSpeed")]
    static void InitHealthAndSpeed(MenuCommand cmd)//是当前正在操作的组件对象 系统调用不用传
    {
        //输出挂载物体的名字
        Debug.Log(cmd.context.name);
        //()转不行就报错 as 不管是不是空是不是能转类型都不会报错
        CompleteProject.PlayerHealth health = (CompleteProject.PlayerHealth)cmd.context;
        health.startingHealth = 200;
        health.flashSpeed = 10;
    }
}

找到物体挂的PlayerHealth脚本右键就有了


image.png

image.png

右键点击之后就修改了


image.png

再来设置一个rigidbody的质量和不受重力

[MenuItem("CONTEXT/Rigidbody/Clear")]
    static void ClearMassAndGravity(MenuCommand cmd)
    {
        Rigidbody rgd = cmd.context as Rigidbody;
        rgd.mass = 0;
        rgd.useGravity = false;
    }
image.png
 [MenuItem("GameObject/my delete", false,11)]
    static void Test6()
    {
        foreach (var item in Selection.objects)
        {
            //编辑器模式下的删除 Ctrl Z无法恢复
            //GameObject.DestroyImmediate(item);

            //需要把删除的操作注册到操作记录里 这个可以撤销的
            Undo.DestroyObjectImmediate(item);
        }
    }

然后我们删除


image.png

添加快捷键
% – CTRL on Windows / CMD on OSX

– Shift

& – Alt
LEFT/RIGHT/UP/DOWN – Arrow keys
F1…F2 – F keys
HOME, END, PGUP, PGDN

  //要有空格 然后加_
    [MenuItem("Tools/test3 _t")]
    static void Test7()
    {
        Debug.Log("Test3");
    }

    //%=ctrl #=shift &=alt 
    [MenuItem("Tools/test4 %q")]
    static void Test8()
    {
        Debug.Log("Test3");
    }
image.png

image.png

第二个参数是验证判断条件

 //除了bool都一样
    [MenuItem("GameObject/my delete", true, 11)]
    static bool MyDeleteValidate()
    {
        if (Selection.objects.Length>0)
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    //第二个参数 是验证方法是否可用
    [MenuItem("GameObject/my delete", false,11)]
    static void Test6()
    {
        foreach (var item in Selection.objects)
        {
            //编辑器模式下的删除 Ctrl Z无法恢复
            //GameObject.DestroyImmediate(item);

            //需要把删除的操作注册到操作记录里 这个可以撤销的
            Undo.DestroyObjectImmediate(item);
        }
    }
image.png

然后没有选中就不让点 但是project界面是亮的

 //在不是Editor脚本中创建按钮
        [ContextMenu("SetColor")]
        void SetColor()
        {
            flashColour = Color.green;
        }
image.png

这样也可以添加

在某个属性上添加按钮 这个也不用unityEditor


image.png
  //按钮名 方法名
        [ContextMenuItem("Add hp", "AddHp")]
        public int startingHealth = 100;
        void AddHp()
        {

        }

然后创建对话框

using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
//可编程的对话框
public class EnemyChange : ScriptableWizard
{
    [MenuItem("Tools/CreateWizard")]
    static void CreateWizard()
    {
        //泛型是做对话框的类 第一个参数是对话框名字 第二个是改变的btn名字
        ScriptableWizard.DisplayWizard<EnemyChange>("统一修改敌人", "Change Value");
    }

    public int changeHealthValue = 10;
    public int changeSinkSpeedValue = 1;

    //按钮点击 之后触发的事件
    private void OnWizardCreate()
    {
        //objects 是场景中 这个包含预制体
        GameObject[] enemyP = Selection.gameObjects;
        for (int i = 0; i < enemyP.Length; i++)
        {
            CompleteProject.EnemyHealth e = enemyP[i].GetComponent<CompleteProject.EnemyHealth>();
            //编辑器记录下可以撤回 放在改变之前
            Undo.RecordObject(e, "change health and speed");
            e.startingHealth += 10;
            e.sinkSpeed += 1;

        }
    }
}


image.png

点击之后就改变了

添加提示报错 还有保存上次调整信息

using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
//可编程的对话框
public class EnemyChange : ScriptableWizard
{
    [MenuItem("Tools/CreateWizard")]
    static void CreateWizard()
    {
        //泛型是做对话框的类 第一个参数是对话框名字 第二个是改变的btn名字
        ScriptableWizard.DisplayWizard<EnemyChange>("统一修改敌人", "Change And Close", "Change");
    }

    public int changeHealthValue = 10;
    public int changeSinkSpeedValue = 1;

    const string changeHealthValueKey= "EnemyChange.changeHealthValue";
    const string changeSinkSpeedValueKey = "EnemyChange.changeSinkSpeedValue";
    //被创建出来调用
    private void OnEnable()
    {
        //一开始调用参数
        changeHealthValue= EditorPrefs.GetInt(changeHealthValueKey, changeHealthValue);
        changeSinkSpeedValue = EditorPrefs.GetInt(changeSinkSpeedValueKey, changeSinkSpeedValue);
    }
    //按钮点击 之后触发的事件
    private void OnWizardCreate()
    {
        //objects 是场景中 这个包含预制体
        GameObject[] enemyP = Selection.gameObjects;
        //进度条
        EditorUtility.DisplayProgressBar("进度", "0/" + enemyP.Length + "完成修改值", 0);
        int count = 0;
        for (int i = 0; i < enemyP.Length; i++)
        {
            CompleteProject.EnemyHealth e = enemyP[i].GetComponent<CompleteProject.EnemyHealth>();
            //编辑器记录下可以撤回 放在改变之前
            Undo.RecordObject(e, "change health and speed");
            e.startingHealth += 10;
            e.sinkSpeed += 1;
            count++;
            EditorUtility.DisplayProgressBar("进度", "0/" + enemyP.Length + "完成修改值", (float)i/enemyP.Length);
        }
        //清空进度条
        //EditorUtility.ClearProgressBar();
        ShowNotification(new GUIContent($"{ Selection.gameObjects.Length}个游戏的值被修改了"));
    }

    private void OnWizardOtherButton()
    {
        OnWizardCreate();
    }

    //自带的Update 打开 改变值调用
    private void OnWizardUpdate()
    {
        if (Selection.gameObjects.Length>0)
        {
            helpString = $"您当前选择了{Selection.gameObjects.Length}个敌人";
        }
        else
        {
            //提示
            errorString = "请选择至少一个敌人";
        }

        //自动保存改变后的字段 下次还是改变的值
        EditorPrefs.SetInt(changeHealthValueKey, changeHealthValue);
        EditorPrefs.SetInt(changeSinkSpeedValueKey, changeSinkSpeedValue);
    }
    //选择物体发生改变
    private void OnSelectionChange()
    {
        OnWizardUpdate();
    }
}



image.png
image.png
image.png

创建常用的窗口 长时间存在的

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
//继承这个类
public class MyWindow : EditorWindow
{
    [MenuItem("Window/Show My Window")]
    static void ShowMyWindow()
    {
        EditorWindow.GetWindow<MyWindow>().Show();
    }

    string name1="";
    //绘制 循环调用的
    private void OnGUI()
    {
        //Text
        GUILayout.Label("这是我的窗口");
        //输入框
        name1 = GUILayout.TextField(name1);

        if (GUILayout.Button("创建"))
        {
            GameObject go = new GameObject(name1);
            //登记撤销记录
            Undo.RegisterCreatedObjectUndo(go,"Create obj");
        }       
    }
}

image.png

可以拖到这里


image.png

输入名字

image.png

然后就创建了一堆
这个是源码
https://github.com/1004019267/EditorTest/tree/master

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,053评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,527评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,779评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,685评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,699评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,609评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,989评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,654评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,890评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,634评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,716评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,394评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,976评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,950评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,191评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,849评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,458评论 2 342

推荐阅读更多精彩内容