Home > Back-end >  Static Function gets updated with each instances
Static Function gets updated with each instances

Time:05-12

I am trying to implement some objects in my Unity3d game by script. They look like this:

public class Building: 
    public int _id;
    public int _level; 

    public Building(int id)
    {
        this._id = id;
        this._level = 0;
    }

    public void UpdateLevel(int target)
    {
        if (target > this._level)
        {
            this._level = target;
        }
    }

Each tile of the map can have one building at a time. Each tile has its own property Build that can be changed. It is initialized using a static Dictionary on an other script like this:

Script: BuildingType

public static Dictionary<int, Building> Types = new Dictionary<int, Building>
{
   { 0, new Building(0) },
   { 10, new Building(10) }
}

Script: Tile

public class Tile : MonoBehavior
{
    Building Build;
    Vector3 coordinates;
    
    public Tile (Vector3 coord)
    {
        this.coordinates = coord;
        this.Build = BuildingType.Types[0];
    }
}

My issue is that for each time I call upon the UpdateLevel method on a specific Tile the static Dictionary also gets updated.

e.g There is a button to upgrade one building to its next level. When pressed it calls the UpdateLevel method. Afterwards the static dictionary entry for this Building is also updated to the new value

> BuildingType.Types[0]._level;
>>> 0

**clicks on button to upgrade the building**
> Tile.Build.UpdateLevel(2);

> BuildingType.Types[0]._level;
>>> 2 

I know that the static variable has only one 'instance' for each run but I don't understand how it is updated in this case. I would like to have a fixed building preset for each tile and the ability to update them independently. Is there any way to prevent this from happening?

Thank you

CodePudding user response:

What is happening is because Building is a reference type.

Meaning that when assigning it to different variables, you aren't creating a new variable like you would with integers, you are simply passing where the variable is found to the other locations. So the Building assigned to the tile is the same one in the dictionary.

Now there are many ways to solve this but this is the easiest in my opinion.

public class Building : ICloneable
{

    public int _id;
    public int _level;

    public Building(int id)
    {
        this._id = id;
        this._level = 0;
    }

    public object Clone()
    {
        return this.MemberwiseClone();
    }

    public void UpdateLevel(int target)
    {
        if (target > this._level)
        {
            this._level = target;
        }
    }
}

Now you can get a copy of the building without selecting the original. So just update your Tile class like this:

public class Tile : MonoBehavior
{
    Building Build;
    Vector3 coordinates;
    
    public Tile (Vector3 coord)
    {
        this.coordinates = coord;
        this.Build = (Building) BuildingType.Types[0].Clone();
    }
}

And everything should work as intended.

  • Related