码迷,mamicode.com
首页 > 其他好文 > 详细

【Unity C#编程】自定义数据

时间:2014-06-15 22:39:05      阅读:290      评论:0      收藏:0      [点我收藏+]

标签:style   class   code   http   tar   ext   

译林军 灰魅|2014-03-04 10:52|10589次浏览|Unity(315)移动应用(31)技术开发(16)0

在这篇Unity C#的文章中,你将会创建一个简单的数据结构,然后写下它的属性抽屉。

下面你将会学到如何创建。

  • 使用一个序列化的类
  • 创建一个自定义的属性抽屉
  • 使用序列化属性
  • 在编辑器里面使用Unity的立即窗口GUI模式

在此之前,你需要了解Unity的编辑器,以及Uinty C#的一些脚本。如果你已经学习了一些其它的课程,这将会让你更加容易上手。

这篇文章适合Unity 4.3或者以上的版本。老版本仍然可以在这里找到。

bubuko.com,布布扣

被压缩的色点

色点

Unity有很多种类的的数据类型,你可以用这些数据去制作很多自定义组件。但是有时我们需要一些小的自定义数据,它可以在很多地方使用。与其重复写同样的代码,倒不如选择一些可以重复使用,而且十分简单的封装数据类,例如一些内置的数据类型。

我们将要创建一些色点,这个数据结构是同时包括颜色和位置。

我们首先创建一个新的空项目工程,然后添加一个名为ColorPoint的新的C#脚本,同时添加所需的变量。

1
2
3
4
5
6
7
using UnityEngine;
 
public class ColorPoint {
 
    public Color color;
    public Vector3 position;
}
然后我们再创建一个叫ColorPointTester的类来测试我们刚刚创建的数据类型。我们给它一个单独的点向量和一个数组向量,同时也比较单独的点向量和数组向量。接着我们创建一个空的游戏物体,把它添加到里面。
1
2
3
4
5
6
7
8
9
10
11
12
using UnityEngine;
 
public class ColorPointTester : MonoBehaviour {
     
    public ColorPoint point;
     
    public ColorPoint[] points;
     
    public Vector3 vector;
     
    public Vector3[] vectors;
}

bubuko.com,布布扣

色点和空测试器。

新的数据类型不能在inspector中看到,因为他的内容还不能被保存。我们要解决这个问题就要把这个数据类型添加到系统中。被序列化后属于我们的类.在执行这步是,这个类可能要在所有公共地方的数据流可以序列化,然后才能被存储起来。

1
2
3
4
5
6
7
8
9
using UnityEngine;
using System;
 
[Serializable]
public class ColorPoint {
     
    public Color color;
    public Vector3 position;
}
现在我们刚自定义的数据可以再inspector中显示了,我们可以再任何地方编辑、保存。同样的,把我们的测试对象通过拖拽到项目视图的预设中,然后在场景中改变一些变量的实例。这可以证明这类数据可以在预设中正常运行。

bubuko.com,布布扣

bubuko.com,布布扣

bubuko.com,布布扣

正常的对象和一个调整的实例预设。inspector看起来很混乱。这可以有所修改,让它通过拖动变宽一些,但如果它的宽度过大,向量将会崩溃。

bubuko.com,布布扣

一个充实的inspector。

绘图属性

很可惜,即使有较宽的inspector,我们仍需要多行色点。

幸运的是,我们可以用自定义的变量在编辑中替换Unity的默认绘图属性。这可以通过扩展UnityEditor.PropertyDrawer来创建一个类,同时用 UnityEditor.CustomPropertyDrawer来匹配我们想要绘制的相关内容。然后,命名一个叫ColorPointDrawer的类,因为这是一个编辑的类,我们会把它放在一个叫Editor新的文件夹里面。

1
2
3
4
5
6
using UnityEditor;
using UnityEngine;
 
[CustomPropertyDrawer(typeof(ColorPoint))]
public class ColorPointDrawer : PropertyDrawer {
}

bubuko.com,布布扣

bubuko.com,布布扣

这是不做任何处理的属性抽屉。

现在inspector不再显示任何有用的东西,但是我们可以改变,通过覆盖在OnGUI上,来默认自定义版本的属性抽屉。

这个OnGUI方法有三个参数。第一个是一个巨型,它是告诉我们那些窗口的区域是应该使用什么来绘制属性。第二个是自身的属性,由一个SerializedProperty来表示。第三个是GUIContent,定义了我们应该使用的属性标签。

让我们首先用GUIEditor.PropertyField的方法找准位置,然后绘制GUIEditor.PrefixLabel。

1
2
3
4
public override void OnGUI (Rect position, SerializedProperty property, GUIContent label) {
        EditorGUI.PrefixLabel(position, label);
        EditorGUI.PropertyField(position, property.FindPropertyRelative("position"));
    }

bubuko.com,布布扣

属性抽屉的重叠标签。

当我们锁定位置后,它的标签就是重叠标签的色点。接下来,我们要通过用GUIContent.none.来重写它。

1
2
3
4
public override void OnGUI (Rect position, SerializedProperty property, GUIContent label) {
    EditorGUI.PrefixLabel(position, label);
    EditorGUI.PropertyField(position, property.FindPropertyRelative("position"), GUIContent.none);
}

bubuko.com,布布扣

一个依旧重叠的标签

向量仍然是重叠标签,因为我们使用的是同样的位置矩形,接下来,我们将用这个矩形进行替换。

1
2
3
4
public override void OnGUI (Rect position, SerializedProperty property, GUIContent label) {
    Rect contentPosition = EditorGUI.PrefixLabel(position, label);
    EditorGUI.PropertyField(contentPosition, property.FindPropertyRelative("position"), GUIContent.none);
}

bubuko.com,布布扣

即使不正确的定位,也不再重叠。

这看起来好了很多,但放置位置向量的数组元素太过于偏右。导致这个发生的原因是PropertyField方法调整当前的编辑器缩进级别。

通过静态初始化EditorGUI.indentLevel的方法,设置缩进的级别。为了暂时的消除自动缩进,我们只要将其设置为零即可。

1
2
3
4
5
public override void OnGUI (Rect position, SerializedProperty property, GUIContent label) {
    Rect contentPosition = EditorGUI.PrefixLabel(position, label);
    EditorGUI.indentLevel = 0;
    EditorGUI.PropertyField(contentPosition, property.FindPropertyRelative("position"), GUIContent.none);
}

bubuko.com,布布扣

正确定位

原文链接:http://catlikecoding.com/unity/tutorials/editor/custom-data/

修改Prefix

当prefix标签变成粗体,显示调整过的预制值时,它就无法进行任何操作。所以我们既不能立即恢复整个弹辨色点(color point),也不能轻易删除或复制prefix标签的数组元素。

我们需要在编辑器中设定属性生效的起始位置,因为目前我们仅仅展示了一部分内容。我们可以使用EditorGUI。利用BeginProperty类函数创建一个新标签,并标志着一个属性的出现,然后使用EditorGUI。利用EndProperty类函数表示属性的终止。这样我们就可以通过上下文菜单(context menu)获得拥有预期功能的标签。

 

1
2
3
4
5
6
7
public override void OnGUI (Rect position, SerializedProperty property, GUIContent label) {
        label = EditorGUI.BeginProperty(position, label, property);
        Rect contentPosition = EditorGUI.PrefixLabel(position, label);
        EditorGUI.indentLevel = 0;
        EditorGUI.PropertyField(contentPosition, property.FindPropertyRelative("position"), GUIContent.none);
        EditorGUI.EndProperty();
    }

 

bubuko.com,布布扣

恢复及数组功能支持

添加颜色

现在该设定颜色属性了。为了使其在一条线上,我们必须减少矢量所占空间。由于矢量由三部分组成而颜色作为其第四部分,我们将把向量置于前75%的水平空间,把颜色置于其余的25%空间中。我们也使用单字母命名颜色标签。

 

1
2
3
4
5
6
7
8
9
10
11
public override void OnGUI (Rect position, SerializedProperty property, GUIContent label) {
        label = EditorGUI.BeginProperty(position, label, property);
        Rect contentPosition = EditorGUI.PrefixLabel(position, label);
        contentPosition.width *= 0.75f;
        EditorGUI.indentLevel = 0;
        EditorGUI.PropertyField(contentPosition, property.FindPropertyRelative("position"), GUIContent.none);
        contentPosition.x += contentPosition.width;
        contentPosition.width /= 3f;
        EditorGUI.PropertyField(contentPosition, property.FindPropertyRelative("color"), new GUIContent("C"));
        EditorGUI.EndProperty();
    }

bubuko.com,布布扣

带颜色,但有误。

尽管我们的标签很短,但是它依然占据较多空间,导致颜色数据被挤到右侧。这是因为无论内容长短,标签宽度都是固定的。你可以通过调整EditorGUIUtility.labelWidth.改变标签宽度。设置14个像素的宽度效果更佳。

 

1
2
3
4
5
6
7
8
9
10
11
12
public override void OnGUI (Rect position, SerializedProperty property, GUIContent label) {
        label = EditorGUI.BeginProperty(position, label, property);
        Rect contentPosition = EditorGUI.PrefixLabel(position, label);
        contentPosition.width *= 0.75f;
        EditorGUI.indentLevel = 0;
        EditorGUI.PropertyField(contentPosition, property.FindPropertyRelative("position"), GUIContent.none);
        contentPosition.x += contentPosition.width;
        contentPosition.width /= 3f;
        EditorGUIUtility.labelWidth = 14f;
        EditorGUI.PropertyField(contentPosition, property.FindPropertyRelative("color"), new GUIContent("C"));
        EditorGUI.EndProperty();
    }

 

bubuko.com,布布扣

尺寸正好的颜色标签。

索取额外一行

默认像素可以在单行与双行之间转变,这取决于inspector的宽度。我们也可以这么做。

我们必须覆盖GetPropertyHeight method,争取更多的垂直空间。一行的默认值是16个像素。再添加一行需要另外18个像素(包括第二行自身的16个像素及两行间距的2个像素)。

当我们使用inspector面板时,屏幕宽度实际上就包含它的宽度,所以我们可以利用这一点。当宽度减小到333以下时,像素会转换至多行,因此我们也要这么做。

 

1
2
3
public override float GetPropertyHeight (SerializedProperty property, GUIContent label) {
        return Screen.width < 333 ? (16f + 18f) : 16f;
    }

 

bubuko.com,布布扣

索取更多空间。

当我们把inspector宽度调小到一定程度时,就能获得更多的垂直空间。然而,我们尚且还不能这么做。为了实现这一目标,我们必须注意以下四点内容。

第一,通过检查position长方形的高度,可以发现我们正在使用双行。第二,我们需要将高度调回到16个像素,以便颜色属性能够保留在同一行。第三,画完属性标签后,我们必须将其下移一行。第四,通过利用EditorGUI IndentedRect method,我们必须增加一级缩进级别,将其应用至position。

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public override void OnGUI (Rect position, SerializedProperty property, GUIContent label) {
        label = EditorGUI.BeginProperty(position, label, property);
        Rect contentPosition = EditorGUI.PrefixLabel(position, label);
        if (position.height > 16f) {
            position.height = 16f;
            EditorGUI.indentLevel += 1;
            contentPosition = EditorGUI.IndentedRect(position);
            contentPosition.y += 18f;
        }
        contentPosition.width *= 0.75f;
        EditorGUI.indentLevel = 0;
        EditorGUI.PropertyField(contentPosition, property.FindPropertyRelative("position"), GUIContent.none);
        contentPosition.x += contentPosition.width;
        contentPosition.width /= 3f;
        EditorGUIUtility.labelWidth = 14f;
        EditorGUI.PropertyField(contentPosition, property.FindPropertyRelative("color"), new GUIContent("C"));
        EditorGUI.EndProperty();
    }

 

bubuko.com,布布扣

利用更多空间。

现在,我们对弹辨色点(color point)有了一个精彩简短的描述。它支持取消(undo),重写(redo),预制(prefabs)以及多目标编辑。如果inspector足够宽,它只占一行,否则,占两行。

接下来的editor教程涉及自定义列表(Custom List)。

已下载的数据资料

custom-data.unitypackage

已完成的项目。

【Unity C#编程】自定义数据,布布扣,bubuko.com

【Unity C#编程】自定义数据

标签:style   class   code   http   tar   ext   

原文地址:http://www.cnblogs.com/forlove/p/3785289.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!