при опробовании кода в unity выскакивает ошибка ArgumentOutOfRangeException

Рейтинг: 0Ответов: 1Опубликовано: 27.06.2023

Помогите, пожалуйста, создал инвентарь персонажа, при запуске игры, когда пробую собрать предмет выдает ошибку, разработкой недавно занимаюсь и поэтому не могу понять где ее ловить:

ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index
System.Collections.Generic.List`1[T].get_Item (System.Int32 index) (at <75633565436c42f0a6426b33f0132ade>:0)
InventoryPlayerUI.UpdateUI (InventoryPlayer inventory) (at Assets/Scripts/Player/InventoryPlayerUI.cs:19)
UnityEngine.Events.InvokableCall`1[T1].Invoke (T1 args0) (at <4746c126b0b54f3b834845974d1a9190>:0)
UnityEngine.Events.CachedInvokableCall`1[T].Invoke (System.Object[] args) (at <4746c126b0b54f3b834845974d1a9190>:0)
UnityEngine.Events.UnityEvent.Invoke () (at <4746c126b0b54f3b834845974d1a9190>:0)
InventoryPlayer.AddDetails (Details detail, System.Int32 amount) (at Assets/Scripts/Player/InventoryPlayer.cs:32)
CollectableDetails.OnTriggerEnter (UnityEngine.Collider other) (at Assets/Scripts/Details/CollectableDetails.cs:18)

Использую следующий код:

public class CollectableDetails : MonoBehaviour
{
    [SerializeField] private Details detail;
    [SerializeField] private int amount = 1;
 
    private void OnTriggerEnter(Collider other)
    {
        if (!detail) return;
 
        var inventory = other.GetComponent<InventoryPlayer>();
        
        if (inventory)
        {
            if (inventory.AddDetails(detail, amount))
                Destroy(gameObject);
        }        
    }
}
 
//************************************* 
public class InventoryPlayer : MonoBehaviour
{
    [SerializeField] private GameObject _canvas;
    [SerializeField] private List<InventorySlot> _details = new List<InventorySlot>();
    private int size = 4;
 
    [SerializeField] public UnityEvent OnInventoryChanged; 
 
    public bool AddDetails(Details detail, int amount = 1)
    {
        foreach (InventorySlot slot in _details)
        {
            if (slot.detail.name == detail.name)
            {
                slot.amount += amount;
                OnInventoryChanged.Invoke();
                return true;
            }
        }
 
        if (_details.Count >= size) return false;
 
        InventorySlot new_slot = new InventorySlot(detail, amount); 
        _details.Add(new_slot); 
        OnInventoryChanged.Invoke(); 
        return true;
    }
 
    public Details GetItem(int i)
    {
        return i < _details.Count ? _details[i].detail : null;
    }
 
    public int GetAmount(int i)
    {
        return i < _details.Count ? _details[i].amount : 0;
    }
 
    public int GetSize()
    {
        return _details.Count;
    }
}
//************************************* 
public class InventoryPlayerUI : MonoBehaviour
{
    [SerializeField] private List<Image> icons = new List<Image>();
    [SerializeField] private List<Text> amounts = new List<Text>();
 
    public void UpdateUI(InventoryPlayer inventory)
    {        
        for (int i = 0; i < inventory.GetSize() && i < icons.Count; i++)
        {
            icons[i].color = new Color(1, 1, 1, 1);
            
            icons[i].sprite = inventory.GetItem(i).icon;
            amounts[i].text = inventory.GetAmount(i) > 1 ? inventory.GetAmount(i).ToString() : "";
        }
 
        for (int i = inventory.GetSize(); i < icons.Count; i++)
        {
            icons[i].color = new Color(1, 1, 1, 0);
 
            icons[i].sprite = null;
            amounts[i].text = "";
        }
    }
}

Ответы

▲ 1Принят

Падает здесь, выходите за рамки массива. Скорее всего, списки icons и amounts разной длины. Посмотрите в инспекторе

        for (int i = 0; i < inventory.GetSize() && i < icons.Count; i++)
        {
            icons[i].color = new Color(1, 1, 1, 1);
            
            icons[i].sprite = inventory.GetItem(i).icon;
            amounts[i].text = inventory.GetAmount(i) > 1 ? 
            inventory.GetAmount(i).ToString() : "";
        }
 
        for (int i = inventory.GetSize(); i < icons.Count; i++)
        {
            icons[i].color = new Color(1, 1, 1, 0);
 
            icons[i].sprite = null;
            amounts[i].text = "";
        }