繁体   English   中英

如何在 Unity 编辑器窗口中显示列表或数组拉出?

[英]How do I display a list or array pullout in a Unity Editor Window?

我正在根据这个 Unity Scriptable Objects Tutorial 创建一个库存和制作系统: https : //learn.unity.com/tutorial/introduction-to-scriptable-objects#5cf187b7edbc2a31a3b9b123

目前我已经完成了所有这些工作,但我正在尝试扩展它以添加使用过的药水来创建临时增益或装备物品以增加您的盔甲/武器伤害的能力(正如他们应该的那样)。 所以我的 Item 类有一个类类型 ItemEffect 的列表。 但我不确定如何让它显示在我的项目数据库编辑器窗口中。

我已经在网上进行了一些搜索,并找到了一些非常古老的解决方案来完成这项工作,尽管我必须承认我自己很难让它们工作。 我还尝试通过使用数组而不是列表的方法来处理它(我不介意任何一个),因为数组更快,我不需要在运行时更改项目数据集,因为它似乎默认情况下,Unity 不假设在编辑器窗口中显示列表。

项目.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 拉出。 这是它现在的样子:

项目编辑器

我不知道如果我抓你有正确的,但是,因为你有公开曝光的变量,你应该能够通过迭代的问题itemDatabase.Items.itemEffects使用foreach循环使用GUILayout函数来创建列表用户界面。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM