I’m basically building a system that lets me populate my game class structure. At first I just was building a class structure, but then I realized I could do better, make it more versatile, and now what was a “class” before is now what I’m calling a “Category”. Instead of a Class for “Stats” and one for “Races” and one for “CharacterClasses” etc, I have a list of entries in a class called “Data”.
Data[0].name may equal “Stats”, for instance.
And Data has a list called “items” of the class Items. Data & Items both have Lists for various types of information – a class called “Floats” just holds a string name and a float value. This way a data[0].items[0].floats[0].name = “Default Stat Value”.
idk if this is making sense. The List for Floats (And other data holding classes, including ones that hold a list of values instead of a single value), is set in the Data class. This way all Items will have the same set of data lists.
For instance, the single float value “Default Stat Value”, is something that all Items in the Stats (Data class) will require.
I go a bit further though, and allow one Category to reference another. So a Data entry for “Classes” will include a reference to the Data entry “Stats”, but in float value . That’s the Class “DataFloats”, which has a name, and “dataName” (name of the referenced category), and a List of float values. I may call this “Stat Proficiencies”, and now when I edit each race, I can set their default stat proficiency – a value I’ll use later in the actual logic of the game.
The benefit here is that I can add and delete Stats and they’ll be automatically added to all other lists that reference the Stats data list.
Does that make sense?
The problem is that there are a lot of types – floats, ints, bools, strings, Texture2ds, audioClips, gameObjects etc. For each one, I need a single class and a “Data” class. Like “Floats” and “DataFloats”. (Although I think I may be able to combine those into one class…I may try to do that as I need to re-strcuture this anyway, to make it work with the advice given so far).
Whenever I want to code any operation, such as AddItemToDataCategory, the method ends up being very long, as it needs redundant loops for each data type.
public void AddItemToDataCategory(string name, int d){
// Check name first
for (int i = 0; i < master.data [d].items.Count; i++) { // For each current item...
if (master.data [d].items[i].name == master.data[d].newItemName) { // if the names match
// Leave an error in the console
Debug.LogError("Error: The name " + master.data[d].newItemName + " has already been assigned to an Item in this Category.");
return; // break the function
}
}
// Add the new item
master.data[d].items.Add (new Items (master.data[d].newItemName));
int itemID = master.data[d].items.Count - 1;
// Now add custom variables
for (int i = 0; i < master.data[d].floats.Count; i++){
master.data [d].items [itemID].floats.Add (new Floats (master.data [d].floats[i].name));
}
for (int i = 0; i < master.data[d].ints.Count; i++){
master.data [d].items [itemID].ints.Add (new Ints (master.data [d].ints[i].name));
}
for (int i = 0; i < master.data[d].strings.Count; i++){
master.data [d].items [itemID].strings.Add (new Strings (master.data [d].strings[i].name));
}
for (int i = 0; i < master.data[d].bools.Count; i++){
master.data [d].items [itemID].bools.Add (new Bools (master.data [d].bools[i].name));
}
for (int i = 0; i < master.data[d].gameObjects.Count; i++){
master.data [d].items [itemID].gameObjects.Add (new GameObjects (master.data [d].gameObjects[i].name));
}
for (int i = 0; i < master.data[d].texture2Ds.Count; i++){
master.data [d].items [itemID].texture2Ds.Add (new Texture2Ds (master.data [d].texture2Ds[i].name));
}
for (int i = 0; i < master.data[d].audioClips.Count; i++){
master.data [d].items [itemID].audioClips.Add (new AudioClips (master.data [d].audioClips[i].name));
}
for (int i = 0; i < master.data[d].dataSingles.Count; i++){
master.data [d].items [itemID].dataSingles.Add (new DataSingle (master.data [d].dataSingles[i].name, master.data [d].dataSingles[i].dataName));
}
for (int i = 0; i < master.data[d].dataFloats.Count; i++){
master.data [d].items [itemID].dataFloats.Add (new DataFloats (master.data [d].dataFloats[i].name, master.data [d].dataFloats[i].dataName));
for (int v = 0; v < master.data [d].dataFloats [i].value.Count; v++) {
master.data [d].items [itemID].dataFloats [master.data [d].items [itemID].dataFloats.Count - 1].value.Add (0.0f);
}
}
for (int i = 0; i < master.data[d].dataInts.Count; i++){
master.data [d].items [itemID].dataInts.Add (new DataInts (master.data [d].dataInts[i].name, master.data [d].dataInts[i].dataName));
for (int v = 0; v < master.data [d].dataInts [i].value.Count; v++) {
master.data [d].items [itemID].dataInts [master.data [d].items [itemID].dataInts.Count - 1].value.Add (0);
}
}
for (int i = 0; i < master.data[d].dataBools.Count; i++){
master.data [d].items [itemID].dataBools.Add (new DataBools (master.data [d].dataBools[i].name, master.data [d].dataBools[i].dataName));
for (int v = 0; v < master.data [d].dataBools [i].value.Count; v++) {
master.data [d].items [itemID].dataBools [master.data [d].items [itemID].dataBools.Count - 1].value.Add (false);
}
}
for (int i = 0; i < master.data[d].dataStrings.Count; i++){
master.data [d].items [itemID].dataStrings.Add (new DataStrings (master.data [d].dataStrings[i].name, master.data [d].dataStrings[i].dataName));
for (int v = 0; v < master.data [d].dataStrings [i].value.Count; v++) {
master.data [d].items [itemID].dataStrings [master.data [d].items [itemID].dataStrings.Count - 1].value.Add ("");
}
}
for (int i = 0; i < master.data[d].dataGameObjects.Count; i++){
master.data [d].items [itemID].dataGameObjects.Add (new DataGameObjects (master.data [d].dataGameObjects[i].name, master.data [d].dataGameObjects[i].dataName));
for (int v = 0; v < master.data [d].dataGameObjects [i].value.Count; v++) {
master.data [d].items [itemID].dataGameObjects [master.data [d].items [itemID].dataGameObjects.Count - 1].value.Add (null);
}
}
for (int i = 0; i < master.data[d].dataTexture2Ds.Count; i++){
master.data [d].items [itemID].dataTexture2Ds.Add (new DataTexture2Ds (master.data [d].dataTexture2Ds[i].name, master.data [d].dataTexture2Ds[i].dataName));
for (int v = 0; v < master.data [d].dataTexture2Ds [i].value.Count; v++) {
master.data [d].items [itemID].dataTexture2Ds [master.data [d].items [itemID].dataTexture2Ds.Count - 1].value.Add (null);
}
}
for (int i = 0; i < master.data[d].dataAudioClips.Count; i++){
master.data [d].items [itemID].dataAudioClips.Add (new DataAudioClips (master.data [d].dataAudioClips[i].name, master.data [d].dataAudioClips[i].dataName));
for (int v = 0; v < master.data [d].dataAudioClips [i].value.Count; v++) {
master.data [d].items [itemID].dataAudioClips [master.data [d].items [itemID].dataAudioClips.Count - 1].value.Add (null);
}
}
// Now we need to add new items for every custom variable already referencing this category
for (int a = 0; a < master.data.Count; a++) { // For each data category
for (int t = 0; t < master.data[a].items.Count; t++){ // For each item in the category
for (int v = 0; v < master.data [a].items [t].dataFloats.Count; v++) { // For each dataFloat item
if (master.data [a].items [t].dataFloats [v].dataName == name) { // If the dataName of the dataFloat = name
master.data [a].items [t].dataFloats [v].value.Add (0.0f);
}
}
for (int v = 0; v < master.data [a].items [t].dataInts.Count; v++) { // For each dataInts item
if (master.data [a].items [t].dataInts [v].dataName == name) { // If the dataName of the dataFloat = name
master.data [a].items [t].dataInts [v].value.Add (0);
}
}
for (int v = 0; v < master.data [a].items [t].dataBools.Count; v++) { // For each dataBools item
if (master.data [a].items [t].dataBools [v].dataName == name) { // If the dataName of the dataFloat = name
master.data [a].items [t].dataBools [v].value.Add (false);
}
}
for (int v = 0; v < master.data [a].items [t].dataStrings.Count; v++) { // For each dataStrings item
if (master.data [a].items [t].dataStrings [v].dataName == name) { // If the dataName of the dataFloat = name
master.data [a].items [t].dataStrings [v].value.Add ("");
}
}
for (int v = 0; v < master.data [a].items [t].dataGameObjects.Count; v++) { // For each dataGameObjects item
if (master.data [a].items [t].dataGameObjects [v].dataName == name) { // If the dataName of the dataFloat = name
master.data [a].items [t].dataGameObjects [v].value.Add (null);
}
}
for (int v = 0; v < master.data [a].items [t].dataTexture2Ds.Count; v++) { // For each dataTexture2Ds item
if (master.data [a].items [t].dataTexture2Ds [v].dataName == name) { // If the dataName of the dataFloat = name
master.data [a].items [t].dataTexture2Ds [v].value.Add (null);
}
}
for (int v = 0; v < master.data [a].items [t].dataAudioClips.Count; v++) { // For each dataAudioClips item
if (master.data [a].items [t].dataAudioClips [v].dataName == name) { // If the dataName of the dataFloat = name
master.data [a].items [t].dataAudioClips [v].value.Add (null);
}
}
}
}
}
In that one function, there are 3 sections that could be made smaller if I could somehow replace just a few of the phrases. In the last bit, for instance, “dataAudioClips” (stated 3 times) is the only change between each for loop.
If I want to add a new type, I need to add a new for loop in every method that I’ve created. It gets tedious and boring and I’m sure there’s a better way of doing it.
In my brain, the “Easiest” way (knowing that I don’t know if this is possible or if there is an easier way) would be to have another List of “Types” where all versions of phrases I may need is kept.
AudioClips
audioClips
for instance, so that in the following loop:
for (int i = 0; i < master.data[d].audioClips.Count; i++){
master.data [d].items [itemID].audioClips.Add (new AudioClips (master.data [d].audioClips[i].name));
I would simply be able to say "For each entry in ‘Types’, do this code but use the proper phrase for where “audioClips” or “AudioClips” etc are. A way to do that would also keep me from having to re-do too much 
EDIT: The problem I’m seeing now is that “DataFloats” and “DataInts” etc, which I can make inherit from a class I"ll call “DataHolder”, can’t inherit from Data or Items. I don’t think they can at least – they each have a list called “value” which is of their unique type. I suppose it could have a list called “valueFloats” etc… but that would only work if I had a way of injecting multiple variable phrases into the code.