Unity编辑器扩展(Advanced Editor Scripting)

24 篇文章 5 订阅

课程开发介绍

创建一个Unity3D工程,名字叫做Advanced Editor Scripting。 创建一个Editor的文件夹,在打包时不会被打包。

使用MenuItem添加菜单栏按钮

创建一个名为Tools的脚本,添加下面的代码

using UnityEditor;
using UnityEngine;

public class Tools 
{
    [MenuItem("Tools/test")]
    static void Test()
    {
        Debug.Log("Test");
    }
}

编辑器就会出现下面的按键

关于MenuItem的路径设置和现实的先后顺序设置

using UnityEditor;
using UnityEngine;

public class Tools 
{
    //[MenuItem("Tools/test")]
    //static void Test()
    //{
    //    Debug.Log("Test");
    //}

    //每一个菜单栏的priority优先级默认为1000
    //priority在11之内是一个组,大于11就是另外一组
    [MenuItem("Tool/Test1",false,1)]
    static void Test1()
    {
        Debug.Log("Test1");
    }

    [MenuItem("Tool/Test2",false,12)]
    static void Test2()
    {
        Debug.Log("Test2");
    }

    [MenuItem("Tool/Test3",false,0)]
    static void Test3()
    {
        Debug.Log("Test3");
    }

    [MenuItem("GameObject/MyTool", false, 10)]
    static void MyTool()
    {
        Debug.Log("MyTool");
    }
}

导入射击项目

给组件的右键菜单栏添加按钮

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

public class PlayerEditor  
{
    //CONTEXT 组件名 按钮名
    [MenuItem("CONTEXT/PlayerHealth/InitHealthAndSpeed")]
    static void InitHealthAndSpeed()
    {
        Debug.Log("Init");
    }
}

给Player上的脚本组件添加一个右键菜单单栏按钮

关于MenuCommand的使用

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


public class PlayerEditor  
{
    //CONTEXT 组件名 按钮名
    [MenuItem("CONTEXT/PlayerHealth/InitHealthAndSpeed")]
    static void InitHealthAndSpeed(MenuCommand cmd)//menucommand是当前正在操作的组件
    {
        CompleteProject.PlayerHealth health = (CompleteProject.PlayerHealth)cmd.context;
        health.startingHealth = 200;
        health.flashSpeed = 10;
    }

    /// <summary>
    /// 取消重力
    /// </summary>
    /// <param name="cmd"></param>
    [MenuItem("CONTEXT/Rigidbody/Clear")]
    static void ClearMassAndGravity(MenuCommand cmd)
    {
        Rigidbody rgd = cmd.context as Rigidbody;
        rgd.mass = 0;
        rgd.useGravity = false;
    }
}

学习使用Selection获取选择的游戏物体

选择物体的操作

    [MenuItem("Tool/show info",false,1)]
    static void Test1()
    {
        Debug.Log(Selection.activeContext.name);//使我们第一个选择的游戏物体
        Debug.Log(Selection.objects.Length);//获取选择游戏物体的数目

    }

删除物体的操作

    [MenuItem("GameObject/my delete", false, 11)]
    static void Mydelete()
    {
        foreach (object o in Selection.objects)
        {
            GameObject.DestroyImmediate(o as GameObject);
        }
        //需要把删除操作注册到 操作记录里面,才能使用ctrl+z恢复
    }

编写可以撤销的删除操作

    [MenuItem("GameObject/my delete", false, 11)]
    static void Mydelete()
    {
        foreach (object o in Selection.objects)
        {
            //GameObject.DestroyImmediate(o as GameObject);
            //需要把删除操作注册到 操作记录里面,才能使用ctrl+z

            Undo.DestroyObjectImmediate(o as GameObject);
            //利用Undo进行的删除操作,是可以撤销的
        }

    }

如何给菜单项添加快捷键

    //%=ctrl #=shift &=alt
    //使用快捷键ctrl+q触发
    [MenuItem("Tool/Test2 %q",false,12)]
    static void Test2()
    {
        Debug.Log("Test2");
    }

    //使用快捷键t触发
    [MenuItem("Tool/Test3 _t",false,0)]
    static void Test3()
    {
        Debug.Log("Test3");
    }

控制菜单项是否启用的功能

    //Mydelete的验证函数,当下面的函数返回为true时,才能点击my delete
    [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 Mydelete()
    {
        foreach (object o in Selection.objects)
        {
            //GameObject.DestroyImmediate(o as GameObject);
            //需要把删除操作注册到 操作记录里面,才能使用ctrl+z

            Undo.DestroyObjectImmediate(o as GameObject);
            //利用Undo进行的删除操作,是可以撤销的
        }

    }

关于ContextMenu和ContextMenuItem的使用

ContextMenu的使用

        [ContextMenu("SetColor")]
        void SetColor()
        {
            flashColour = Color.green;
        }

ContextMenuItem的使用

        [ContextMenuItem("AddHp","AddHp")]
        public int startingHealth = 100;  
        void AddHp()
        {
            startingHealth += 20;
        }

学习如何创建对话框

创建一个EnemyChange脚本,用来创建对话框来快捷改变Enemy属性

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

public class EnemyChange : ScriptableWizard
{
    [MenuItem("Tools/CreateWizard")]
    static void CreateWizard()
    {
        ScriptableWizard.DisplayWizard<EnemyChange>("统一修改敌人");
    }

    public int changeHealthValue = 10;
    public int changeFlashSpeedValue = 10;
}

如何兼容按钮点击统一修改字段

在EnemyChange脚本中添加 下列代码

    //检测create按钮的点击
    private void OnWizardCreate()
    {
        GameObject [] enemyPrefabs =  Selection.gameObjects;
        foreach (GameObject go in enemyPrefabs)
        {
            CompleteProject.EnemyHealth hp = go.GetComponent<CompleteProject.EnemyHealth>();
            Undo.RecordObject(hp, "change health and speed");
            hp.startingHealth += changeHealthValue;
            hp.sinkSpeed += changeSinkSpeedValue;
        }
    }

显示提示框的帮助信息和错误信息

    //当前字段值修改的时候会被调用
    private void OnWizardUpdate()
    {
        errorString = null;
        helpString = null;
        if (Selection.gameObjects.Length > 0)
        {
            helpString = "你当前选择了" + Selection.gameObjects.Length + "个敌人";
        }
        else
        {
            errorString = "请选择至少一个敌人";
        }
    }

    private void OnSelectionChange()
    {
        OnWizardUpdate();
    }

创建OtherButton按钮并监听按钮点击

    [MenuItem("Tools/CreateWizard")]
    static void CreateWizard()
    {
        ScriptableWizard.DisplayWizard<EnemyChange>("统一修改敌人","Change And CLose","Change");
    }

    private void OnWizardOtherButton()
    {
        OnWizardCreate();
    }

使用ShowNotification显示提示信息

ShowNotification(new GUIContent(Selection.gameObjects.Length + "个游戏物体的值被修改"));

使用EditorPrefs保存数据

    const string changeHealthValueKey = "EnemyChange.changeStartHealthValue";
    const string changeSinkSpeedValueKey = "EnemyChange.changeSinkSpeedValue";
    /// <summary>
    /// 当窗口被创建的时候调用
    /// </summary>
    private void OnEnable()
    {
        EditorPrefs.GetInt(changeHealthValueKey,changeHealthValue);
        EditorPrefs.GetInt(changeSinkSpeedValueKey,changeSinkSpeedValue);
    }


    //调用的时候
    EditorPrefs.SetInt(changeHealthValueKey, changeHealthValue);
    EditorPrefs.SetInt(changeSinkSpeedValueKey, changeSinkSpeedValue);

关闭打开之后

显示进度条

    //检测create按钮的点击
    private void OnWizardCreate()
    {
        GameObject [] enemyPrefabs =  Selection.gameObjects;
        EditorUtility.DisplayCancelableProgressBar("进度", "0/" + enemyPrefabs.Length + "完成修改值", 0);
        int count = 0;
        foreach (GameObject go in enemyPrefabs)
        {
            CompleteProject.EnemyHealth hp = go.GetComponent<CompleteProject.EnemyHealth>();
            Undo.RecordObject(hp, "change health and speed");
            hp.startingHealth += changeHealthValue;
            hp.sinkSpeed += changeSinkSpeedValue;
            count++;
            EditorUtility.DisplayCancelableProgressBar("进度", count+"/" + enemyPrefabs.Length + "完成修改值", (float)count/enemyPrefabs.Length);
        }
        EditorUtility.ClearProgressBar();
        ShowNotification(new GUIContent(Selection.gameObjects.Length + "个游戏物体的值被修改"));
    }

创建自定义窗口

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

public class MyWindow : EditorWindow
{
    [MenuItem("Window/show my window")]
    static void ShowMyWindow()
    {
        MyWindow window = EditorWindow.GetWindow<MyWindow>();
        window.Show();
    }

    private string name = "";
    private void OnGUI()
    {
        GUILayout.Label("这是我的窗口");
        name = GUILayout.TextField(name);
        if (GUILayout.Button("创建"))
        {
            GameObject go = new GameObject(name);
            Undo.RegisterCompleteObjectUndo(go, "create gameobject");
        }
    }
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值