Unity拥有非常丰富的拓展编辑器接口,如果是在网上下载过别人写的插件,你会发现为什么它的监测面板视图和普通的不一样?其实是他通过代码自己绘制的监测面板,这篇博文MOMO带大家来学习编辑器。如下图所示,这是我通过代码拓展的面板视图。
下一条简单的脚本,绑定挂在摄像机上。
1 2 3 4 5 6 7 8 9 10 |
using UnityEngine; using System.Collections; public class Test : MonoBehaviour { public Rect mRectValue ; public Texture texture; } |
如图所示,在监测面板视图中它是一个很普通的结构。
下面我们需要在代码中动态的编辑它。请在你的Project视图中创建一个Editor文件夹,如果有的话就不用创建。把脚本MyEditor放进Editor文件夹中。
MyEditor.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
using UnityEditor; using UnityEngine; //自定义Tset脚本 [CustomEditor(typeof(Test))] //在编辑模式下执行脚本,这里用处不大可以删除。 [ExecuteInEditMode] //请继承Editor public class MyEditor : Editor { //在这里方法中就可以绘制面板。 public override void OnInspectorGUI() { //得到Test对象 Test test = (Test) target; //绘制一个窗口 test.mRectValue = EditorGUILayout.RectField("窗口坐标", test.mRectValue); //绘制一个贴图槽 test.texture = EditorGUILayout.ObjectField("增加一个贴图",test.texture,typeof(Texture),true) as Texture; } } |
编辑器的用法非常简单,OnInspectorGUI()方法中可以绘制控件,EditorGUI和EditorGUILayout可创建编辑器控件,和GUI的用法非常相像。如图所示,在回到Test的面板中,新的面板已经映入眼帘。对于其它控件的使用,大家可以自行去API中查阅,。原理都差不多。
值得一提的是C#语言提供了一个非常赞的方法,它可以让你的数据更加的安全,并且可以在Get Set方法中监听到你获取与赋值的操作,推荐使用这种方法。简单的改一下Test.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
using UnityEngine; using System.Collections; public class Test : MonoBehaviour { [HideInInspector][SerializeField] Rect pRectValue ; public Rect mRectValue { get { return pRectValue; } set { pRectValue = value; } } [HideInInspector][SerializeField] Texture pTexture ; public Texture texture { get { return pTexture; } set { pTexture = value; } } } |
举例说明一下 [HideInInspector][SerializeField] 隐藏数据在面板,并且序列化。它可以帮我们永久保存数据,如果不加的话数值就会重置。就好比我先添加了一个贴图,一运行游戏刚刚添加的贴图就变成null了。
还是以texture为例,当我们使用texture对象的时候,它会进入get板块快获取私有变量pTexture的值。当编辑器更改texture的时候,会进入set版块,将数值保存在pTexture中。这样你的数据会更加安全,因为这里操作的是当前类中的一个私有变量。也可以在get/set版块中加入一些特殊的代码。
最后在update()或者OnGUI中就可以直接用texture 对象了。当然也可以是你定义的任意对象。
最后是本文的下载 http://vdisk.weibo.com/s/xbzrt
欢迎大家踊跃留言,一起讨论学习。
- 本文固定链接: https://www.xuanyusong.com/archives/2202
- 转载请注明: 雨松MOMO 于 雨松MOMO程序研究院 发表
现在是2023年来看这个,依然很有帮助
MOMO,貌似下载链接已失效
unity 5.x 没OnInspectorGUI函数了吧?提示override OnInspectorGUI失败
去Editor里找,你报错肯定不是这个原因
你看下 你的类,继承的是不是 Editor
讲讲 reorderableList 吧,这个很有用的,还有,如果List中的元素又包含一个List元素,如何显示了?
请问一下,momo,我想问有没有个东西是可以监测Unity挂载控件。比如我想在个Gameobject挂载个5.3.3版本的Image控件或创建一个Image对象时把它的Raycast Target设为false
抱歉,补充一下我的Unity版本是5.3.5的,上面的5.3.3是错误的
请教一下,在UnityEditor开发过程中,在修改资源或着代码时,会出现重新编译,除Unity自带的数据类型和C#自带的基本数据类型外,其它如list,dictionary都会在重新编译的过程中被回收,请问这种情况要怎么处理?
要把 数据序列化在prefab或者scene 再或者asset里。。 不然 关了unity或者 重新选择gameobject数据都会没
雨松你好,我想请问下,我在Inspector中通过EditorGuiLayout.ObjectField扩展了一个功能,当我选中某个对象a,往这个ObjectField里拖拽了另一个对象b,但是当我取消选中a后再选中,之前ObjectField里已经拖拽过的对象b就没有了,这个有什么解决方法吗?尝试使用了[HideInInspector][SerializeField]也没有效果
没有被序列化上,你这个是序列化在prefab上吧
嗯,确实是犯傻了,后来解决啦,非常感谢。
另外还想顺便请教一个问题,使用GuiLayout.BeginHorizontal来布局的组件,位置总是有点乱(例如一个label加一个ObjectField,ObjectField框的左侧位置总是跟系统本身的不一样),也尝试了设置GuiLayout.MinWidth或者GuiLayout.MaxWidth来约束,但是貌似跟Inspector里默认的那些属性排版有区别,特别是在拖拽Inspector框宽度的时候。
请问怎么动态显示参数呢,比如在InInspector勾选其它选项时,动态加载其它选项?
我想问一下。就是这个,EditorGUILayout.IntPopup,,我想做一个下拉菜单。继承的是Editor。 在这个下面执行的。public override void OnInspectorGUI()。面板上是显示了。但是下拉后,选择后没有反应,总是显示的默认的那一个。下面是我的代码。public class test : Editor{ public override void OnInspectorGUI() { Test t = (Test)target; int [] a = {1,2,3}; string [] b = {“a”,”b”,”c”}; t.w = EditorGUILayout.IntPopup(“aa”,1, b,a); }}
请教下,我在脚本中通过sprite.create来截取一个spritesheet中的一部分当作游戏对象,但是只有在游戏运行后才能看到效果,没运行时scene场景中还是spritesheet整张,我怎样做才能在修改完脚本中的变量后自动更新scene视图中的对象呢?
加editor脚本, 这样不用运行也可以执行一些代码~~
请问一下雨松大人,Transform组件中的rotation字段怎么用这个办法来处理,我试过position和scale都可以,但是rotation是四元数死活不行╮(╯▽╰)╭。
您好MOMO,我最近想编写一个Scene视图的菜单,仿照Maya的8方向快捷菜单做的在Maya默认情况下按住Shift键 鼠标右键能唤出8方向创建快捷键,此时拖动鼠标会有一根线从中心绘制到鼠标的位置以提示用户当前鼠标松开后可能会调用的指令是什么上述操作我已经完成了,但是最后一步,画线没想到什么好的办法,因为用Handles绘制线条是以世界坐标来绘制的,在该情况下又拿不到任何相机进行坐标转换,怎么办呢?
您好MOMO,我最近想编写一个Scene视图的菜单,仿照Maya的8方向快捷菜单做的在Maya默认情况下按住Shift键+鼠标右键能唤出8方向创建快捷键,此时拖动鼠标会有一根线从中心绘制到鼠标的位置以提示用户当前鼠标松开后可能会调用的指令是什么上述操作我已经完成了,但是最后一步,画线没想到什么好的办法,因为用Handles绘制线条是以世界坐标来绘制的,在该情况下又拿不到任何相机进行坐标转换,怎么办呢?
我的Test脚本中有一个数组,MyEditor中有一个按钮来添加这个数组的数量,但是一运行,组件上的数组就空掉了。这个问题怎么解决啊
为什么我按照上面的写了,运行没反应的呀而且我也下载您提供的例子,导入运行也没什么东西出现的呀
请教个问题,我按照你说的方法试了一下,出现两个错误,1parsing error.2 newline in constant , 我用3.5ob6 , 是否版本有问题?代码片段为Myeditor。
如果不加的话数值就会重置。就好比我先添加了一个贴图,一运行游戏刚刚添加的贴图就变成null了。此话何解,运行游戏不会把贴图置null吧。
看来还得学学C#啊,顶你,MOMO神
加油学C#吧。。
加油 小伙子!!
嗯!
转!
谢谢小马。。