ArgumentOutOfRange (I am out of arguments on how to fix this)

I am in the long process of making a card game, and I feel like the complexity of the code is going to kill me at any moment (That’s an exaggeration, but for a beginner like me, it’s as if I’m learning to communicate with an ancient cosmic entity that doesn’t like me much). And I’m having a tough time with a bug that not even AI assistants could help me with.

I need the card to rise slightly when the player hovers over it (note: the position of the cards is tied to the camera, so I feel like the error lies there, but I haven’t managed to fix it yet) and then lower back down again—a standard effect in card games. But I’m facing a bug that’s really bothering me, which is:

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 <8ce0bd04a7a04b4b9395538239d3fdd8>:0)
Carta.OnMouseOver () (at Assets/Scripts/Carta.cs:96)
UnityEngine.SendMouseEvents:DoSendMouseEvents(Int32)

Yes, I’m coding in my native language (Judge me, I know I made a mistake, but I’m too far along to fix it now).

Could any of you help me understand how to avoid this bug? I’d really appreciate it.

Oh, by the way, here’s the code:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
using UnityEngine.UI;

public class Carta : MonoBehaviour
{
    public CartaScriptObjeto CartaSO; // Referência ao ScriptableObject com os dados da carta

    public int vidaAtual;  
    public int danoAtaque, custoOuro;  

// Referências para os textos da carta
 public TMP_Text textoVida, textodano, textoCusto, nomeCarta, históriaCarta, açãoCarta;

    // Referências para as imagens da carta
    public Image planoDeFundo, personage;

    private Vector3 pontoAlvo;
    public float velocidade = 5f;
    
    public bool naMão; // Informa se a carta está ou não na mão
    public int posiçãoNaMão; // Informa qual a posição da carta na mão
    private ControladorDeMao theHC;

    // Start is called before the first frame update
    void Start()
    {
        SetupCarta();  

        // Corrigido: Usar FindObjectOfType com F maiúsculo
        theHC = FindObjectOfType<ControladorDeMao>();
    }

    // Configura a carta com base nos dados do ScriptableObject
    public void SetupCarta()
    {
      

        // Atribui os valores numéricos da carta
        vidaAtual = CartaSO.vidaAtual;
        danoAtaque = CartaSO.danoAtaque;
        custoOuro = CartaSO.custoOuro;

        // Atribui os textos da carta
        textoVida.text = vidaAtual.ToString();
        textodano.text = danoAtaque.ToString();
        textoCusto.text = custoOuro.ToString();
        nomeCarta.text = CartaSO.nomeCarta;
        açãoCarta.text = CartaSO.açãoCarta;
        históriaCarta.text = CartaSO.históriaCarta;

        // Atribui as imagens (fundo e personagem)
        planoDeFundo.sprite = CartaSO.bgSprite;
        personage.sprite = CartaSO.characterSprite;

        // Centraliza as imagens
        AlinharImagens();
    }

    // Método para alinhar as imagens corretamente na carta
    private void AlinharImagens()
    {
        // Centraliza o fundo da carta
        planoDeFundo.rectTransform.localPosition = Vector3.zero;

        // Centraliza o personagem e garante que ele fique à frente do fundo
        personage.rectTransform.localPosition = Vector3.zero;
        personage.rectTransform.SetAsLastSibling();  // Garante que o personagem fique em frente ao fundo

        // Ajuste de escala (opcional): Garante que as imagens preencham corretamente a carta
        planoDeFundo.rectTransform.localScale = Vector3.one;
        personage.rectTransform.localScale = Vector3.one;
    }

    // Update is called once per frame
    void Update()
    {
        transform.position = Vector3.Lerp(transform.position, pontoAlvo, velocidade * Time.deltaTime);
    }

    // Método atualizado para mover a carta e aplicar rotação
    public void MoverPara(Vector3 lugarParaIr, Quaternion rotacao)
    {
        pontoAlvo = lugarParaIr;
        transform.rotation = rotacao;  // Aplica a rotação
    }

    // Função corrigida para mover a carta quando o mouse está sobre ela
    void OnMouseOver()
   {
    if (naMão)
    {
        // Sobe a carta no eixo Y quando o mouse estiver sobre ela
        MoverPara(theHC.posicaoCarta[posiçãoNaMão] + new Vector3(1f, 2f, 1.5f), Quaternion.identity);
    }
   }
} 

Here are some notes on IndexOutOfRangeException and ArgumentOutOfRangeException:

http://plbm.com/?p=236

Steps to success:

  • find which collection it is and what line of code accesses it <— (critical first step!)
  • find out why it has fewer items than you expect
  • fix whatever logic is making the indexing value exceed the collection size

Remember also:

  • a collection with ZERO elements cannot be indexed at all: it is empty
  • you might have more than one instance of this script in your scene/prefab
  • the collection may be used in more than one location in the code
  • indices start at ZERO (0) and go to the count / length minus 1.

This means with three (3) elements in your collection, they are numbered 0, 1, and 2 only.

I agree with Kurt here; have you tried adding a boundary test before accessing the list? For example, in the OnMouseOver() method, if the card is in hand, also check the list:

void OnMouseOver()
{
    if (naMão)
    {
        if (posiçãoNaMão >= 0 && posiçãoNaMão < theHC.posicaoCarta.Count)
        {
            // Move the card if the index is valid
            MoverPara(theHC.posicaoCarta[posiçãoNaMão] + new Vector3(1f, 2f, 1.5f), Quaternion.identity);
        }
        else
        {
            Debug.LogError("posiçãoNaMão is out of range: " + posiçãoNaMão);
        }
    }
}

Apologies if I mistyped any variables :smiley:

Check your ControladorDeMao script. The list posicaoCarta apparently isn’t filling up with as many items as the posicaoNaMao int is asking for. The boundary test should do the trick too, you can Debug.Log(theHC.posicaoCarta.Count) to track things.

Remember that lists and arrays count from 0! So if the length/count is 5, the last index is 4. Maybe your posicaoNaMao variable is one higher than it should be.