Keeping a large object in memory or just a pointer to it in C #?

struct Tile
{
    GameObject go;
    ... //more fields

    public Tile(GameObject g, Object s)
    {
        go = g;
        ...
    }
}
Tile[,] tilemap = new Tile[1000,1000]

      

The Tile structure consists of a GameObject (a Unity Engine game object that is already in the scene / memory) and other fields. This can take a huge amount of memory considering I want to store a million of them.

I don't have much experience with pointers in C #.

Would it be smart to just store a pointer to the GameObject in a struct?

struct Tile
{
    GameObject* go;
    ...
}

      

+3


source to share


3 answers


As I understand it, GameObject is already a reference type, so it is a reference to the object, not the actual object itself.

Therefore, simple storage

struct Tile {
  GameObject go;
  ...
}

      



would be enough.

If you pass your structure arround; the structure will be passed by value, so a copy of the entire structure will be passed to any methods, unless you specifically indicate that you need to follow the link (with the "Ref" keyword).

+1


source


The link is already a pointer (under the hood) in C #. It is not a copy of any object. In your first piece of code, "go" is actually a pointer to the actual object. You are worried about something that is not true.

One of the differences between ref (like "go") and unsafe pointer is that ref can move, GC can and will (when it feels like) move objects around (and automatically change refs).



So there is no problem here, just misperception.

+3


source


You cannot use a class as a pointer. This may have changed in the latest C #, but I'm not sure. It just wo n't . Any reference type will not work with pointers.

Simple types such as int

, float

and bool

, while others can be used as pointers.

Even if you declare a variable GameObject go

in a struct Tile

, that's not okay.

It is not recommended to specify a reference type inside a structure, especially in a game application, because it will make the garbage collector unnecessarily check for objects that will be destroyed in the structure, which slows things down. It's even worse when you have millions of these structures with referenced objects inside them.


My suggestion is to use an integer instead of GameObject *. This integer must be initialized with a GameObject instanceID

instead of a GameObject reference or pointer.

Then you can use Dictionary

to map instanceID

(int) to GameObject

. If you want to access the GameObject, specify intanceID

which is stored in the structure Tile

. This will speed everything up.

Example:

struct Tile
{
    int goID;

    public Tile(int goID)
    {
        this.goID = goID;
    }
}

      

Application:

Dictionary<int, GameObject> idToObj = new Dictionary<int, GameObject>();

Tile[] tiles = new Tile[1000];
GameObject obj = new GameObject("obj");

//Create new Instance with Instance ID
tiles[0] = new Tile(obj.GetInstanceID());

//Add to Dictionary
idToObj.Add(obj.GetInstanceID(), obj);

      

Finally, it's worth checking this out to see which one is faster. A test with a GameObject declared in the struct, then using the method above, which it uses int

and Dictionary

to work with.

+2


source







All Articles