Unity 3D C# - Making Classes Act Like An Array
So this is my code
//All the buildings in the game with set values of int
[System.Serializable]
public class Buildings {
public class nothing {
public static int id = 0;
}
public class tower {
public static int id = 1;
public static int health = 200;
public static string resource = "TestCube";
}
public class wall {
public static int id = 3;
public static int health = 1000;
public static string resource = "TestCube2";
}
}
Currently to access the variables I must
string getValue = Buildings.tower.resource;
which I also want. but I want to access the value like an array like this so then I can look up all the values with resources.
this would be an example of what i want.
string getValueFromArray = Buildings[0].resource;
string getValue = Buildings.tower.resource;
And the value would be the same either way, is this possible to do? if so, how?
Answer by Hrungdak · Apr 19, 2016 at 12:27 PM
All your classes use the same properties, aka id, health, resource.
So make one class
public BuildingBase {
public int Id {get;set;}
public int Health {get;set;}
public string Resource {get;set;}
public BuildingBase(int id, int health, string resource)
{
Id = id;
Health = health;
Resource = resource;
}
}
Now create a script with a dictionary:
public Dictionary allBuildings;
void Start()
{
allBuildings = new Dictionary<string, BuidlingBase>();
allBuildings.Add("nothing", new BuildingBase(0, 0, string.Empty));
allBuildings.Add("tower", new BuildingBase(1, 200, "TestCube"));
allBuildings.Add("wall", new BuildingBase(2, 1000, "TestCube"));
allBuildings.Add("gate", new BuildingBase(3, 100000, "TestCube"));
}
Now, if you need one of those buildings:
BuildingBase building = allBuildings("tower");
Use an oredered dictionary, the standard dictionary doesnt maintain order of addition. So if you add a key and object to the dictionary, the position of that key will not necessarily always have the same index.
A dictionary is like a list but you use key words ins$$anonymous$$d of index positions to retrieve the value.
I'm trying his method, unity doesn't know what dictionary is, I modified the code, to try to get it to work but no.
public Dictionary[] allBuildings;
//Use this for initialization
void Start () {
allBuildings = new Dictionary<string, BuidlingBase>();
allBuildings.Add("nothing", new BuildingBase(0, 0, string.Empty));
allBuildings.Add("tower", new BuildingBase(1, 200, "TestCube"));
allBuildings.Add("wall", new BuildingBase(2, 1000, "TestCube"));
allBuildings.Add("gate", new BuildingBase(3, 100000, "TestCube"));
}
public class BuildingBase {
public int Id {get;set;}
public int Health {get;set;}
public string Resource {get;set;}
public BuildingBase(int id, int health, string resource)
{
Id = id;
Health = health;
Resource = resource;
}
}
Currently at work so will take a look when I get home, for now try read up here about ordered dictionarys.
You will have to import the system.collection.special
The declaration of the Dictionary should be
public Dictionary<string, BuildingBase> allBuildings;
And you need System.Collections.Generic as using directive.
Answer by giorashc · Apr 19, 2016 at 11:19 AM
You can define in a script an array property of the type Building
:
public class MyScript : MonoBehaviour {
public Building [] buildings;
}
You will need to initialize the array in the inspector and then you can easily access it as in the example you provided
Note that the members in the Building inner classes are static and should be changed to be non-static (otherwise they will be the same for all building instances)
I get errors like Assets/Scripts/TerrainSetup.cs(47,74): error CS0120: An object reference is required to access non-static member `TerrainSetup.Buildings.nothing.id'
Did you initialize the array of buildings in the inspector? can you show the code where you try to access this array?
I did this. I'm not sure what u mean by " in the inspector" sorry.
void Start () {
print (buildings[1]);
}
public Buildings[] buildings;
//All the buildings in the game with set values of int
[System.Serializable]
public class Buildings {
public class nothing {
public int id = 0;
}
public class tower {
public int id = 1;
public int health = 200;
public string resource = "TestCube";
}
public class wall {
public int id = 3;
public int health = 1000;
public string resource = "TestCube2";
}
public class gate {
public int id = 4;
public int health = 10000;
public string resource = "TestCube2";
}
}
Answer by Rumor · Apr 19, 2016 at 01:22 PM
Buildings is a class, so you would have to create an instance of the class. As im assuming you are wanting multiple Buildings Instances, or are you going to use Buildings as a singleton or container for buildings?
string getValueFromArray = Buildings[0].resource; The above line of code would assume that the variable Buildings is of list type but you actually want it to be the Class. Im not sure is that is actually achievable.
I would suggest creating a container class that has the following code.
using System.Collections.Generic; public List buildings = new List()