这是我看到的一片比较完整的讲自定义窗口,自定义组件的教程,讲的比较详细,特地转过来给你们分享一下html
原文地址:https://mp.weixin.qq.com/s/4kporY-PCScRAESy4WSpmA
原文做者:克森
原文出处:微信公众号克森空间node
利用学到的东西制做本身的工具(自定义的窗口、Inspector、菜单等等)。编程
关于 Unity 内置属性能够从到官方文档中查询,本篇文章只介绍一些经常使用的内置属性,以下图所示:
接下来进行项目设置,建立一个空的 Unity 工程,名字由你来定,文件夹的层级关系以下:
目前还不须要Editor文件夹,可是先建立,日后的教程中会用到。而后再 Scripts 文件夹中建立一个新的 C# 脚本,命名为“People”,双击打开该脚本。数组
AddComponentMenu 属性容许将一个脚本添加到 Component 菜单中,而后你即可以经过 Component ->(你设置的名字)为一个选中的游戏对象建立该脚本,以下所示:微信
RequireComponent()属性会自动帮你添加你须要的组件,若是已经存在则再也不重复添加,且不能移除,以下所示:
提示:通过测试,我发现一个问题,若是脚本已经挂在物体身上,而后再修改脚本,为添加 RequireComponent 属性的话,彻底不起做用,所以建议你们在用此属性的时候要注意。ide
ContextMenu()属性容许添加一个命令到该组件上,你能够经过右键或者点击设置图标来调用到它(通常用于函数),且是在非运行状态下执行该函数,以下所示:函数
HelpURL()提供一个自定义的文档连接,点击组件上的文档图标既能打开到你指定的连接,以下所示:
提示:填写连接时,必定要写上 http:// 或者 https://,不然将无任何反应。工具
具体操做以下所示:oop
简单的分解一下:
1.第9行,咱们使用了 [Header(“BaseInfo”)] 为其设置了标题(为“BaseInfo”),如上图所示。布局
2.第10行,咱们使用了 [Multiline(5)] 为其 name 属性添加了5行输入,如上图所示,明显输入框变大了。
3.第12行,咱们使用了 [Range(-2,2)] 为其 age 属性指定了一个(-2,2)的范围,而且为其添加了一个滑块,如上图所示。
Tooptip()属性用于在 Inspector 面板中,当鼠标停留在设置了Tooptip()的属性添加指定的提示;Space()用于为在 Inspector 面板两属性之间添加指定的距离,以下所示:
仍是使用上一篇的 Unity 工程,而后在 Scripts 文件夹里建立一个新的 C# 脚本,命名为“Player”,而后双击打开脚本,而后为其添加以下代码:
Player 类记录了 Player 的一些基础信息,例如:ID、名字、背景故事、生命值、伤害等等。
自定义 Inspector 属性面板的一些基础知识,和注意事项以下图所示:
传送门: http://www.ceeger.com/Script/Editor/Editor.html
接下来开始制做的咱们本身的 Inpector,对于自定义 Inpector 面板可参考下图的API:
传送门:http://www.ceeger.com/Script/EditorGUILayout/EditorGUILayout.BeginVertical.html
如今,请你在 Editor 文件夹中建立一个新的 C# 脚本,双击就打开该脚本,并为其添加以下代码:
Okey,接下来一一分析一下
默认的界面布局就是垂直布局,可是为了节目效果,咱们仍是把它写上比较好,设置元素为垂直布局需使用这对兄弟来声明:
EditorGUILayout.BeginVertical(); EditorGUILayout.EndVertical();
在这对兄弟里面作的布局都是以垂直方向来排列的。
如上图所示,整个页面元素都是以垂直方向来布局的。
设置元素为水平布局需使用这对兄弟来声明:
EditorGUILayout.BeginHorizontal(); EditorGUILayout.EndHorizontal();
在这对兄弟里面作的布局都是以水平方向来排列的。
因为咱们在上图圈选的地方使用了 Horizontal 这对兄弟,所以在这对兄弟里的元素全是以水平方向排列。
使用 EditorGUILayout.Space() 可在两个元素之间空出一行。
绘制字段用到如下几个方法:
EditorGUILayout.LabelField()标签字段 EditorGUILayout.IntField() 整数字段 EditorGUILayout.FloatField() 浮点数字段 EditorGUILayout.TextField() 文本字段 EditorGUILayout.Vector2Field() 二维向量字段 EditorGUILayout.Vector3Field() 三维向量字段 EditorGUILayout.Vector4Field() 四维向量字段
它们的规律就是方法名都是以 Field 结尾,大伙们能够根据绘制的类型选择相对应的方法。
通常括号里面的参数,第一个为绘制该字段的名字(string 类型),第二个为绘制该字段的值,以下所示:
1 为标签字段
2 为整形字段
3 为文本字段
4.为文本区域
滑块:EditorGUILayout.Slider()
EditorGUILayout.Slider()用于绘制一个滑块,从上可知:
第一个参数是滑块的名字
第二个参数是滑块要改变的值
第三和第四个参数是滑块的范围
效果以下图所示:
进度条:EditorGUI.ProgressBar()
EditorGUI.ProgressBar()用于绘制一个进度条,从上可知:
第一个参数是设置进度条的大小,类型是一个 Rect。
第二个参数是设置显示的值,
第三个参数是设置进度条的名字
提示:
1.第一个参数,咱们使用了 GUILayoutUtility.GetRect() 工具类的 GetRect()方法返回一个设置好的矩形框,在案例里咱们设置了一个 50*50 大小的矩形框。
2.第二个参数,咱们使用 player.health / 100.0f。那是由于进度条的最大值为1,若是不除100的话,当滑块的值为1时,进度条便填满了,所以咱们想让值与进度条的比例同步,那就除100吧(语文很差,不知道解释得如何)。
效果图:
帮助框:EditorGUILayout.HelpBox()
EditorGUILayout.HelpBox()用于绘制一个盒子(也能够看做矩形框),而后再盒子的里面显示提示信息,从上图可知:
第一个参数是传入提示信息
第二个参数是提示信息的类型
效果图:
错误类型
正常类型
警告类型
在以前的项目中,找到 Editor 文件夹,而后建立一个新的 C# 脚本,命名为“MyFirstWindow”,而后双击打开脚本,添加以下代码:
传送门:http://www.ceeger.com/Script/EditorWindow/EditorWindow.html
传送门:http://www.ceeger.com/Script/GUILayout/GUILayout.html
以上是咱们这个案例中主要用到的几个类。
属性
首先声明了三个变量:
设置窗口的名字
如代码注释所示,利用构造函数来设置窗口的名字。比较陌生的是 titleContent属性 和 GUIContent 类,简单了解以下图所示:
GUIContent 界面内容类
titleContent 属性
这个构造函数所产生的做用以下图所示:
设置窗口的名字
这个函数用于在菜单栏上添加一个打开该窗口的的菜单选项。比较陌生的是 [MenuItem()] 属性 和 GetWindow()函数,简单了解以下图所示:
[MenuItem()] 属性须要注意的两点(上图也有提示):
1.必须是放在 Assets / Editor 文件夹下的类,且使用了 using UnityEditor
2.调用的函数必须是静态函数(static)
该函数就是用于返回一个窗口对象(就是打开一个窗口)。
绘制窗口元素须要在 OnGUI() 函数里面设计,接下来咱们一一分解。
步骤:
1.GUILayout.Space(10),这个有说过,让两个元素之间空十个像素之间的距离
2.GUI.skin.label.fontSize 、GUI.skin.label.alignment 用于设置标题的字体大小和对齐格式,具体从下图中了解:
对于 GUI.skin API 里面没有列出一些关于皮肤的属性,可是大伙们能够经过在Assets 菜单下右键 Create => GUI skin,以下图所示:
想对应的属性全在里面
3.利用 GUILayout.Label() 来绘制标题
整个代码的效果以下图所示:
好吧,似曾相识,所以不在赘述,效果以下所示:
在这段代码中,比较陌生的也就是 EditorSceneManager.GetActiveScen().name,咱们先看下图进行简单的了解:
其实就是返回当前编辑的场景信息(也就是返回 Scene 类型参数),而后利用 name 属性获取场景的名字,效果以下:
这段代码主要就是利用 System.DateTime.Now 获取当前时间,而后经过 GUILayout.Label() 把当前时间显示出来,对于 System.DateTime.Now 可从下面连接去了解:
https://msdn.microsoft.com/zh-cn/library/system.datetime.now(v=vs.110).aspx
效果图以下:
#####绘制对象槽
咱们先看看API:
从上图可知:
1.第一个参数用于设置卡槽的标题名字
2.第二个参数用于设置字段显示的物体
3.第三个参数用于设置显示的类型
4.第四个参数用于设置是否容许指定场景中的物件
效果以下:
好的,这段代码咱们也介绍过了,直接上效果图:
其实很简单,不外乎就是添加一个按钮呗。在咱们的代码中,用了一个 if 判断语句来判断,当咱们点击该按钮时所触发的事件(该函数的返回值是一个 bolol 类型),在代码中克森也上好备注了,所以也没有什么难的,直接上效果图:
#####SaveBug() 函数
其实这个函数所作的事情也很简单,就是把咱们设置好的一些参数保存到一个文本文件(.txt文件)上,仅此而已。
步骤以下:
1.第一行,利用 Directory 类建立一个目录
2.建立一个写入流类(StreamWriter)
3.而后把设置好的各个参数写入文件中
还不了解 C# 文件操做的朋友,是时候返回去补补了,API 连接以下:
https://msdn.microsoft.com/zh-cn/library/system.io.directory(v=vs.110).aspx
https://msdn.microsoft.com/zh-cn/library/system.io.streamwriter(v=vs.110).aspx
具体操做以下所示:
而后你便能在 Assets 文件夹看到以下图所示信息:
其实这个函数所作的事情跟上面那个函数作的事情同样同样的,不外乎就对了一行代码,而这行代码即是得到游戏屏幕截图,仅此而已,经过下面 API 去了解:
具体操做和上面同样同样的,只不过多了同样图片,仅此而已,以下图所示:
好吧,至此咱们的这篇文章就结束了。
因为过久不更新,以前的项目不知道跑哪儿去了。让咱们从新建立一个新的项目,命名为“MyHandles”。而后建立三个文件夹,以下图所示:
接下来在Scripts文件夹中,建立一个C#脚本,并命名为“MyHandles”;而后在Editor文件夹中再建立一个C#脚本,命名为“HandlesInspector”;而后在将下面的小图标保存到Img文件夹中:
好了准备工做就绪,开始码了个码。
在这篇教程中,咱们主要用到 Handles 这个类,一下是该类的基本介绍,克森会挑出几个比较经常使用的属性和方法来制做一下简单的东西,其它属性和方法大伙们能够自行去尝试尝试:
API传送门:http://www.ceeger.com/Script/Handles/Handles.html
首先打开咱们的 MyHandles.cs 脚本,为其添加一个变量:
而后打开 HandlesInspector.cs 脚本,添加以下代码:
将这两个脚本保存,回到Unity中建立一个空物体,并为其添加 MyHandles.cs 脚本:
此时咱们观察场景,除了场景中出了 “MyHandles” 几个字外,彷佛啥事儿也没发生,不急,让咱们来调整调整 Area Radius 参数的值,便能看到以下效果:
代码很简单,注释也给你们弄上了,相信你们都能看懂吧。仍是不太懂的能够多看看API:
做用:这个东西是否是有点类型于碰撞体的那个框框啊,这玩意多用于制做AI,用于判断和指定UI影响范围用的。
打开 MyHandles.cs 脚本,添加以下变量:
而后为 HandlesInspector.cs 脚本添加以下代码:
这段代码呢也不难于理解,就是参数多了点
PS:因为中文版的介绍不全,因此补了一张官方的API。
做用:多用于绘制一些自定义的操做,好比Unity的粒子系统就用到了好多自定义的操做柄,好比粒子系统的Shape参数就用到了该函数的第五个参数来绘制:
打开 MyHandles.cs 脚本,添加以下变量:
而后为 HandlesInspector.cs 脚本添加以下代码:
回到场景中,此时大伙们会碰到这样的问题:
别担忧,那是由于你没有设置 nodePoints 属性,全部该函数访问到一个空的数组,所以便报出了老司机错误。以下图所示便OK:
这段代码简单了吧,也就两个参数,若是仍是不清楚的小伙伴能够多尝试尝试。
做用:这个能够用在AI上面,而后为每个AI添加一个位置操做柄,这样好像看上去方便很多吧?
打开 MyHandles.cs 脚本,添加以下变量:
而后为 HandlesInspector.cs 脚本添加以下代码:
一样的,会出现上面相似的错误,甚至更加严重,Scene视图直接白屏!!使用一样的解决方法便可,以下所示:
PS:nodePointsRotation的个数要与nodePoints的个数要相等或者小于nodePoints。
这段代码一样很简单了吧,也是两个参数,若是仍是不清楚的小伙伴能够多尝试尝试。
作一个操做,看看大伙们能不能看懂我想表达的意思:
是否是感受像是静止通常,一动不动的呢?下面修改一下代码:
此时,你会看到以下的错误,不要慌张,咱们只有越到错误,解决多了,那之后越到错误就不是什么可怕的事情了:
相信不少人都知道这个是什么错误吧,那是由于由三维向量转为四元素W的值不能为0,所以咱们只要把W设置为1便可,以下所示:
这个操做呢,主要是帮你们找出一些开发过程当中容易遗漏的错误,还有一个目的就是让坐标轴跟随着旋转而旋转(由于第二个参数是位置操做柄的旋转方向嘛,我把它改成了咱们设置好的旋转方向,所以位置操做柄便能跟随着咱们的旋转而旋转了)。
为 HandlesInspector.cs 脚本添加以下代码:
此时回到场景中便能看到以下所示:
这段代码呢,也很简单,可能有点不明白的也就是 Mathf.Repeat()函数,这个简单,看下图便能明白:
其实这样作的缘由大伙们都知道,就是为了防止下标越界。
打开 MyHandles.cs 脚本,添加以下变量:
而后为 HandlesInspector.cs 脚本添加以下代码:
其实也很容易理解,就是当showNodeHandles为false时便不执行 if 代码块里的代码,所以便没法绘制出位置操做柄和旋转操做柄咯,最终的效果以下:
为 HandlesInspector.cs 脚本添加以下代码:
回到场景便能看到以下图所示的界面:
这段代码呢,其实也很简单,不过是运用了两对函数。
第一对为:Handles.BeginGUI() 和 Handles.EndGUI()。这对函数表名你想要在Scene视图下绘制东西。
第二对为:GUILayout.BeginHorizontal() 和 GUILayout.EndHorizontal()。这对函数代表你想要以水平方向绘制东西。相信第二对函数大伙们都不陌生吧,记得在《Unity Editor 基础篇(三):Editor Window》中有介绍过。
里面的逻辑代码也很简单,那就是绘制一个按钮,当我点击时让 MyHandles.shoNodeHandles的值取反(也就是原来为true,点击后取反,便为false)。
补充:在第一对函数里得操做和自定义窗口里得操做几乎相同,你们能够参考下面得API去尝试尝试:
http://www.ceeger.com/Script/GUILayout/GUILayout.html
这个插件就用到了今天咱们学到的东西制做而成的:
好了,差很少就介绍到这里吧
在以前的项目或者新建的项目中建立以下目录结构:
若是是新的项目,只需建立Scripts和Gizmos就好。
该文章用的到API:
传送门:http://www.ceeger.com/Script/Gizmos/Gizmos.html
由上图可知,Gizmos是用于在场景视图可视化调试或辅助设置用的。
须要注意的是因此Gizmos的绘制必须在脚本的OnDrawGizmos或OnDrawGizmosSelected里编写,所以咱们的第一步即是在脚本中添加这两个函数。
在Scripts文件夹中建立一个C#脚本,命名为:“MyGizmos”,双击打开脚本,码入以下代码:
让咱们来测试一下:
咦,感受不对啊,感受不是每一帧都在调用啊!克森作了个测试,若是你在Scene视图下不作任何错误(鼠标滑动也不能调用这两个函数),这两个函数都没有调用(看来官方文档说得不彻底啊!!)。
无论了,总之大伙们知道是这么一回事儿就好了。
PS:必须于Scene视图下,于Game视图下不起做用。
接下来为“MyGizmos.cs”脚本添加以下代码:
好,如今回到场景视图下,以下图所示操做:
哦豁,咱们的线框球体便出来了,是否是很简单啊。
代码分析:
该函数的第一个参数是该线框球体的中心点位置,它是一个Vector3类型。
第二个参数是该线框球体的半径大小,它是一个float类型。
接下为咱们的脚本添加以下代码:
好,如今回到场景视图下,以下图所示操做:
哦豁,咱们的线条便出来了,是否是很简单啊。
代码分析:
上图已经解释得很是清楚,两个参数表示:从from起点到to位置绘制一条线。
所以第一个参数就是起点的位置,第二个参数就是指定的位置。
上面代码的意思就是当前的位置朝 Z-轴 正方向根据 size 的值扩大。
接下来为咱们的脚本“MyGizmos.cs”添加以下代码:
好,如今回到场景视图下,以下图所示操做:
如上图所示,咱们经过for循环调用Gizmos.绘制出了5个实心球体。
代码分析:
由上图可知。第一个参数是绘制该球体的中心点的位置,第二个参数是该球体的半径。
所以在咱们的代码中,利用for循环依据nodePoints参数建立多个球体,在上面的案例中克森建立了5个球体,设置它们的半径为0.5(大伙们也能够添加一个参数,进行动态操做半径值)。
因为绘制的东西都是一个色,很差辨别,大伙们能够添加以下代码:
添加后的效果:
咱们的球体变成了蓝色,咱们的线条编程了红色,未设置的线框球体仍是默认的白色。
PS:Gizmos.color = Color.blue,若是后续没有从新指定绘制的颜色,则使用最后一次设置的颜色。
接下来为咱们的脚本“MyGizmos.cs”添加以下代码:
回到场景中看看有什么效果:
好了,从上图中你们也知道咱们添加的这段代码的意思了吧。很简单,就是将这些球体给链接起来。
尴尬了,发现最后要将的东西已经在前面暴露出来了。。。就是下图的这个东西:
相信这个东西大伙们都知道怎么设置吧,不过为了该文章的完整性,咱们仍是来操做一遍:
好了,这个是手动设置的,那么代码中又是如何设置的呢?
请你们添加以下代码:
回到场景中,看看有什么效果发生。
咦,没有什么事情发生啊!!!
哦,原来是找不到图片资源。如上图所示,这就是为何文章的开头让大伙们建立 Gizmos 文件夹的缘由。如今将一张你喜欢的图标,命名为:“icon.jpg”放入Gizmos文件夹中。
PS:图片的命名必定要与代码中的第二个参数的名字同样。
####准备工做
建立一个新的工程或者用上一篇的工程均可以(克森是新建的工程),而后在Scripts文件夹中建立两个C#脚本,分别命名为:“Persion.cs”和“ShowPersionInfo.cs”,以下图所示:
而后在Editor文件夹中建立一个名为“PersionPropertiesDrawer.cs”的脚本,具体以下图所示:
首先,打开咱们得“Persion.cs”脚本,为其添加以下代码:
这段代码不用解释了吧,就是一个普通得类和枚举。接下来为咱们的“ShowPersionInfo.cs”脚本添加以下代码:
为何要这样呢?相信大伙们都知道,要想给一个游戏对象挂上脚本,那么该脚本就必须继承自 MonoBehaviour 。大伙们能够将“Persion.cs”挂到游戏对象上,便会出现以下图所示:
因此“ShowPersionInfo.cs”仅仅就是一个辅助类,做用就是将咱们的“Persion.cs”能挂到游戏对象上。
好了,接下来让咱们建立一个空的游戏对象,而且命名为“Persion”,而后为其添加“ShowPersionInfo.cs”脚本:
这什么都没有啊!!原来,咱们漏掉了一段代码,接下来让咱们为其补上:
原来呀,要想将一个普通的类里的属性在Inspector面板中显示出来,那么必须将这个普通的类序列化。
好了,让咱们回到 Unity 中,看看发生了什么变化。
Perfect!Persion类中的属性成功的显示在了Inspector面板上。
好,让咱们简单的了解一下,什么是序列化,以下图所示:
(图片来源于百度百科)
简单的理解就是,序列化类的时候是从属性读取值以某种格式保存下来,将其传输到另外一个地方去。那么呢,这个过程是交给Unity引擎来实现的,简单的了解就好了(也就是会用就好了)。
接下来就是本篇教程的核心了!!!
首先打开咱们的“PersionPropertiesDrawer.cs”脚本,为其添加以下代码:
让咱们的“PersionPropertiesDrawer.cs”继承自PropertyDrawer类,而后重写 OnGUI 和 GetProperties 函数。
添加 [CustomPropertyDrawer(typeof(Persion))],指定该类是用于自定义属性的绘制。
接下来让咱们来测试一下这些方法传入的参数都是作什么的,为咱们的脚本添加以下代码:
好,如今回到Unity看看测试的数据:
从上面的数据能够看出以下几点:
1.OnGUI 和 GetPropertyHeight 里的 property 参数是同一个参数。该参数里存放的是 Persion 里的属性信息。
2.OnGUI 和 GetPropertyHeight 里的 Label 参数也是同一个参数,该参数里存放的是 Persion 类的类名。
3.position参数指的是须要在Inspector面板中绘制的区域信息,能够从下面两张图中简单的了解一下:
PS:为了测试,注释了一些代码,而且添加了一个2D刚体组件。
对了还有一个地方遗漏掉了,那就是在Inspector面板中的一行高度为 16 。咱们能够从下图中得知。
好了,接下来就让咱们来绘制咱们Persion的属性吧。咱们的目标以下图所示:
下面看一看咱们的分析图:
好了,接下来就开始码咱们的代码,打开“PersionPropertiesDrawer.cs”,为其添加以下代码:
上面的代码呢,都有分析过了。也许会有一些小伙伴在两个地方上头晕,也就是【获取对应的序列化属性】和【绘制属性】这两个地方上弄不明白。其实很简单,从下面两张图中即可理解:
好了,让咱们回到Unity中,看看咱们的效果实现了没:
好的,很是完美的实现了。
至此,该篇文章就已经弄完了。
大伙们还记得《Unity Editor 基础篇(一):Build-In Attribute》里所说的东西吗?以下图所示:
建立一个新的工程或者用上一篇的工程均可以(克森用的是原来的工程),而后在Scripts文件夹中建立两个C#脚本,分别命名为:“ReadOnlyAttribute.cs”和“Test.cs”,以下图所示:
而后在Editor文件夹中建立一个名为“ReadOnlyAttributeDrawer.cs”的脚本,具体以下图所示:
首先,打开咱们得“ReadOnlyAttribute.cs”脚本,为其添加以下代码:
这段代码很简单,就是让咱们的“ReadOnlyAttribute”类继承自“PropertyAttribute”类,该类的解释以下图所示:
因此呢,由上图便能知道咱们接下来要作的事情了吧,那就是让咱们的“ReadOnlyAttributeDrawer”类继承自PropertyDrawer类,而后重写OnGUI和GetPropertyHeight方法,以下图所示:
上图的代码在上一篇都有讲解过,所以这里再也不作过多的赘述。
好的,接下来继续为咱们的“ReadOnlyAttributeDrawer.cs”的OnGUI方法添加以下代码:
在上面的代码中,咱们使用到了一个名为“SerializedPropertyType”的枚举,它存放的是序列化属性的类型,它包含的类型不少,可是在该篇文章中咱们只使用到了这几个,感兴趣的同窗看能够去尝试其它类型。
咱们使用该枚举为value获取相对应类型的值,而后使用一个Label在Inspector面板中绘制出来(\t为制表符,为了美化显示)。
好了,接下来打开咱们的“Test.cs”脚本,添加以下代码:
如今,让咱们回到Unity中查看一下效果:
这个。。。是否是很简单呀。接下来让咱们制做一个带有参数的。
让咱们打开咱们的“ReadOnlyAttribute.cs”,添加以下代码:
再让咱们为“ReadOnlyAttributeDrawer.cs”的OnGUI函数添加以下方法:
上面的代码相信大伙们都能看懂,惟一有点迷惑的可能就是 attribute 属性了,其实它就是咱们经过 [CustomPropertyDrawer(typeof(ReadOnlyAttribute))] 传过来的ReadOnlyAttribute类,所以克森Debug了它的类型名字,接下来让咱们看看打印出来的信息:
好的,就是咱们的 ReadOnlyAttribute 类。对了克森打印了 myAttribute.textColor 的值,是为了测试值是否正确的传入。
好了,接下来开始测试,让咱们为咱们的“Test.cs”脚本添加以下代码:
从上图可知,其实[ReadOnly(参数)] 传入的参数对应的就是咱们ReadOnlyAttribute类的构造函数须要传入的参数。
好了,接下来让咱们回到Unity中查看一下效果:
好了,大伙们能够看到,值已经完美的传入了,效果并非完美指望的那样。可是咱们的 My Int 的 Apha 值起做用了。
克森对于这个Bug弄了一个晚上,最后发现原来是Unity5.x出的BUG,总之克森今晚把Unity5.x版本都试得差很少了,仍是一个鸟样,最后Unity4.6版本妥妥得实现了咱们想要得效果,下面有两张图,一张是克森试过得版本,一张是Unity4.6实现得效果图:
(试过的版本)
(Unity4.6版本的效果)
好了,今天的教程就到这里吧
建立一个新的工程或者用上一篇的工程均可以(克森用的是原来的工程,由于这一篇的内容和上一篇的内容很相似),而后在Scripts文件夹中建立两个C#脚本,分别命名为:“DrawerImageAttribute.cs”和“Test.cs”,以下图所示:
而后在Editor文件夹中建立一个名为“DrawerImageAttributeDrawer.cs”的脚本,具体以下图所示:
首先,打开咱们得“DrawerImageAttribute.cs”脚本,为其添加以下代码:
这段代码很简单,就是让咱们的“DrawerImageAttribute”类继承自“PropertyAttribute”类,上一篇已经讲过,不了解的同窗能够去看《Unity Editor 基础篇(七):Property Attributes》
接下来,打开咱们的“DrawerImageAttributeDrawer.cs”脚本,为其添加以下脚本:
上图的代码除了红色框框里的东西,其它的在上一篇都有讲解过,所以这里再也不作过多的赘述。
好了,让咱们来分析分析 DecoratorDrawer 类是个什么东西,首先从字面上的意思就是:装饰绘制者。意味着它是用于装饰的。接下来让咱们看看它的源码:
从源码中咱们知道,它其实和上一篇的PropertyDrawer类差很少,都是继承自 GUIDrawer。只不过他的 OnGUI 方法的参数比 PropertyDrawer 的 OnGUI 方法的参数好了两个,仅此而已。
接下来让咱们为“DrawerImageAttributeDrawer.cs”添加以下代码:
上面的代码应该不难理解吧,就是判断图片是否存在,若是不存在就去Resources文件夹里读取对应的图片,而后调用 GUI.DrawTexture(position, image); 在Inspector面板中绘制该图片。
所以,接下来的操做相信大伙们都知道了吧。那就是建立Resources文件夹,而后将图片放入该文件夹中,修改相对应的名字,搞定!
接下来,让咱们回到Unity中查看效果:
咦,怎么回事儿,怎么那么难看?看到这里,相信看过上一篇文教的伙计们应该知道怎么作了吧?那就是修改咱们 GetHeight() 方法的返回值就好了呀。
让咱们回到咱们的“DrawerImageAttribute.cs”脚本中,为其添加以下代码:
接着回到“DrawerImageAttributeDrawer.cs”中,添加以下代码:
好了,接下来打开咱们的“Test.cs”脚本,添加以下代码:
如今,让咱们回到Unity中查看一下效果:
这…你坑我?不急不急,克森是故意这么作的,错误见多了那就不是错误了。
好,让咱们来解决这个错误。接下来为咱们的“DrawerImageAttributeDrawer.cs”脚本添加以下代码:
而后回到Unity中,看看测试的数据,分析出错缘由:
从上图中,咱们能够看出,该脚本先调用的是 GetHeight() 方法,所以当咱们在 GetHeight() 方法中使用 _attribute.height 的时候便会报空指针的错误,由于此时的 _attribute 尚未初始化,所以让咱们添加以下代码:
好了,接下来回到Unity中查看效果:
Perfect,漂亮的完成了。
好了,《Unity Editor 基础篇》系列结束了!!!太棒了