如何在Unity Editor窗口中显示列表或数组提取?

时间:2019-07-15 19:21:50

标签: c# unity3d

我正在根据以下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提取。这就是现在的样子:

item editor

1 个答案:

答案 0 :(得分:0)

我不确定我是否正确理解了问题,但是由于您公开公开了变量,因此您应该能够使用foreach循环和GUILayout函数遍历itemDatabase.Items.itemEffects列表创建UI。