我正在尝试为 PlayerInventory
类创建自定义检查器。 PlayerInventory
类由项目列表(ScriptableObjects
)以及每个项目的数量组成,如下所示:
public class Item : ScriptableObject
{
public string description;
public Sprite picture;
}
public class InventoryItem : ScriptableObject
{
// A reference to the Item object that contains the item's description,
// picture, stats, etc.
public Item item;
// The quantity of this item that the player has in his inventory
public int quantity;
}
[CreateAssetMenu(menuName = "Player/Player Inventory")]
public class PlayerInventory : ScriptableObject
{
// The list of each distinct item that the player has in his inventory,
// along with the quantity of each item
public List<InventoryItem> items;
}
我创建了一个 PlayerInventory
实例作为游戏 Assets 。默认情况下,Inspector 会显示一个 InventoryItem
列表。但是,我想要的是让 Inspector 显示每个 InventoryItem
元素,其中包含一个为其选择 Item
的字段、一个输入数量的字段和一个“删除”按钮。
这是我试图实现的目标的可视化示例,以及下面的当前代码。此屏幕截图的问题在于 Unity 让我为每个元素选择一个 InventoryItem
对象。我希望能够为每个元素选择一个 Item
对象。我遇到的第二个问题是我不知道如何将 EditorGUILayout.TextField
设置为 InventoryItem.quantity
属性,因为我不知道如何将SerializedProperty
到 InventoryItem
对象。
[CustomEditor(typeof(PlayerInventory))]
public class PlayerInventoryEditor : Editor
{
public override void OnInspectorGUI()
{
this.serializedObject.Update();
SerializedProperty items = this.serializedObject.FindProperty("items");
for (int i = 0; i < items.arraySize; i++)
{
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField("Item", GUILayout.Width(50));
// I don't know how to make this line reference the child "item"
// field of the current InventoryItem
EditorGUILayout.PropertyField(items.GetArrayElementAtIndex(i), GUIContent.none, GUILayout.Width(170));
EditorGUILayout.LabelField(" Quantity", GUILayout.Width(80));
// I don't know how to set the text field to the "quantity" field
// of the current InventoryItem
EditorGUILayout.TextField("0", GUILayout.Width(50));
EditorGUILayout.LabelField("", GUILayout.Width(20));
GUILayout.Button("Delete Item");
EditorGUILayout.EndHorizontal();
}
GUILayout.Button("Add Item");
}
}
类必须是可序列化的才能出现在检查器中。参见 Serializable
编辑。在下面的评论中进一步讨论后,这里是完整的片段;
标有Serializable
的标准类;
[System.Serializable]
public class InventoryItem
{
public Item item;
public int quantity;
}
使用 PlayerInventoryEditor;
public override void OnInspectorGUI ()
{
this.serializedObject.Update();
SerializedProperty items = this.serializedObject.FindProperty("items");
for (int i = 0; i < items.arraySize; i++)
{
SerializedProperty item = items.GetArrayElementAtIndex(i);
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField("Item", GUILayout.Width(50));
EditorGUILayout.PropertyField(item.FindPropertyRelative("item"), GUIContent.none, GUILayout.Width(170));
EditorGUILayout.LabelField(" Quantity", GUILayout.Width(80));
EditorGUILayout.IntField(item.FindPropertyRelative("quantity").intValue, GUILayout.Width(50));
EditorGUILayout.LabelField("", GUILayout.Width(20));
GUILayout.Button("Delete Item");
EditorGUILayout.EndHorizontal();
}
GUILayout.Button("Add Item");
}
我是一名优秀的程序员,十分优秀!