Hey guys. Trying to find out of there is a way to create a list of lists, so that you can cycle through and change objects of a list based on variable i. Obviously the code below doesn’t work, but am aiming for something like this. Any suggestions would be appreciated.
List<GameObject> list1, list2;
List<List> lists;
lists.Add(list1); lists.Add(list2);
for (int i = 0; i < lists.count; i++)
{
foreach (Gameobject object in lists(i))
{
//do something to object based in i
}
}
Do not use the name object … it’s already a type in C#.
And don’t use gameObject either, since that hides an inherited member.
Even using something as bland as thing or item is an improvement, but ideally you can give your code more semantics with something like enemy or bullet
You aren’t kidding. That’s a real brain-bender. Seems like it would work though, except it doesn’t populate the lists in the inspector. I wouldn’t even begin to know how to procedurally add the gameObjects to the lists. Is there any trick to make the lists show in the inspector outside of making it public?
Unity’s serialization system does not support multidimensional arrays or jagged arrays / lists. The inspector can only show thing which are serialized. Of course a custom inspector could show whatever you want, but that’s pretty pointless if that data is not serialized (except maybe for debugging purposes).
The only way how to serialize something that is more or less multi dimensional is to use an intermediate class / struct like this:
[System.Serializable]
public struct ListWrapper<T>
{
public List<T> list;
}
Now you can create a List of that type. Though watch out, Unity only supports a nesting depth of 7. So you can not nest infinitely deep.
public List<ListWrapper<GameObject>> yourList;
This can be serialized by Unity and can be viewed and edited in the inspector. In order to access an element in your nested list you would have to do something like:
GameObject go = yourList[1].list[5];
This would access the 6th gameobject element in the second list.
I did this with a music project where I had 4 different “instruments”, each with their own scale of 12 notes/individual waveforms. So each was an AudioClip[ ], then I created a List<> of those (iirc). In the Inspector it showed as 4 collapsible instruments (the text identifier) with 12 slots each for assigning the wave files. Worked great.
Also, you can assign/drag lists of assets to arrays in the Inspector all at once if you highlight them and drag to the main array label. They will fall into the slots in the order they were in the Project panel.
I appreciate all the input on this one guys. I was able to find a clumsy work-around where I set the gameobjects as children to form “lists” and then place the parents in an actual list. This way I can cycle through the children of the list gameobjects to do what I need to do. I’m surprised that Unity doesn’t have something a bit more accessible built into the system.
Kurt: As always, I appreciate and value your input. I’ll keep an eye out on how I’m naming my variables moving forward.
Bunny83: I’m gonna have to admit stupidity on this one. I tried to implement your solution but had trouble getting it to work. I know next to nothing about serialization, so I’m going to have to do some reading and come back to this later. Thanks for the advice.
SeeJayJames: This sounds simple enough, but I couldn’t quite figure out how to implement it. I’d love to see a code example. What type of list were you using to be able to nest arrays inside?
[System.Serializable]
public class AudioClipArray // to allow a 2D array for playing clips
{
public AudioClip[] clips;
}
and
public AudioClipArray[] clipArray;
So then you’ve got the main array named clipArray, and you can set how many you want (say 4, for 4 instruments). In each of those you’ll have a sub-array of the actual audio clips, which you can say how many, and populate them by dragging the clips in. You’ll need an array of AudioSources to play them if you want to be able to overlap (I think, maybe PlayOneShot allows it from a single source?)
You can initialize the array size and populate the clips in script too, I just used the Inspector.
Note that this technique (a custom class with arrays inside) can be used with any Component, or with GameObjects themselves. You can have as many elements inside the class as you want, I just have one. Very handy!
(edit: the screenshot got cut off, but there are Element 1, 2, and 3 below this first array, each with a clips[ ] array in them.)
Oh, I see. I didn’t realize the first time I read it that you were adding to Bunny83’s answer. I’ll definitely have to read more about serialization. It does look like what I’m looking for. Thanks for the script example!
Sounds good!
In my case I had the 4 instruments, each with an array of notes (all the same in each), so I can set my AudioSource.clip to clipArray[1].clips[5], for example. There was another array which pointed to the correct/current clips based on various conditions. Lots of flexibility, and of course it’s a snap to iterate through everything if you need to.
list of list is a mind bender, I have read about ways to display them in the inspector but every time I have worked with list of list I have had to manage it all on brain power alone list of list is tricky, but it can be achieved used and depended on to great effect. I have managed to make a list of list save to player prefs before, by making a custom list of list converter that followed key characters in a decoded string. So list of list is good stuff though it should never really be used in playerprefs when it’s much simpler to create and read a text file for your persistent data.