unity 编辑器扩展简单入门

通过使用编辑器扩展,我们可以对一些机械的操作实现自动化,而不用使用额外的环境,将工具与开发环境融为一体;并且,编辑器扩展也提供GUI库,来实现可视化操作;编辑器扩展甚至也可以“补充”IDE缺失的一些内容,让IDE更加人性化。

主要内容

  • MenuItem无界面操作
  • 窗口
  • 优化内置操作
  • 简单工具窗口
  • Gizmos改造场景显示

一、MenuItem无界面操作


assets文件夹下创建Editor文件夹,创建一个新的c#脚本;

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor; public class BaseTest : MonoBehaviour
{
[MenuItem("德玛/第一个扩展")]
static void debugLog()
{
Debug.Log("我是一个menuItem");
}
}

如图,这是我们第一个创建的扩展。

此时,如果我们需要获得一个当前场景选中的物品,则

需要通过Selection。将代码拷贝到当前创建的类里面:

    // 设置第二个参数
[MenuItem("德玛/two", false)]
static void testSecondParam()
{
Vector3 p = Selection.activeTransform.position;
Vector3 v3 = new Vector3(p.x+1, p.y, p.z);
Instantiate(Selection.activeTransform, v3, Quaternion.identity);
}
[MenuItem("德玛/two", true)]
static bool testSecondParam2()
{
return Selection.activeGameObject != null;
}

通过这段代码,我们可以创建一个只有选择了一个场景物体,才会激活的按钮。

二、窗口


创建窗口需要通过EditorWindow作为基类,还是MenuItem为入口创建;

using UnityEngine;
using System.Collections;
using UnityEditor; //注意要引用
public class MyWindow : EditorWindow
{
[MenuItem("德玛/Window/NormalWindow")]//在unity菜单Window下有MyWindow选项
static void NormalWindow()
{
windowType = 1;
MyWindow myWindow = (MyWindow)EditorWindow.GetWindow(typeof(MyWindow), true, "德玛标题", true);//创建窗口
myWindow.Show();//展示
} public void Awake()
{
//在资源中读取一张贴图
texture = Resources.Load("1") as Texture;
}
//绘制窗口时调用
void OnGUI()
{
EditorGUILayout.LabelField("选中");
EditorGUILayout.LabelField(EditorWindow.focusedWindow.ToString());
EditorGUILayout.LabelField("划入");
EditorGUILayout.LabelField(EditorWindow.mouseOverWindow.ToString());
}
//更新
void Update()
{ }
void OnFocus()
{
Debug.Log("当窗口获得焦点时调用一次");
}
void OnLostFocus()
{
Debug.Log("当窗口丢失焦点时调用一次");
}
void OnHierarchyChange()
{
Debug.Log("当Hierarchy视图中的任何对象发生改变时调用一次");
}
void OnProjectChange()
{
Debug.Log("当Project视图中的资源发生改变时调用一次");
}
void OnInspectorUpdate()
{
//Debug.Log("窗口面板的更新");
//这里开启窗口的重绘,不然窗口信息不会刷新
this.Repaint();
} void OnSelectionChange()
{
//当窗口出去开启状态,并且在Hierarchy视图中选择某游戏对象时调用
foreach (Transform t in Selection.transforms)
{
//有可能是多选,这里开启一个循环打印选中游戏对象的名称
Debug.Log("OnSelectionChange" + t.name);
}
} void OnDestroy()
{
Debug.Log("当窗口关闭时调用");
}
}

将上面的代码放入Editor目录下,通过德玛/Window/NormalWindow可以打开窗口。

EditorWindow.focusedWindow获取当前焦点窗口;

EditorWindow.mouseOverWindow获取当前鼠标划入的窗口;

各种生命周期函数均有打印,自行理会。

	void OnInspectorUpdate()
{
//Debug.Log("窗口面板的更新");
//这里开启窗口的重绘,不然窗口信息不会刷新
this.Repaint();
}

这段代码可以保证实时刷新显示。

三、优化内置操作


当路径放入GameObject的时候,会出现在右键菜单里面;

  [MenuItem("GameObject/德玛/德玛Custom Game Object", false, 10]

注解

当然,除了在Editor目录下添加各种扩展以外,我们可以通过给项目脚本添加注解的方式,来优化编辑器显示;

比如通过添加类似于Component的方式,来优化脚本的添加方式,点击后会直接将脚本添加到场景物体上。

[RequireComponent(typeof(Rigidbody))]放入类头。我们将下面脚本放入到Assets/Scripts目录下面。

using UnityEngine;

// 通过编辑器的Component菜单添加脚本
[RequireComponent(typeof(Rigidbody))]
[HelpURL("https://docs.unity3d.com/ScriptReference/HelpURLAttribute.html")]
[AddComponentMenu("德玛/添加德玛脚本")]
public class ContextTesting : MonoBehaviour
{
[Header("属性标题")]
[Multiline(3)]
public string name2; [Space(100)]
[Tooltip("用于设置性别")]
public string sex; [HideInInspector]
public int p = 5; [Range(1, 100)]
[Tooltip("Health value between 0 and 100.")]
public int health = 0; /// Add a context menu named "Do Something" in the inspector
/// of the attached script.
/// 给当前脚本添加右键内容
[ContextMenu("德玛西亚")]
void DoSomething()
{
Debug.Log("德玛西亚打印");
} // 给属性添加右键
[ContextMenuItem("重置属性为空", "ResetBiography")]
public string playerBiography = "";
void ResetBiography()
{
playerBiography = "";
}
}

我们发现,我们可以想组件一样的添加脚本了!



Inspector目录我们也注意到当前脚本属性的显示也发生了变化;

Inspector上,我们也多出来一个Rigidbody组件。

美化项目脚本的属性显示

Assets/Scripts下面创建MyPlayer

using UnityEngine;
using System.Collections; public class MyPlayer : MonoBehaviour
{
public int armor = 100;
public int attack = 100;
public GameObject equipment; }

Editor下面创建MyPlayerEditor:

using UnityEngine;
using UnityEditor;
using System.Collections;
[CustomEditor(typeof(MyPlayer))]
public class MyPlayerEditor : Editor
{
SerializedProperty attack;
void OnEnable()
{
attack = serializedObject.FindProperty("attack");
}
public override void OnInspectorGUI()
{
serializedObject.Update();
EditorGUILayout.IntSlider(attack, 0, 100, new GUIContent("攻击力"));
ProgressBar(attack.intValue / 100, "攻击力");
serializedObject.ApplyModifiedProperties();
}
private void ProgressBar(float value, string label)
{
Rect rect = GUILayoutUtility.GetRect(18, 18, "TextField");
EditorGUI.ProgressBar(rect, value, label);
EditorGUILayout.Space();
}
}

观察Inspector

简单工具窗口


一个简单的确认窗口

using UnityEngine;
using UnityEditor; public class MyEditorUtilityTest : ScriptableObject
{
[MenuItem("德玛/自定义对话框")]
static void CreateWizard()
{
if (EditorUtility.DisplayDialog("对话框标题", "对话框的消息", "OK", "取消"))
{
Debug.Log("OK被点击");
}
else
{
Debug.Log("您没有点击OK");
}
}
}

显示如下

Gizmos改造场景显示


我们可以改造物体在场景中的显示;

如下代码

其他


通过上面的案例,我们大致了解了Unity编辑器扩展的基本内容,通过这些已经可以实现很多功能了!

仓库地址:

https://github.com/wyy5552/unityEditor

unity 编辑器扩展简单入门的更多相关文章

  1. Unity编辑器扩展 Chapter7--使用ScriptableObject持久化存储数据

    Unity编辑器扩展 Chapter7--使用ScriptableObject持久化存储数据 unity unity Editor ScirptableObject  Unity编辑器扩展 Chapt ...

  2. Unity编辑器扩展chapter1

    Unity编辑器扩展chapter1 unity通过提供EditorScript API 的方式为我们提供了方便强大的编辑器扩展途径.学好这一部分可以使我们学会编写一些工具来提高效率,甚至可以自制一些 ...

  3. PHP中的IMAP扩展简单入门

    对于邮件处理来说,大家比较熟悉的应该是 POP3 . SMTP 这类的协议,而今天我们介绍的 IMAP 其实也是非常常用的一种邮件处理协议.它和 POP3 比较类似,都是以接收处理邮件为主.不过相对于 ...

  4. Unity编辑器扩展Texture显示选择框

    学习NGUI插件的时候,突然间有一个问题为什么它这些属性可以通过弹出窗口来选中呢? 而我自己写的组件只能使用手动拖放的方式=.=. Unity开发了组件Inspector视图扩展API,如果我们要写插 ...

  5. Unity 编辑器扩展

    自定义检视面板的使用: 先是定义一个脚本文件,我们来修饰它的检视面板: [HelpURL("http://www.baidu.com")] public class Atr : M ...

  6. Unity 编辑器扩展 场景视图内控制对象

    http://blog.csdn.net/akof1314/article/details/38129031 假设有一个敌人生成器类,其中有个属性range用来表示敌人生成的范围区域大小,那么可以用O ...

  7. Unity编辑器扩展

    在开发中有可能需要自己开发编辑器工具,在Unity中界面扩展常见两种情况,拿某插件为例: 1,自建窗口扩展 2,脚本Inspector显示扩展 不管使用那种样式,都需要经常用到两个类EditorGUI ...

  8. unity编辑器扩展学习

    扩展编辑器实际上就是在unity菜单栏中添加一些按钮,可以一键执行一些重复性的工作. 一.添加按钮 1.简单使用MenuItem特性 using UnityEngine; using UnityEdi ...

  9. Unity 编辑器扩展 Chapter2—Gizmos

    二. 使用Gizoms绘制网格及矩阵转换使用 1. 创建Leve类,作为场景控制类: using UnityEngine; //使用namespace方便脚本管理 namespace RunAndJu ...

随机推荐

  1. 为什么Arrays.asList() 不能使用其修改方法(阿里开发手册里明确说明)

    Arrays.asList()方法把数组转换成集合时,不能使用其修改集合相关的方法,它的add/remove/clear方法会抛出UnsupportedOperationException(),我们来 ...

  2. linux下yum无法安装lrzsz,Error: Failed to download metadata for repo ‘appstream‘: Cannot prepare internal

    镜像下载.域名解析.时间同步请点击阿里云开源镜像站 linux虚拟机上准备安装一下rz sz,执行yum命令后提示如下: [root@tony001 ~]# yum install lrzsz Cen ...

  3. 内网穿透工具--frp

    对于没有公网 IP 的内网用户来说,远程管理或在外网访问内网机器上的服务是一个问题. 今天给大家介绍一款好用内网穿透工具 FRP,FRP 全名:Fast Reverse Proxy.FRP 是一个使用 ...

  4. Struts2搭建及利用OGNL表达式弹出计算器

    0x01 环境搭建 1.创建Struts2应用 创建一个动态网站项目 2.配置Tomcat启动环境 3.在WebContent目录下的WEB-INF文件夹中创建web.xml,Tomcat启动时会加载 ...

  5. Nebula Graph 在网易游戏业务中的实践

    本文首发于 Nebula Graph Community 公众号 当游戏上知识图谱,网易游戏是如何应对大规模图数据的管理问题,Nebula Graph 又是如何帮助网易游戏落地游戏内复杂的图的业务呢? ...

  6. CLion入门教程

    1. 说点什么 以下我将介绍地表最强(可能是之一,别打我) C/C++ 开发 IDE--CLion,以及如何使用它来快乐刷题. 工欲善其事,必先利其器.一个好的编程工具对写代码或是做题来说格外重要,尤 ...

  7. Mac安装和配置Maven 及其第二次启动报错问题解决

      1.下载安装 下载地址: https://maven.apache.org/download.cgi 下载后解压下来重名名为ApacheMaven,并放入到/usr/local/下 2.配置环境变 ...

  8. 为什么 wait(), notify()和 notifyAll ()必须在同步方法或 者同步块中被调用?

    当一个线程需要调用对象的 wait()方法的时候,这个线程必须拥有该对象的锁,接 着它就会释放这个对象锁并进入等待状态直到其他线程调用这个对象上的 notify() 方法.同样的,当一个线程需要调用对 ...

  9. linux-安装zookeeper及相关操作

    下载两个安装包并解压: 配置jdk环境变量: [root@VM-0-10-centos zookeeper]# cat /root/.bash_profile # .bash_profile # Ge ...

  10. C++面试问题汇总

    作者:勿忘心安~~链接:https://www.nowcoder.com/discuss/197611来源:牛客网 1 C++基础: (1)多态是怎么样的?写个样例? https://www.cnbl ...