Ordering a list of GameObjects

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class GoList : MonoBehaviour {
	public GameObject[] enemyList;
	public int enemyListLength;

	// Use this for initialization
	void Awake () {
		enemyList = GameObject.FindGameObjectsWithTag ("Enemy");
		enemyListLength = enemyList.Length;


		List<GameObject> GObj = new List<GameObject> ();

		for (int i = 0; i < enemyListLength; i++){
			GObj.Add (enemyList*);*

_ print (enemyList*.name);_
_
}*_

* GObj.Sort ();*
* }*

* // Update is called once per frame*
* void Update () {*

* }*
}
When I run this code I get an error (ArgumentException: does not implement right interface) on the line with sort. If I comment that line everything works great, except for the fact that the list isn’t sorted. I want to be able to sort the list based off a variable stored in the GameObjects. Some research I’ve done says the icomparer/icomparable might help, but I have no idea how to implement that. I’d prefer no to use Linq if I can get away with it, it still confuses the heck out of me haha. Any and all help will be appreciated!

What property do you want to sort on?

3 Answers

3

Essentially the error is telling you there is no natural way to sort a list of GameObjects. How do you tell if which GameObject comes first?

You need to provide a sort method to GObj.Sort(). The following pseudo code sorts the GameObjects in alphabetical order by name.

....
GObj.Sort(SortMethod(GameObject A, GameObjectB));
....

private int SortMethod  (GameObject A, GameObjectB){
    if (!A && !B) return 0;
    else if (!A) return -1;
    else if (!B) return 1;
    else return A.name.CompareTo(B.name);
}

Each GameObject has a script on it with a public variable speed. The greater speed means higher on the list that GameObect would be. How would I compare those values in the SortMethod?

Just change line 9 to reflect the actual comparison you want to achieve. private int SortMethod (GameObject A, GameObjectB){ if (!A && !B) return 0; else if (!A) return -1; else if (!B) return 1; else if (A.GetComponent<ScriptName>().speed > B.GetComponent<ScriptName>().speed) return 1; else return -1; }

If you are sorting the list frequently consider using a SortedList or SortedDictionary as these structures are more efficient.

So I'm getting an error on GObj.Sort(SortMethod(GameObject A, GameObject B)); stating unexpected symbol 'A' I'm assuming the A and B need to have a space between them and GameObject. My SortMethod looks like this: private int SortMethod (GameObject A, GameObject B){ if (!A && !B) return 0; else if (!A) return -1; else if (!B) return 1; else if (A.GetComponent<Attributes>().speed > B.GetComponent<Attributes>().speed) return 1; else return -1; }

I haven't ever tried to implement this, try GObj.Sort(SortMethod(GameObject, GameObject)); Or GObj.Sort(SortMethod); I'll check out the docs and give you a proper syntax later

May I direct you to this question I asked myself some time ago, it has everything you need (albeit in UnityScript):

I think you can write an inherited class from IComparer to tell the code how to sort your list. I believe this code works - haven’t gotten to multiplayer testing yet so it might need some tweaking.

using System.Collections.Generic;

public class AggroComparer : IComparer<AggroData>
{
    public int Compare(AggroData x, AggroData y)
    {
        if (x.AggroLevel == y.AggroLevel)
        {
            return 0;
        }
        if (y.AggroLevel > x.AggroLevel)
        {
            return 1;
        }
        else return -1;
    }
}