Resorting List of gameobjects with assorted attached scripts

I can’t seem to figure out a way to sort the list of gameobjects that are collected by tag name, that have different scripts, with the same int name, but different values. I want to sort the collection once gathered and the arrange by “start channel” of each… ascending from 1.2.3.4… etc.

public class FXManager : MonoBehaviour
{
    private List<GameObject> effects = new List<GameObject>();
    public List<Effect> effect = new List<Effect>();

    void Start()
    {
        
        foreach (GameObject item in GameObject.FindGameObjectsWithTag("Effect"))
        {
            effects.Add(item);

            FXTrigger fXTrigger = item.GetComponent<FXTrigger>();
            

            if (fXTrigger != null)
            {
                Effect fx = new Effect();
                fx.FX_Type = fXTrigger.FX_Type;
                fx.channelsUsed = fXTrigger.channelsUsed;   
                fx.startChannel = fXTrigger.startChannel;
                effect.Add(fx);
            }

            FXLighting3ch fxLighting3Ch = item.GetComponent<FXLighting3ch>();

            if (fxLighting3Ch != null)
            {
                Effect fx = new Effect();
                fx.FX_Type = fxLighting3Ch.FX_Type;
                fx.channelsUsed = fxLighting3Ch.channelsUsed;
                fx.startChannel = fxLighting3Ch.startChannel;
                effect.Add(fx);
            }

            FXRamp1ch fxRamp1Ch = item.GetComponent<FXRamp1ch>();

            if (fxRamp1Ch != null)
            {
                Effect fx = new Effect();
                fx.FX_Type = fxRamp1Ch.FX_Type;
                fx.channelsUsed = fxRamp1Ch .channelsUsed;
                fx.startChannel = fxRamp1Ch.startChannel;
                effect.Add(fx);
            }

        }

    }
}
[Serializable]
public class Effect
{
    public string FX_Type;
    public int channelsUsed;
    public int startChannel;

}

I’m no pro at this, but I think you could make some logic where if the index is larger than the array you could use .Insert(Index #) Instead of .Add and if the index is smaller than array size you could do array[Index #] = whatever.

so logic would look something like…


if(wantedIndexNumber >= array.Size()) array.SetSize(wantedIndex)
  array[wantedIndexNumber] = whatever;


I’m sure there’s a better solution by people better with code, but if no one else is around to chime in you could try that.

Actually I’m not sure insert instantly sets the size of the array. You could do Array.Add() at the start several times to get the right size. Again I have no idea what i’m doing so I can learn as much from an answer to this as you would :stuck_out_tongue:

Edit: Ok i did a quick google search and found out about SetSize and updated the above code.

This is what the List<T>.Sort() method is for: List<T>.Sort Method (System.Collections.Generic) | Microsoft Learn

Generally you’ll want to use it with the overload that takes the Comparison<T> delegate: Comparison<T> Delegate (System) | Microsoft Learn which is a delegate that takes two instances of T and returns an integer.

As per the docs on comparison, you return -1 if x should be sorted before y, 0 if they’re the same, and +1 if it comes after.

In this case, as you want to sort by an integer value, which already implements IComparable<int>, you can just use its existing .CompareTo method:

public static int EffectStartChannelComparison(Effect left, Effect right)
{
	return left.startChannel.CompareTo(right.startChannel);
}

// usage 
effects.Sort(EffectStartChannelComparison);
1 Like