【问题标题】:How can I use my existing array like a list?如何像列表一样使用现有的数组?
【发布时间】:2019-06-23 05:09:18
【问题描述】:

我有一个数组来控制我的 UI 清单列表。当我将 GameObject 添加到数组时,该函数还会将相同的 GameObject 添加到我的库存 UI。

在我的脚本中,我还有一个删除函数,可以从数组中删除 GameObject 并从 UI 中删除 GameObject

我的问题是我需要将此数组更改为列表,以便它可以动态工作,因为列表具有将数组元素移动到数组前面的内置功能(即向左移动它们在数组索引中)。

例如,当前使用数组时,当我选择项目 1、2、3、4 和 5 时。然后我继续删除项目 3。我的数组中剩下的是 1,2,null,4,和 5. 同样,我的库存 UI 中剩下的内容是插槽 1、2、null、4、5 中的GameObjects。在这种情况下,null 是一个没有任何内容的 UI 图像。

通过将此数组转换为列表,我相信我可以避免库存 UI 中出现空白。同样,我知道我的数组和/或列表将始终是 16 项。

我已尝试将现有数组转换为列表并使用与列表方法对应的所有方法。

原数组用法:

public class Inventory : MonoBehaviour
{
    public GameObject[] inventory = new GameObject[16];
    public List<GameObject> inventory2 = new List<GameObject>();

    public void AddItem(GameObject item)
    {
        bool itemAdded = false;

        //find the first open slot in inventory
        for (int i = 0; i < inventory.Length; i++)
        {
            if (inventory[i] == null)
            {
                inventory[i] = item;

                //Update UI
                InventoryButtons[i].image.overrideSprite = 
    item.GetComponentInChildren<SpriteRenderer>().sprite;
        }
    }
}

我尝试将其转换为列表并像这样使用它:

public class Inventory : MonoBehaviour
{
    public List<GameObject> inventory = new List<GameObject>();

    public void AddItem(GameObject item)
    {
        bool itemAdded = false;

        //find the first open slot in inventory
        for (int i = 0; i < inventory.Count; i++)
        {
            if (inventory[i] == null)
            {
                inventory[i] = item;

                //Update UI
                InventoryButtons[i].image.overrideSprite = 
     item.GetComponentInChildren<SpriteRenderer>().sprite;
            }
        }
    }
}

由于我认为列表和数组的工作方式相同,我认为我的方法可以工作,但是列表仍然充当数组,也就是说,它不会在删除项目后将数组中的项目动态移动到前面来自数组。

【问题讨论】:

  • SO 上有代码块的小提示:它们必须在代码开头和段落文本的前一行之间有一个空行。双 ` 不是必需的,但您可以用单个反引号将文本括起来以引用这样的内联代码的短词:“我在 var v = nullthing.Property 行出现错误 - 为什么会这样”
  • 首先,当您向 Stack Overflow 发布问题时,您确实需要包含一个好的minimal reproducible example。另请参阅How to Ask 了解更多提示。其次,虽然List&lt;T&gt; 确实提供了动态大小、插入和删除,但您必须实际使用这些功能。您的代码示例中没有任何内容显示您如何从列表中删除项目,但根据您发布的内容和您的描述,很可能您并没有真正更改代码,而只是更改了数据类型。如果是这样,那么列表当然会像数组一样工作。请改用List&lt;T&gt;.RemoveAt() 方法,并使用Add() 添加。
  • 此外,无需在帖子本身中包含解释编辑的信息。这就是为什么每个帖子都有修订历史,每次编辑都有评论。
  • “同样,我知道我的数组和/或列表将始终包含 16 个项目。” 如果您使用 List&lt;T&gt; 并正确使用 RemoveAt,那么您的列表将有Count-1 项目。将有没有空白供您搜索。您的for 循环将在新的Count 处停止迭代,最后永远不会触及“间隙”索引(它们不存在!)。您需要Add 将内容放在列表末尾。但总体而言,您的项目数量会波动,您可以索引的插槽数量也会波动(底层数组的大小可能永远不会超过原始长度 16,但这是一个实现细节)

标签: c# arrays list unity3d


【解决方案1】:

如果数组版本成功并且您总是想要 16 个项目,为什么不这样做来删除一个项目:

//remove item at index 5
for (int i = 5; i < inventory.Count - 1; i++)
  inventory[i] = inventory[i+1];

inventory[inventory.Length - 1] = null;

我们从要删除的索引 5 开始,然后继续到数组 1 的末尾,将下一个项目复制到当前项目的顶部。然后我们完成循环并使最后一项为空

【讨论】:

    猜你喜欢
    • 2021-12-10
    • 1970-01-01
    • 2021-02-19
    • 1970-01-01
    • 2011-12-19
    • 2019-07-10
    • 1970-01-01
    • 1970-01-01
    • 2018-12-08
    相关资源
    最近更新 更多