I am using static lists of classes, and am trying to simplify or genericize the functions for ease of typing and copy/pasting. I'll try to explain the best I can:
public static List<Resources> allResources = new List<Resources>();
public static List<Resources> allIron = new List<Resources>(); // Iron.cs is child
public static List<Resources> allCoal = new List<Resources>(); // Coal.cs is child
public Iron GetIron(Vector3 position)
{
if (allIron.Count > 0)
{
for (int i = 0; i < allIron.Count; i++)
{
if (!allIron[i].gameObject.activeSelf)
{
allIron[i].trans.position = position;
allIron[i].gameObject.SetActive(true);
return (Iron)allIron[i];
}
}
}
Instantiate(prefabIron, position, Quaternion.identity, oreHolder.transform);
return (Iron)allIron[allIron.Count - 1];
}
So using this way of Object pooling, in order to have a function that does this, I would have to copy paste this function for each new resource, and change each call to the particular list. What I would like to do, but can't seem to manage, is this:
public Resource GetResource(List<Resource> resources, Vector3 position, GameObject prefab)
{
if (resources.Count > 0)
{
for (int i = 0; i < resources.Count; i++)
{
if (!resources[i].gameObject.activeSelf)
{
resources[i].trans.position = position;
resources[i].gameObject.SetActive(true);
return resources[i];
}
}
}
Instantiate(prefab, position, Quaternion.identity, oreHolder.transform);
return resources[resources.Count - 1];
}
But when trying to simplify a function like this(way less typing), it doesn't work. Passing a List into a function basically just copies it to be used within the function, and doesn't change the actual Lists entities, even though being static.
So my question is, is this at all possible? Or am I stuck with making a function for each resource, and living in copy/paste hell? Or even better, would there be a way to just make one function that can do it all? All my attempts have failed, any help or insight would be greatly appreciated, cheers!
I would like to note, that I could just for-loop through "allResources" since that list contains all of the child classes. However knowing that each new "Get" call is iterating through possibly (100,000 to infinity) would grind my gears just knowing the code is doing that in the background. This is why I made particular lists of each resource, that would cut the iterations down to a measly 10,000, when just looking for a particular item in game.
My question actually answered my question. My answer is the last post(website won't allow me to accept my own answer for 3 days). Special thanks to all who replied, you guys are awesome!
Not sure how it didn't work the first time, but the second snippet was correct, and the code works beautifully. Here is a better explanation that you can test for yourself:
// Main.cs
public static List<Resources> allResources = new List<Resources>();
public static List<Resources> allIron = new List<Resources>(); // Iron.cs is child
public static List<Resources> allCoal = new List<Resources>(); // Coal.cs is child
public Resources GetResource(List<Resources> resources, Vector3 position, GameObject prefab)
{
if (resources.Count > 0)
{
for (int i = 0; i < resources.Count; i++)
{
if (!resources[i].gameObject.activeSelf)
{
resources[i].trans.position = position;
resources[i].gameObject.SetActive(true);
return resources[i];
}
}
}
Instantiate(prefab, position, Quaternion.identity, oreHolder.transform);
return resources[resources.Count - 1];
}
So by having static List's of classes, and also having the "Get" call within same script, somehow the List is able to be passed without "copying" itself to be used within the function. So no special calls are needed. And during Instantiate() the Awake() method of Iron.cs is called within the same frame, so as you see Iron.cs adds itself to the List being called , then the next line of code gets it's index and returns the correct script.
// Resources.cs is child of Main.cs
// Iron.cs (child of Resources.cs)
public float amount;
void Awake()
{
allIron.Add(this);
}
^ as you can see, Iron.cs adds itself to the static List(instantly).
Then a simple call of GetResource() is used where needed. And since each script is a child of the previous, leading back to Main.cs, no other "Get" calls are needed. Especially not GetComponent() which is a performance killer, or worse yet a serious performance killer of an interface(IGetResource.cs).
// Drill.cs (also child of Main.cs)
if (isPowered)
{
timer++;
if (timer > tick)
{
Iron iron = (Iron)GetResource(allIron, pos, prefabIron);
iron.amount = 55.5f;
inventory.Add(iron);
timer = 0;
}
}
But as I said please test for yourself, and better yet use a benchmark test(min 100k objects). You will clearly see that this is the fastest and most performant way to do this :)