- Home /
Loading game objects into a generic list in specified order
Greetings all,
I'm using C# and a generic List.
I have a setup where the user chooses a path which may take them through one or more Unity scenes. Because of this, I have created a script "Scene.cs" to hold a list of waypoints for the user to visit. Each waypoint may have a series of two or three objects to click on. Clicking may play an audio clip, a movie texture (video clip), or a static image with an audio clip.
When the scene loads, the "Scene.cs" script creates a list of waypoints (in Start):
foreach(Waypoint wp in GetComponentsInChildren<Waypoint>(true))
{
waypointList.Add(wp);
// Ensure all waypoint scripts disabled, trigger will activate the script
wp.enabled = false;
}
I added an additional waypoint, Start, as logical place holder. When I use Start (waypoint), it loads Start, Waypoint 1, Waypoint 2, and Waypoint 3 in the list in the correct order.
I duplicated Start and renamed it to End as another waypoint. In the Unity Hierarchy, End jumps up in front of Start which leads me to believe GameObjects are listed in alphabetical order. When I run my scene the list shows Start then End, and the rest of the waypoints follow. This leads me to believe that the list is not using alphabetical order.
So, I deleted End and created an empty GameObject, attached my waypoint script to it, renamed it to End and expected it to jump to the front. In the Hierarchy, this happened as I expected. In the generated list it jumped to the first element of the list.
When I changed the name to Waypoint 4, it jumped to the end of the Hierarchy but remained the first element in the list.
Next I deleted that, created a new empty Game Object, renamed it to Waypoint 4 and attached the script. This time, it showed up at the end of the Hierarchy and as the last element of the list.
For grins, I changed the name from Waypoint 4 to End. In the Hierarchy, it jumped to the top (alphabetical) but in the List it remained as the last element of the list.
So, does anyone know by what order game objects are inserted into a list?
I want to be able to guarantee the order. It seems that the behavior changes depending on if you duplicate one and rename it. Seems completely bizarre. For organization, I'd like the way it shows up in my Hierarchy to be the same in the generated list.
Can anyone point me in the right direction?
I think the question isn't so much 'what order are gameObjects inserted into a list' so much as it is 'what order does Transform[index] order its children in'.
Answer by syclamoth · Jan 25, 2012 at 01:24 AM
Honestly, if I wanted to be sure I would just declare the list public and manually assign its elements in the correct order in the inspector. However, this is pretty slow and time-consuming, and is the kind of thing that you should really get a computer to do anyway.
So, alternatively, you could use a special case for the beginning and end variables (assign them manually in the inspector), and then use a sorted list to sort them into alphabetical order:
SortedList<string, Waypoint> alphabetList = new SortedList<string, Transform>(); foreach(Waypoint wp in GetComponentsInChildren<Waypoint>()) { if(wp == startWaypoint || wp == endWaypoint) { continue; } alphabetList.Add(wp.gameObject.name, wp); }
List<Waypoint> sortedWaypoints = new List<Waypoint>(alphabetList.Values); sortedWaypoints.Add(endWaypoint); sortedWaypoints.Insert(0, startWaypoint);
foreach(Waypoint element in sortedWaypoints) { Debug.Log(element.gameObject.name); }
I think that should do it. Sorry I couldn't answer your actual question, but I have a sneaking suspicion that it works in a way that is fairly opaque and magical, being one of those things that gets completely broken if you mess with the Library folder.
Thank you for that example solution. Yes, I agree that it is a bit like a black box, but it would be sure helpful to know how the list places items in (is it by GUID or some other classifier).
Interestingly, I had considered doing something like this, but thanks for an example of how to do it. I suppose I can just create them one at a time and name them alphabetically (as that seems to work, but is pretty slow and time consu$$anonymous$$g).
The list is public and shows up in the inspector but it is initially empty and only fills in when I hit Play in the Unity Editor. So, I'd have to set the size of the list explicitly. At that point, why not just use an array?
Anyway, I'll accept this as an answer. Thanks!
Answer by karl_ · Jan 25, 2012 at 01:36 AM
If you'd like to ensure that your list is always alphabetical, just sort the resulting list with a custom IComparer that takes GameObjects as a parameter.
http://msdn.microsoft.com/en-us/library/234b841s.aspx
And just 'cause, here's a quick example with my IComparer:
using System.Collections; using UnityEngine; using System.Collections.Generic;
public class GameObjectComparer : IComparer<GameObject> { return string.Compare(x.name, y.name, false); }
public class YourClass : MonoBehaviour { public List<GameObject> yourList = new List<GameObject>();
void Start()
{
GameObjectComparer gameObjectComparer = new GameObjectComparer();
yourList.Sort(gameObjectComparer);
}
}
$$anonymous$$arl, thanks for another way to achieve my goal. I was planning on accepting both as an answer as both are valid ways to attack this. $$anonymous$$y apologies as I'd never had anyone answer my previous two questions.
It appears that I can get the items in the list in the order I want if I create them in the order I want them to appear in the list. They won't match the hierarchy unless I purposefully name them alphabetically.
Thanks again!
Well, to be fair, your previous two questions kind of required specialist knowledge that not everyone would have. This one is a purely Unity question, so is fair game.
Well, there are a lot of smart people and specialists hanging around these parts. :)
I don't think the PHP one is too far out of spec as I'm sure plenty of people have tried to use PHP/$$anonymous$$ySQL. The sad part on that one, the requirement for the login went away. But, I learned along the way, and isn't that what it is about (at least partially anyway)?
For my $$anonymous$$otionBuilder question, I guess I can't argue on that one. I guess it should have been an indication that Unity's own documentation on 3rd party tools doesn't even mention $$anonymous$$otionBuilder. I guess early on, with Unity attempting to fill more Indie Game Developer needs, maybe $$anonymous$$otionBuilder is too rich for Indie developer blood. But, now that they are also wooing AAA level $$anonymous$$ms/development, I'd think that there would be more info about $$anonymous$$otionBuilder. This is about to become important for me again as we're getting ready to get back into some animation work. If I ever get it figured out, maybe I'll come back and answer my own question for the benefit of others.
Anyway, thanks again for your help!
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
Initialising List array for use in a custom Editor 1 Answer
Illuminating a 3D object's edges OnMouseOver (script in c#)? 1 Answer
Flip over an object (smooth transition) 3 Answers