Unity freezes when I juggle Lists and SortedLists.

Hey everyone,

I have a scene full of objects - “Sites”. Their positions are stored in a List < Vertex3 > siteList. I’d like to get a List < List < int > > siteNeighboursList - list of lists of neighbours - indexes of sites sorted by distance from each site.

My current code freezes Unity whenever I try to populate siteList with more than ~200 entries.

private void CreateNeighboursList()
    {
        var oneSiteDistancesList = new SortedList(); // key - distance; value - site index
        var oneSiteSortedList = new List<int>(); //value - site index, sorted by distance
        float tempDistance;

        for (int i = 0; i < siteList.Count; i++)
        {
            oneSiteDistancesList.Clear();
            oneSiteSortedList.Clear();

            for (int j = 0; j < siteList.Count; j++)
            {
                if (i != j) // to avoid sites trying to list themselves as neighbours
                {
                    tempDistance = Vector3.Distance(siteList*, siteList[j]);*

while (oneSiteDistancesList.ContainsKey(tempDistance)) // to avoid duplicate keys
{
tempDistance += 0.000001f;
}
oneSiteDistancesList.Add(tempDistance, j);
}
}

for (int j = 0; j < oneSiteDistancesList.Count; j++)
{
oneSiteSortedList.Add((int)oneSiteDistancesList.GetByIndex(j));
}

siteNeighbours.Add(oneSiteSortedList);
}
}
Is there something wrong with the code? Should I try different approach? Should I store the values differently?
Thanks in advance.

It is most likely that as you add more and more items to the oneSiteDistancesList, it eventually takes longer to go through it. Which make the while loop appear to be endless. Try using a coroutine like this instead

List<Vertex3> siteList = new List<Vertex3>(); // assuming this is how you have this defined

// moved the following two to be global
private SortedList oneSiteDistancesList = new SortedList(); // key - distance; value - site index
private List<int> oneSiteSortedList = new List<int>(); //value - site index, sorted by distance

private void CreateNeighboursList()
{

    if (siteList.Count > 0)
    {
        float tempDistance;

        for (int i = 0; i < siteList.Count; i++)
        {
            oneSiteDistancesList.Clear();
            oneSiteSortedList.Clear();

            for (int j = 0; j < siteList.Count; j++)
            {
                if (i != j) // to avoid sites trying to list themselves as neighbours
                {
                    tempDistance = Vector3.Distance(siteList*, siteList[j]);*

StartCoroutine(CheckDistance(tempDistance, j));
}
}

for (int j = 0; j < oneSiteDistancesList.Count; j++)
{
oneSiteSortedList.Add((int)oneSiteDistancesList.GetByIndex(j));
}

siteNeighbours.Add(oneSiteSortedList);
}
}
}

IEnumerator CheckDistance(float tempDistance, int site)
{
while (oneSiteDistancesList.ContainsKey(tempDistance)) // to avoid duplicate keys
{
tempDistance += 0.000001f;
yield return null;
}
yield return null;
oneSiteDistancesList.Add(tempDistance, site);
}
It may still take a while to process a large number of sites, but now other processing can take place including quitting the game immediately if desired.