Calmer的文章

  • 首页
  • 文章归档
  • 关于页面

  • 搜索
体验游戏 笔记 推荐 工具链 工具使用 小游戏 插件 UI 软件 教程

Unity3D编辑器扩展(UnityEditor)

发表于 2020-04-07 | 分类于 游戏开发 | 0 | 阅读次数 1053

前言

此文为UnityEditor的入门文章,在UnityEditor中我们可以很方便的使用它自带的UnityEditor类中相关的工具,实现我们工具的可视化以及修改添加部分编辑中的功能。

  1. 为什么需要编辑器扩展?
    因为项目中可能很多时候存在重复性工作,而我们做成工具类后,可以使用代码帮我们快速的完成这些工作。
  2. 相较于Python书写工具,Editor有哪些优劣?
    1. Python工具
      • (优势)但是一旦开发完成,我们可以用于任何引擎,需求只需要根据项目而定
      • (劣势)需要额外的去实现可视化操作,并且调用Unity自身Api不是那么方便
    2. Editor工具
      • (优势)可以快速的实现可视化的操作,便于调用Unity中本身的相关Api,开发效率相对高一些。
      • (劣势)不是那么容易移植到其他游戏引擎中
    3. 建议
      • 可视化要求不高,并且对Unity自身Api依赖度低的工具采用Python开发。(例如:批量修改资源名,修改meta文件中部分的内容等等)
      • 相反,尽量使用引擎自身的编辑器扩展方法

视频学习: 基础:siki学习
源码:
官方文档:

Unity版本:2018.4.18f


开始

  • 了解
    Unity引擎扩展的类,都放在Editor目录下
    Editor:该目录下资源都不会被打包
    因此这些方法,只能在编辑器模式下有用,项目发布后是无法使用的

  • 主要内容

    • 菜单栏的功能添加
    • 选中项Selection
    • 回撤操作
    • 创建独立窗口

菜单栏(MenuItem 用法)

unity manual: ScriptsApi(查询相关方法Api)

  • 创建

在静态方法上加上[MenuItem("Tools/Test")] ,即可在Unity上方创建一个新的Tools选项,进入后有一个可点击按钮Test

using UnityEditor;
using UnityEngine;
public EditorExtend
{
  [MenuItem("Tools/Test")]
  static void Test()
  {
      Debug.Log("Test");
  }
}
  • 分类

每个[MenuItem("xxx/xxx")] 默认优先级priority是1000
可以使用[MenuItem("Tools/Test",false,1)] 修改优先级,优先级越小越在上面,其中第三个参数为优先级,第二个参数暂时可以忽略

using UnityEditor;
using UnityEngine;
public EditorExtend
{
  [MenuItem("Tools/Test",false,3)]
  static void Test()
  {
      Debug.Log("Test");
  }
  [MenuItem("Tools/Test2",false,2)]
  static void Test2()
  {
      Debug.Log("Test2");
  }
  [MenuItem("Tools/Test3",false,15)]
  static void Test3()
  {
      Debug.Log("Test3");
  }
  [MenuItem("Tools/Test4",false,4)]
  static void Test4()
  {
      Debug.Log("Test4");
  }
}

在Tools选项卡中,会将 Test,Test2,Test4归为一类,并且Test2最上,Test中间,Test4最下面;然后Test3 分为一类。

优先级相差11以上为一类,即添加横线

  • 修改
    • 如果我们现在Unity编辑原本的GameObject选项卡中添加一项
      [MenuItem("GameObject/MyTool",false,10)]
    • 在Asset选项卡中添加一项
      [MenuItem("Assets/MyTool1",false,1000)]

同时我们原本在Project中“右键”会有弹窗,其中也会添加上我们的MyTool1的选项,而在GameObject选项卡中,将优先级设置为10左右,也能够在Hierarchy面板中右键弹窗显示相应按钮"MyTool"


具体案例的使用

官方项目:survial shooter
我们的MenuItem还有在Inspector中右键组件 添加扩展功能
例如:给相关的组件添加额外的功能

[MenuItem("CONTEXT/组件名/按钮名")]
static void InitHealthAndSpeend(MenuCommand cmd) 
{
  
}

(MenuCommand是当前操作的组件 cmd.context)


UnityEditor中选中项(Selection)

  • Hierarchy面板选中的目标 可以使用 Selection.activeTransform(选中多个其值为选中的第一个)
  • Hierarchy和Project选中目标:Selection.objects or Selection.gameObjects(返回值为一个数组)

Ctrl+Z的撤销功能

所有我们自己添加的扩展,如果没有记录的,删除了Ctrl+Z是不能恢复的
例如:

  • 删除操作不可撤销
    DestroyObjectImmeiate(o);
  • 删除操作可撤销
    Undo.DestroyObjectImmeiate(o);

功能快捷键

  • 单个字母:路径名后 空格 下划线
    [MenuItem("Assets/MyTool1 _t",false,1000)]
    该快捷键T

  • 组合键:
    [MenuItem("Assets/MyTool1 %t",false,1000)]
    该快捷键Ctrl+T

ctrl:%
shift:#
alt:&


关于功能方法判断

[MenuItem("Assets/MyTool1 %t",false,1000)]
其中间的参数作用,为true表示功能是否可用需要通过一个判断方法。

[MenuItem("Assets/MyTool1 %t",true,1000)]
static bool CheckFun()
{
    return true;
}
[MenuItem("Assets/MyTool1 %t",true,1000)]
static void Fun()
{
    //do something
}

注意:注解需一致,只是有一个返回值为bool的为判断方法

例如:选中有目标可用,否则置灰

[MenuItem("Assets/MyTool1 %t",true,1000)]
static bool CheckFun()
{
    if(Selection.objects.length!=0)
        return true;
    return false;
}
[MenuItem("Assets/MyTool1 %t",true,1000)]
static void Fun()
{
    //do something
}

直接在自定义脚本中,添加右键功能

ContextMenu和ContextMenuItem都在UnityEngine中,因此可以自己写在作用的脚本中,并且不用试静态的方法,前者修饰方法,后者修饰属性

//右键脚本:可以出现该方法
[ContextMenu("Do Something")]
void Do()
{
    Debug.Log("DoSomething")
}

//右键属性:可以出现该方法
//第一个参数是按钮名  第二是方法名
[ContextMenuItem("Add Hp","AddHp")] 
public int health;

private void AddHp()
{
    health+=10;
}

创建对话框

创建的基础对话框:ScriptableWizard

using Editor 
public Dialog:ScriptableWizard
{
    [MenuItem("Tools/CreateDialog")]
    static void CreateDialog()
    {
        ScriptableWizard.DisplayWizard<类名>("名字",“按钮名”);
    }

    public int addHealth=10;
    public int addSpeed=1;
    
    
    //按钮Create按钮时调用的函数
    void OnWizardCreate()
    {
        Selection.gameObjects
        //撤销 ,放在所有操作之前
        Undo.RecordObject(hp,"sss");
    }
    
    //对话框中的数据变化后调用,创建时调用一次
    void OnWizardUpdate()
    {

    }
    
    //选中的对象发生改变
    OnSelectionChanage()
    {

    }
    
}

wizard中的提示字符串
helpString= 显示在对话框顶部 ,errorString= 显示在对话框底部
第二按钮
ScriptableWizard.DisplayWizard<类名>("名字",“按钮名”,“第二个按钮名”)
第一个按钮点击会关闭窗口
第二个按钮不会关闭窗口

ShowNotification(new GUIContent("str"));

EditorPrefs保存编辑值(与PlayerPrefs同样适用方法)
SetInt
GetInt


显示进度条

EditorUtility.
DisplayProgressBar(........) 显示
ClearProgressBar() 关闭


创建自定义窗口

继承于EditorWindow

MyWindow window = EditorWindow.GetWindow()
window.Show()

void OnGUI()

EditorGUILayout.Button()
Undo.RegisterCreatedObjectUndo(go,"create game")

  • 本文作者: Calmer
  • 本文链接: https://mytechplayer.com/archives/unity3d编辑器扩展unityeditor
  • 版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!
# 工具链
XLua+UGUI框架
循环列表的实现(UI优化)
  • 文章目录
  • 站点概览
Calmer

Calmer

88 日志
7 分类
10 标签
RSS
Creative Commons
0%
© 2020 — 2025 Calmer
由 Halo 强力驱动
蜀ICP备20010026号-1川公网安备51019002006543
Copyright © 2020-2025 Calmer的文章