- Home /
Sorting Variables Help
Hello guys, I want to sort a list of 4 items and arrange them from highest to lowest according to specific variables. And also display the list on a GUI. Is that even possible?
Item1 has a script called Script1 which contains a variable called variable1
Item2 has a script called Script2 which contains a variable called variable2
Item3 has a script called Script3 which contains a variable called variable3
Item4 has a script called Script4 which contains a variable called variable4
Answer by DiegoSLTS · May 26, 2015 at 05:28 PM
If the Scripts are not related in any way (i.e, they're different components and don't extend the same base script) or the variables are different variables (i.e. variables with different names) you'll have to do it manually considering all the "steps" of a usual sorting algorithm. It could look really bad in code and it's really bad for any kind of editing or reuse.
Anyway, if you are in that situation and still need to sort the items with those conditions you probably want to redesing your code to have something in common, to be able to use a standard sorting algorithm. For example, extract those variables into a CommonScript with a variable called "singleVariable", then your items could have a CommonScript each, and Script1 to Script4 can use the "singleVariable" variable in the CommonScript attached to the same gameObject (you can force the inclusion of other scripts).
Then, the items could be stored in a CommonScript array and you can write a traditional sort comparing each item.singleVariable. Here you can find some method to sort an array: http://forum.unity3d.com/threads/sorting-arrays.136097/
So if the script in each gameobject have the same name it'll be easier to compare? And is this true for the variables too?
Yes, if you have 4 items with different scripts and different variable names you have to write a sort algorithm that uses all those names. Following the names you used in your question, to sort 2 items you'll need some code similar to this:
GameObject first = null;
GameObject second = null;
if (item1.GetComponent<Script1>().variable1 > item2.GetComponent<Script2>().variable2) {
first = item2;
second = item1;
} else {
first = item1;
second = item2;
}
It doesn't look bad, but what about 3 items?
GameObject first = null;
GameObject second = null;
GameObject third = null;
if (item1.GetComponent<Script1>().variable1 > item2.GetComponent<Script2>().variable2 && item1.GetComponent<Script1>().variable1 > item3.GetComponent<Script3>().variable3) {
if (item2.GetComponent<Script2>().variable2 > item3.GetComponent<Script3>().variable3) {
first = item3;
second = item2;
} else {
first = item2;
second = item3;
}
third = item1;
} else if (item2.GetComponent<Script2>().variable2 > item1.GetComponent<Script1>().variable1 && item2.GetComponent<Script2>().variable2 > item3.GetComponent<Script3>().variable3) {
if (item1.GetComponent<Script1>().variable1 > item3.GetComponent<Script3>().variable3) {
first = item3;
second = item1;
} else {
first = item1;
second = item3;
}
third = item3;
} else {
if (item1.GetComponent<Script1>().variable1 > item2.GetComponent<Script2>().variable2) {
first = item2;
second = item1;
} else {
first = item1;
second = item2;
}
third = item2;
}
Now that's ugly, just imagine sorting 4 items... And worse, what if you find out you need one more button tomorrow? You can simplify some expressions getting the value from each variable once in temporary variables and comparing them, but you'll still need all those if-else-if levels or something similar. You can also store all the items in an array ins$$anonymous$$d of "first", "second" and "third" variables, which is not a bad idea, but again, that's not the main problem.
If all the items have the same component you can use a loop, and there are lots of algorithms that work that way. Picking the first piece of code on that link that doesn't use external libraries it could look like this:
GameObject holder;
for(int i = 1; i < items.Count; i++) {
int j = i;
while(j > 1) {
if(items[j-1]).GetComponent<CommonScript>().singleVariable < items[j].GetComponent<CommonScript>().singleVariable) {
holder = items[j-1];
items[j-1] = items[j];
items[j] = holder;
j--;
}
else
break;
}
}
Note that for this to work the items must be inside an array, but it's the same code for 2, 3, 4 or 1000 items.
GameObject first = null; GameObject second = null; if (item1.GetComponent().variable1 > item2.GetComponent().variable2) { first = item2; second = item1; } else { first = item1; second = item2; }
If its possible can you write a script for the 8 objects like you did for this example please? Until I figure out the shorter version please and thank you.
Thanx I get what you are saying but I'm still a bit confused. Im not good with the coding yet. Do I use this in an Update or onEnter function? Or do I need to declare any variables or anything? And can I display my results on GUI? Sorry if I'm asking daft or too many questions but I'm new to this. I'm sure once I get it down I'll look back and laugh and I'll have patience with future newbies I'll be assisting lol
I don't know where to call this, that code is usually the body of a "sort" method somewhere that you call whenever you have to sort an array.
If you call it in an Update function the array will be sorted on every frame, which may be usefull if the values change really often, but kind of useless if the values change every now and then (consider that there might by like 60 frames per second).
If the changes are not done frequently you might want to sort the array whenever a value changes, so the code would be in some setter function, or an OnClick callback if a button changes the value.
It's really hard to tell you where to put it because there's never a correct way, there are ways with different pros and cons.
For that code to work you only need an items array that holds all the items you want to sort.
You can display the result in your GUI but again, there are a lot of ways to do it and depends on what you want to do. What is an item? What do you want to display? The values of the variables or the name of the items?
The easiest thing I can think of is making a string with all the items names and then set that string as the text of a UI Text component.
This are pretty common stuff in program$$anonymous$$g, if you're not confortable with this you might want to at least follow some of the official tutorials, they'll give you an idea of how to work with the GUI and some other tutorials on working with arrays. Program$$anonymous$$g is not easy and making your own stuff without a good understanding of how code is writen will be twice as hard.
This tutorial is intended for Unity beginners: http://unity3d.com/learn/tutorials/projects/roll-a-ball
Yes I want to call it during update because its a ranking system. "Item1" is actually a gameobject called "Car1". "Item2" is "Car2" etc. I want to display the list of names in ascending order according to their variables. Or maybe just display the main car's (Car1) race position (1st, 2nd etc.) according to the variables in the list. Which ever is simplest until I fully understand the coding. Its actually 8 cars but I was trying to simplify the situation hence why I wasnt using the real names of the gameobject, scripts or variables. Was trying a little reverse engineering.
Your answer
Follow this Question
Related Questions
How to arrange list 3 Answers
Storing a variable and it's name 3 Answers
What is the quickest way of getting the most common item in a list or array? 1 Answer
How to find the opposite variables list? 1 Answer
Adding and Removing to a Inbuild Array 2 Answers