Recursive reference within a list
Hello all,
I am designing a pantheon of gods in my current project. To do so I am keeping a list within my game manger singleton which keeps track of all the information on each god within that list; doing this though I've ran into a problem— I need that list (which holds a reference to each god as an element) to hold another list within that element to 'rival gods' which should reference other gods within that same list.
I'm not sure if this is a problem in design or if I need a certain structure which I haven't used before. I'll try to do a little rundown to better explain it...
GameManager Class->Holds reference to PantheonManager->holds List (God being a class in itself which holds another list to 'rivalGods' so List as of now)...
I'd rather not use strings (god names) for checking and what not as they're slow, thought about giving each one an int ID for faster checking but would rather a straight reference to a element in the initial list, is this possible and if so what would be the ideal method for this?
Edit: Hey all, after reading a bit more into this I think I've narrowed down what I was looking for originally. This thread here seems to do the trick, so for future reference if anyone is trying to do something similar to this I would go for this method. Thanks again all!
This could probably be abstracted a bit more as well so the RefreshEnum isn't tied directly to that specific class...
Code Below
public class MyClass : MonoBehaviour
{
public void RefreshEnum()
{
string enumName = "MyEnum";
string[] enumEntries = new string[myList.Count] as string[];
string filePathAndName = "Assets/Scripts/Enums/" + enumName + ".cs"; //The folder Scripts/Enums/ is expected to exist
for(int i = 0; i < myList.Count; i++)
{
enumEntries[i] = myList[i].myElementName;
}
using(StreamWriter streamWriter = new StreamWriter(filePathAndName))
{
streamWriter.WriteLine( "public enum " + enumName );
streamWriter.WriteLine( "{" );
for( int i = 0; i < enumEntries.Length; i++ )
{
string lastItem = (enumEntries.Length == 0) ? null : enumEntries[enumEntries.Length - 1];
if(enumEntries[i] != lastItem)
{
streamWriter.WriteLine( "\t" + enumEntries[i] + "," );
}
else
{
streamWriter.WriteLine( "\t" + enumEntries[i]);
}
}
streamWriter.WriteLine( "};" );
}
AssetDatabase.Refresh();
}
} //end class
//then a custom Editor Class, here below...
[CustomEditor(typeof(MyClass))]
public class MyCustomEditor : Editor
{
public override void OnInspectorGUI()
{
DrawDefaultInspector();
MyClass mC = (MyClass)target;
if(GUILayout.Button("Refresh Enum"))
{
mC.RefreshEnum();
}
}
}
What you're thinking of is standard. As you wrote, just have a reference to it. Think of how public GameObject nearestEnemy; is just a reference. Same thing. And no need to think about whether that technically counts or doesn't count as being recursive.
Answer by Cynikal · Nov 03, 2016 at 02:59 PM
Without seeing your script, I can only assume how its setup... But here is a basic recursive list.
foreach(God myGod in PantheonManager.GodsList) //Will loop through ALL gods.
{
foreach (God rival in PantheonManager.GodsList) //Will loop through the same list again
{
if (rival != myGod) //add all gods except itself as a rival.
{
myGod.RivalsList.Add(rival);
}
}
}
Answer by YoYo89 · Nov 03, 2016 at 11:47 PM
Thanks for the quick response guys! I think my main problem is that these Gods don't exist anywhere other than this list, they're very much just data-driven entities in the game which keep track of tributes, appeasement, etc... Here is a picture of my inspector using the script as of now...
I'm trying to avoid the 7-level limit for recursion here as well, which has become an issue in my current design.
So to try and focus more simply on my issue -> Each god must hold a reference to certain other gods, not all others, this would be ideal if it was a drop down selection or drag and drop type situation.
-Perhaps as you add to the initial 'Gods' list these elements get added as enumerated items in real-time which can be selected under the rivals and allied lists, I feel like maybe a custom editor script could do the trick?
Sorry for not being able to put this in better terms, I'm having trouble myself putting it in to words.
public enum Gods
{
Horrence,
$$anonymous$$orrag,
Cynikal
}
Rival Gods List could reference the Enum of Gods.
--THat'll be your drop down list.
Then just compare the enum value with other stuff to get specific stats.
Setting up a data structure is just a generic program$$anonymous$$g thing. UA isn't so much for that.
But if it's an issue of wanting to "see" your little guys, you could make the "deity" class be a monobehaviour. Then each one can be on a gameObject, named Zeus or Ares (I only know Xena: Warrior Princess.) For grouping, can put them all in an empty. You can then drag those into whatever lists you like.
Some people even forget making a real master list. The empty and it's deity children is the master list. That's crude, but it might make more sense than a pure coding approach.
O$$anonymous$$ cool, I think I was trying to go for something a bit fancier in terms of not leaving a foot-print on the scene other than in the Game$$anonymous$$anager, like some type of enum that could grab its elements from the 'Name' item of each god in this list.
Looking at it again I might just treat this as a simple tree of game objects and reference those for now like Owen has mentioned above— the reason being I don't know the Gods that are going to fill this list just yet, but that still gives me the flexibility I'm looking for, just with a visible foot-print in the scene. Thanks for the advice everyone!
Your answer

Follow this Question
Related Questions
Get all combinations of a list of lists of arrays... 2 Answers
MonoDevelop Unity API reference function with wrong path. How to Fix it? 1 Answer
Create an array of scripts that don't affect each other? 1 Answer
Get reference to spawned object from server on client 1 Answer
How do I reference int from other script 0 Answers