我正在根据以下Unity可编写脚本的对象教程https://learn.unity.com/tutorial/introduction-to-scriptable-objects#5cf187b7edbc2a31a3b9b123
制作库存和手工系统目前,我已经完成所有工作,但我正在尝试扩展它,以增加使用过的药水创建临时增益的能力或装备精良的物品,以增加您的装甲/武器伤害(如他们预期的那样)。因此,我的Item类具有类TypeEffect的列表。但是我不确定如何将其显示在我的项目数据库编辑器窗口中。
我已经在网上进行了一些搜索,找到了一些相当古老的解决方案来完成这项工作,尽管我必须承认我很难让他们自己工作。我也尝试过使用数组而不是列表的方法来实现它(我不在乎任何一个),因为数组更快,我不需要在运行时更改项目数据集,因为它似乎默认情况下,Unity不会在编辑器窗口中显示列表。
Item.cs
using System.Collections.Generic;
using UnityEngine;
namespace PixelsoftGames.Inventory
{
public enum ItemType { Weapon, Armor, Food, Material }
public enum EquipSlot { None, Head, Chest, Hands, Legs, Feet, Accessory1, Accessory2, Weapon, Shield }
public enum EffectType { RestoreHP, IncreaseArmor, IncreaseDamage }
[System.Serializable]
public class Item
{
public string name = "New Item";
public string description = "Item Description";
public Sprite icon = null;
public int basePrice = 0;
public int useValue = 0;
public ItemType type = ItemType.Material;
public EquipSlot equipSlot = EquipSlot.None;
public List<ItemEffect> itemEffects;
public bool isEquippable = false;
public bool isUseable = false;
public bool isSellable = false;
public bool canDestroy = false;
}
[System.Serializable]
public class ItemEffect
{
public EffectType effectType;
public float effectDuration;
public int effectMagnitude;
}
}
ItemEditor.cs
using UnityEngine;
using UnityEditor;
using System.Collections.Generic;
namespace PixelsoftGames.Inventory
{
public class ItemEditor : EditorWindow
{
public ItemDatabase itemDatabase;
private int viewIndex = 1;
Vector2 scroll;
[MenuItem("Window/Item Editor %#e")]
static void Init()
{
EditorWindow.GetWindow(typeof(ItemEditor));
}
void OnEnable()
{
if (EditorPrefs.HasKey("ObjectPath"))
{
string objectPath = EditorPrefs.GetString("ObjectPath");
itemDatabase = AssetDatabase.LoadAssetAtPath(objectPath, typeof(ItemDatabase)) as ItemDatabase;
}
}
void OnGUI()
{
GUILayout.BeginHorizontal();
GUILayout.Label("Item Editor", EditorStyles.boldLabel);
if (itemDatabase != null)
{
if (GUILayout.Button("Show Item Database"))
{
EditorUtility.FocusProjectWindow();
Selection.activeObject = itemDatabase;
}
}
if (GUILayout.Button("Open Item Database"))
{
OpenItemDatabase();
}
if (GUILayout.Button("New Item Database"))
{
EditorUtility.FocusProjectWindow();
Selection.activeObject = itemDatabase;
}
GUILayout.EndHorizontal();
if (itemDatabase == null)
{
GUILayout.BeginHorizontal();
GUILayout.Space(10);
if (GUILayout.Button("Create New Item Database", GUILayout.ExpandWidth(false)))
{
CreateItemDatabase();
}
if (GUILayout.Button("Open Existing Item Database", GUILayout.ExpandWidth(false)))
{
OpenItemDatabase();
}
GUILayout.EndHorizontal();
}
GUILayout.Space(20);
if (itemDatabase != null)
{
GUILayout.BeginHorizontal();
GUILayout.Space(10);
if (GUILayout.Button("Prev", GUILayout.ExpandWidth(false)))
{
if (viewIndex > 1)
viewIndex--;
}
GUILayout.Space(5);
if (GUILayout.Button("Next", GUILayout.ExpandWidth(false)))
{
if (viewIndex < itemDatabase.Items.Count)
{
viewIndex++;
}
}
GUILayout.Space(60);
if (GUILayout.Button("Add Item", GUILayout.ExpandWidth(false)))
{
AddItem();
}
if (GUILayout.Button("Delete Item", GUILayout.ExpandWidth(false)))
{
DeleteItem(viewIndex - 1);
}
GUILayout.EndHorizontal();
if (itemDatabase.Items == null)
Debug.Log("wtf");
if (itemDatabase.Items.Count > 0)
{
GUILayout.BeginHorizontal();
viewIndex = Mathf.Clamp(EditorGUILayout.IntField("Current Item", viewIndex, GUILayout.ExpandWidth(false)), 1, itemDatabase.Items.Count);
//Mathf.Clamp (viewIndex, 1, inventoryItemList.itemList.Count);
EditorGUILayout.LabelField("of " + itemDatabase.Items.Count.ToString() + " items", "", GUILayout.ExpandWidth(false));
GUILayout.EndHorizontal();
itemDatabase.Items[viewIndex - 1].name = EditorGUILayout.TextField("Item Name", itemDatabase.Items[viewIndex - 1].name as string);
scroll = EditorGUILayout.BeginScrollView(scroll);
itemDatabase.Items[viewIndex - 1].description = EditorGUILayout.TextArea(itemDatabase.Items[viewIndex - 1].description, GUILayout.Height(position.height - 30));
EditorGUILayout.EndScrollView();
itemDatabase.Items[viewIndex - 1].icon = EditorGUILayout.ObjectField("Item Icon", itemDatabase.Items[viewIndex - 1].icon, typeof(Sprite), false) as Sprite;
GUILayout.Space(10);
GUILayout.BeginHorizontal();
itemDatabase.Items[viewIndex - 1].basePrice = EditorGUILayout.IntField("Base Price", itemDatabase.Items[viewIndex - 1].basePrice, GUILayout.ExpandWidth(false));
itemDatabase.Items[viewIndex - 1].useValue = EditorGUILayout.IntField("Use Value", itemDatabase.Items[viewIndex - 1].useValue, GUILayout.ExpandWidth(false));
itemDatabase.Items[viewIndex - 1].type = (ItemType)EditorGUILayout.EnumPopup("Item Type", itemDatabase.Items[viewIndex - 1].type);
itemDatabase.Items[viewIndex - 1].equipSlot = (EquipSlot)EditorGUILayout.EnumPopup("Equip Slot", itemDatabase.Items[viewIndex - 1].equipSlot);
GUILayout.EndHorizontal();
GUILayout.Space(10);
GUILayout.BeginHorizontal();
itemDatabase.Items[viewIndex - 1].isEquippable = (bool)EditorGUILayout.Toggle("Is Equippable ", itemDatabase.Items[viewIndex - 1].isEquippable, GUILayout.ExpandWidth(false));
itemDatabase.Items[viewIndex - 1].isUseable = (bool)EditorGUILayout.Toggle("Is Useable ", itemDatabase.Items[viewIndex - 1].isUseable, GUILayout.ExpandWidth(false));
itemDatabase.Items[viewIndex - 1].isSellable = (bool)EditorGUILayout.Toggle("Is Sellable ", itemDatabase.Items[viewIndex - 1].isSellable, GUILayout.ExpandWidth(false));
itemDatabase.Items[viewIndex - 1].canDestroy = (bool)EditorGUILayout.Toggle("Can Destroy ", itemDatabase.Items[viewIndex - 1].canDestroy, GUILayout.ExpandWidth(false));
GUILayout.EndHorizontal();
GUILayout.Space(10);
}
else
{
GUILayout.Label("This item database is empty.");
}
}
if (GUI.changed)
{
EditorUtility.SetDirty(itemDatabase);
}
}
void CreateItemDatabase()
{
// There is no overwrite protection here!
// There is No "Are you sure you want to overwrite your existing object?" if it exists.
// This should probably get a string from the user to create a new name and pass it ...
viewIndex = 1;
itemDatabase = PixelsoftGames.Inventory.CreateItemDatabase.Create();
if (itemDatabase)
{
itemDatabase.Items = new List<Item>();
string relPath = AssetDatabase.GetAssetPath(itemDatabase);
EditorPrefs.SetString("ObjectPath", relPath);
}
}
void OpenItemDatabase()
{
string absPath = EditorUtility.OpenFilePanel("Select Item Database", "", "");
if (absPath.StartsWith(Application.dataPath))
{
string relPath = absPath.Substring(Application.dataPath.Length - "Assets".Length);
itemDatabase = AssetDatabase.LoadAssetAtPath(relPath, typeof(ItemDatabase)) as ItemDatabase;
if (itemDatabase.Items == null)
itemDatabase.Items = new List<Item>();
if (itemDatabase)
{
EditorPrefs.SetString("ObjectPath", relPath);
}
}
}
void AddItem()
{
Item newItem = new Item();
newItem.name = "New Item";
itemDatabase.Items.Add(newItem);
viewIndex = itemDatabase.Items.Count;
}
void DeleteItem(int index)
{
itemDatabase.Items.RemoveAt(index);
}
}
}
代码现在没有错误,我只是不知道如何在编辑器窗口中显示ItemEffect提取。这就是现在的样子:
答案 0 :(得分:0)
我不确定我是否正确理解了问题,但是由于您公开公开了变量,因此您应该能够使用foreach循环和GUILayout函数遍历itemDatabase.Items.itemEffects
列表创建UI。