Assign to null or RemoveAt(i) return a empty object

Hi!
I need to have a List to manage a inventory , the inventory don’t have limited size, for add objects i use :

player.files.Add(item);

and for remove

player.files.RemoveAt(id);

The problem with that is the List don’t resize when i remove an entry , it simply create a “null” empty object, i can delete in the inspector , but no in game with code , so when i read the data from the inventory it creates the space of a blank empty item.
How can i solve this ? Is there a way to really resize and delete an entry in a list ? o need to use another type of collection ?

According to the documentation of Lists, it should automatically resize on Remove() and RemoveAt(). How does it look in the debugger?

It creates an Empty object called “Element #” where # is the index value

Problem solved, now i instantiate (the old method was checking if null and activate a button) a reference of the Item and i use

player.files.Remove(item);

and it seems to work
Sorry for any inconvenience

I don’t think that function resizes the list, it just deletes an entry and shifts the remaining entries without changing the list size. You probably end up with a null at the last entry, right?

Try dropping this into your project to add a Resize() method to all your C# lists. What might work is to do RemoveAt() like you’re doing now followed by this Resize().

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
using System.Linq;

public static class ListExtra{
    public static void Resize<T>(this List<T> list, int sz, T c = default(T))
    {
        int cur = list.Count;
        if (sz < cur)
            list.RemoveRange(sz, cur - sz);
        else if (sz > cur)
            list.AddRange(Enumerable.Repeat(c, sz - cur));
    }

}

EDIT: Nevermind, you posted that you solved it while I was writing this. I’ll just leave this Resize() extension method here anyway in case it comes in handy some day. :stuck_out_tongue:

1 Like

I’m not sure what is going on with your code but Using Unity 5.4 and C# I created the following script and attached it to a GameObject. It definitely showed that RemoveAt(id) does indeed remove the object and resize the list:

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class GenericTest : MonoBehaviour {

    List<SomeClass> myList = new List<SomeClass>();

    void Awake()
    {
        for (int i=0;i<4;i++)
        {
            SomeClass tmp = new SomeClass();
            tmp.x = i;
            myList.Add(tmp);
        }
        for (int i = 0; i < myList.Count; i++)
            Debug.Log("Value at index " + i.ToString() + " equals  " + myList[i].x.ToString());
        myList.RemoveAt(2);
        for (int i = 0; i < myList.Count; i++)
            Debug.Log("Value at index " + i.ToString() + " equals  " + myList[i].x.ToString());

    }
}

public class SomeClass
{
    public int x;
}

Debug Code was this:
Value at index 0 was 0
Value at index 1 was 1
Value at index 2 was 2
Value at index 3 was 3
Value at index 0 was 0
Value at index 1 was 1
Value at index 2 was 3

The 2nd index was indeed removed, and you can see the second for loop myList.Count was smaller

I’d be interested in what language you use, what version of unity RemoveAt was not performing correctly
I would also suggest copying this code, create a new project. Create an empty gameObject and attach this script to it. See if you get the same results. That would indicate that your earlier problems with RemoveAt were some other logical bug in your code you probably want to track down :slight_smile:

1 Like

Thank you for the answers guys :smile:
I finally found the problem , when i start the game i suppose the initial equipment are set to null when created , but it creates a empty item ,so when i do the check if the object is not null(for return the old item and equip the new or just equip) the game treat as a empty item and spam return that item , setting to null on purpose solve this.

Sorry for any inconvenience