Yilin army's gray charm||10589 views|Unity (315) mobile application (31) Technology Development (16)0
In this article of Unity C #, you will create a simple data structure and write down its property drawer.
Next you will learn how to create.
- Use a serialized class
- Create a custom property drawer
- Use serialized attributes
- Use Unity's immediate window GUI mode in the editor
Before that, you need to understand the Unity editor and some Uinty C # scripts. If you have learned some other courses, this will make it easier for you to get started.
This article is applicable to Unity 4.3 or later. The old version can still be found here.
Color point to be compressed
Color point
Unity has many types of data. You can use this data to create many custom components. But sometimes we need some small custom data, which can be used in many places. Instead of repeatedly writing the same code, it is better to select some data classes that can be reused and can be easily encapsulated, such as some built-in data types.
We will create some color points. The data structure includes both colors and positions.
Create a new empty project, add a new C # script named ColorPoint, and add the required variables.
1234567 |
using UnityEngine; public class ColorPoint { public Color color; public Vector3 position; } |
Then we create a class named ColorPointTester to test the data type we just created. We will give it a separate vertex vector and an array vector, and compare a separate vertex vector and an array vector. Then we create an empty game object and add it to it.
123456789101112 |
using UnityEngine; public class ColorPointTester : MonoBehaviour { public ColorPoint point; public ColorPoint[] points; public Vector3 vector; public Vector3[] vectors; } |
Color point and empty tester.
The new data type cannot be seen in inspector because its content cannot be saved. To solve this problem, we need to add this data type to the system. After being serialized, it belongs to our class. In this step, this class may have to serialize data streams in all public places before they can be stored.
123456789 |
using UnityEngine; using System; [Serializable] public class ColorPoint { public Color color; public Vector3 position; } |
Now the custom data can be displayed in the inspector, and can be edited and saved anywhere. Similarly, we drag our test object to the project view preset, and then change some variable instances in the scene. This proves that such data can run normally in the preset.
A normal object and an adjusted instance preset. Inspector looks messy. This can be modified to make it wider by dragging, but if its width is too large, the vector will crash.
A full inspector.
Drawing Properties
Unfortunately, even with a wide inspector, we still need multiple lines of color points.
Fortunately, we can use custom variables to replace the default drawing properties of Unity in editing. You can create a class by extending UnityEditor. PropertyDrawer, and use UnityEditor. CustomPropertyDrawer to match the content we want to draw. Then, name a class named ColorPointDrawer. Because this is an edited class, we will put it in a new folder named Editor.
123456 |
using UnityEditor; using UnityEngine; [CustomPropertyDrawer( typeof (ColorPoint))] public class ColorPointDrawer : PropertyDrawer { } |
This is the property drawer that does not do any processing.
Now the inspector does not show anything useful, but we can change it. By overwriting the OnGUI, the property drawer of the custom version is used by default.
This OnGUI method has three parameters. The first is a giant, which tells us what properties should be drawn for the areas of those windows. The second is its own property, represented by a SerializedProperty. The third is GUIContent, which defines the attribute tag we should use.
Let's first use the GUIEditor. PropertyField method to locate the location, and then draw GUIEditor. PrefixLabel.
1234 |
public override void OnGUI (Rect position, SerializedProperty property, GUIContent label) { EditorGUI.PrefixLabel(position, label); EditorGUI.PropertyField(position, property.FindPropertyRelative( "position" )); } |
The overlapping label of the property drawer.
When we lock the position, its label is the color point of the overlapping label. Next, we will rewrite it by using GUIContent. none.
1234 |
public override void OnGUI (Rect position, SerializedProperty property, GUIContent label) { EditorGUI.PrefixLabel(position, label); EditorGUI.PropertyField(position, property.FindPropertyRelative( "position" ), GUIContent.none); } |
A label that still overlaps
The vector is still an overlapping label, because we use the same position rectangle. Next we will replace it with this rectangle.
1234 |
public override void OnGUI (Rect position, SerializedProperty property, GUIContent label) { Rect contentPosition = EditorGUI.PrefixLabel(position, label); EditorGUI.PropertyField(contentPosition, property.FindPropertyRelative( "position" ), GUIContent.none); } |
Even if the location is incorrect, it does not overlap.
This looks a lot better, but the array element where the location vector is placed is too far to the right. This occurs because the PropertyField method adjusts the indentation level of the current editor.
You can set the indent level by statically initializing the EditorGUI. indentLevel method. To temporarily remove auto indent, we only need to set it to zero.
12345 |
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); } |
Correct Positioning
Original article:Http://catlikecoding.com/unity/tutorials/editor/custom-data/
ModifyPrefix
When the prefix label turns to bold and the adjusted premade value is displayed, it cannot perform any operations. Therefore, we cannot immediately restore the entire color point or easily delete or copy the array elements of the prefix label.
We need to set the starting position for the attribute to take effect in the editor, because currently we only show a part of the content. We can use EditorGUI. Use the BeginProperty class function to create a new tag, mark the appearance of an attribute, and then use EditorGUI. The EndProperty class function is used to indicate the termination of the property. In this way, you can use context menu to obtain tags with the expected functions.
1234567 |
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(); } |
Recovery and array support
Add color
Now it is time to set the color attribute. To make it online, we must reduce the space occupied by vectors. Because the vector is composed of three parts and the color is the fourth part, we will place the vector in the first 75% horizontal space and the color in the remaining 25% space. We also use single-letter color labels.
1234567891011 |
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(); } |
Color, but incorrect.
Although our label is very short, it still occupies a lot of space, resulting in the color data being squeezed to the right. This is because the label width is fixed regardless of the content length. You can change the label width by adjusting EditorGUIUtility. labelWidth. Setting the width of 14 pixels is better.
123456789101112 |
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(); } |
Color labels of the right size.
Request an additional line
By default, pixels can be changed between a single row and two rows, depending on the width of the inspector. We can also do this.
We must overwrite the GetPropertyHeight method to obtain more vertical space. The default value of a row is 16 pixels. Adding a row requires an additional 18 pixels (including 16 pixels of the second row and 2 pixels of the distance between the two rows ).
When we use the inspector panel, the screen width actually contains its width, so we can use this. When the width is reduced to less than 333, the pixel will convert to the maximum number of rows, so we need to do the same.
123 |
public override float GetPropertyHeight (SerializedProperty property, GUIContent label) { return Screen.width < 333 ? (16f + 18f) : 16f; } |
Ask for more space.
When we reduce the inspector width to a certain extent, we can get more vertical space. However, we still cannot do this. To achieve this goal, we must pay attention to the following four points.
First, by checking the height of the position rectangle, we can find that we are using double rows. Second, we need to adjust the height back to 16 pixels so that the color attribute can be kept in the same row. Third, after the attribute label is painted, we must move it down one line. Fourth, by using the EditorGUI IndentedRect method, we must increase the level of first-level Indentation and apply it to position.
123456789101112131415161718 |
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(); } |
Use more space.
Now we have a brief description of the color point. It supports undo, redo, prefabs, and multi-object editing. If the inspector is wide enough, it occupies only one row. Otherwise, it occupies two rows.
The following editor tutorial involves the Custom List ).
Downloaded data
Custom-data.unitypackage
Completed projects.