[英]Unity custom inspector which allows selected child objects
I'm trying to make a custom inspector for a PlayerInventory
class. 我正在尝试为
PlayerInventory
类创建自定义检查器。 The PlayerInventory
class consists of a list of items (which are ScriptableObjects
), along with a quantity of each item, like this: 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;
}
I created an instance of PlayerInventory
as a game asset. 我创建了一个
PlayerInventory
实例作为游戏资产。 By default, the Inspector shows a list of InventoryItem
s. 默认情况下,Inspector显示
InventoryItem
列表。 However, what I want is for the Inspector to show each InventoryItem
element with a field to select an Item
for it, a field to enter a quantity, and a "delete" button. 但是,我想要的是Inspector为每个
InventoryItem
元素显示一个字段来为它选择一个Item
,一个输入数量的字段和一个“删除”按钮。
Here's a visual example of what I'm trying to achieve, along with my current code below. 这是我正在尝试实现的一个直观示例,以及下面的当前代码。 The problem with this screenshot is that Unity is making me select an
InventoryItem
object for each element. 这个屏幕截图的问题是Unity让我为每个元素选择一个
InventoryItem
对象。 I want to be able to select an Item
object for each element. 我希望能够为每个元素选择一个
Item
对象。 The second problem I'm having is I don't know how to set an EditorGUILayout.TextField
to the InventoryItem.quantity
property because I don't know how to convert the SerializedProperty
to an InventoryItem
object. 我遇到的第二个问题是我不知道如何将
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");
}
}
Classes must be serializable to appear in the Inspector. 类必须可序列化以显示在Inspector中。 See Serializable
请参见Serializable
Edit . 编辑 。 Following further discussion in the comments below, here's the full snippet;
在下面的评论中进一步讨论后,这里是完整的片段;
Standard class marked Serializable
; 标准类标记为
Serializable
;
[System.Serializable]
public class InventoryItem
{
public Item item;
public int quantity;
}
With PlayerInventoryEditor; 使用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");
}
You can use FindPropertyRelative
您可以使用
FindPropertyRelative
//...
EditorGUILayout.PropertyField(
items.GetArrayElementAtIndex(i).FindPropertyRelative("item"),
new GUIContent("Item"),
GUILayout.Width(170));
//...
And same method for your 'Quantity' field. 和“数量”字段的方法相同。
Make sure InventoryItem not null
in your items List. 确保您的商品列表中的InventoryItem不为
null
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.