iT邦幫忙

0

[Unity] Custom PropertyDrawer for a class with an array

  • 分享至 

  • twitterImage
  •  

當一個陣列B的長度是等於另一個變數A裡的值。不做額外處理的話,必須隨時注意A與B是否相同。為了方便及穩定性,不彷自訂一個class包含變數變數A與陣列B,並為此class訂做一個PropertyDrawer,如此一來,既自動又正確。先附上圖說明before與After。

範例目標 (MeshRenderer上的Materials有幾個,陣列長度就是多少)

Before (指定完MeshRenderer後,還需要指定陣列長度)

After (指定完MeshRenderer後,自動根據Materials初始化陣列)

範例程式碼 (Sample.cs)

using System;
using UnityEngine;

public enum State { _1, _2, _3 }

// Custom serializable class
[Serializable]
public class Table
{
    public MeshRenderer meshRenderer;
    public State[] states;
}

public class Sample : MonoBehaviour
{
    public Table table;
}

範例程式碼 (TableDrawer.cs)

using UnityEditor;
using UnityEngine;

[CustomPropertyDrawer(typeof(Table))]
public class TableDrawer : PropertyDrawer
{
    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    {
        EditorGUI.BeginProperty(position, label, property);
        Rect rLabel = position;

        Rect rField = EditorGUI.PrefixLabel(position, GUIUtility.GetControlID(FocusType.Passive), label);
        rField.height = EditorGUIUtility.singleLineHeight;

        SerializedProperty spMesh = property.FindPropertyRelative("mesh");
        SerializedProperty spStates = property.FindPropertyRelative("states");

        EditorGUI.PropertyField(rField, spMesh, GUIContent.none);
        rField.y += EditorGUIUtility.singleLineHeight;

        MeshRenderer mesh = spMesh.objectReferenceValue as MeshRenderer;
        if (mesh != null && mesh.sharedMaterials.Length > 0)
        {
            spStates.arraySize = mesh.sharedMaterials.Length;
            for (int i = 0; i < spStates.arraySize; ++i)
            {
                SerializedProperty spLipShape = spStates.GetArrayElementAtIndex(i);
                string labelName = "  " + mesh.sharedMaterials[i].name;
                Rect rt = new Rect(rLabel.x, rField.y, rLabel.width - rField.width, rLabel.height);
                EditorGUI.LabelField(rt, labelName);
                EditorGUI.PropertyField(rField, spLipShape, GUIContent.none);
                rField.y += EditorGUIUtility.singleLineHeight;
            }
        }
        EditorGUI.EndProperty();
    }

    public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
    {
        int lineCount = 1;
        SerializedProperty spMesh = property.FindPropertyRelative("mesh");
        MeshRenderer mesh = spMesh.objectReferenceValue as MeshRenderer;
        if (mesh != null) lineCount += mesh.sharedMaterials.Length;
        return EditorGUIUtility.singleLineHeight * lineCount;
    }
}

圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言