- Home /
Sorting builtin arrays
I need to sort the return of RaycastAll (a builtin array) from the nearest object to the farthest, but I can't figure out how to sort builtin arrays in a nice, tidy fashion.
What would be the best way to accomplish this?
Thanks
Answer by Mike 3 · Jul 13, 2010 at 10:14 PM
http://msdn.microsoft.com/en-us/library/system.array.sort.aspx
You'd have to write your own comparer class, but it's pretty trivial (and very customizable)
Edit:
import System;
function Start () { var raycasthits = Physics.RaycastAll(Camera.main.transform.position, Camera.main.transform.forward);
var output = ""; //this is for debugging
for(var rch in raycasthits) output += rch.collider.name + " "; //this is for debugging
Debug.Log(output); //this is for debugging
System.Array.Sort(raycasthits, new RaycastSorter());
output = ""; //this is for debugging
for(var rch in raycasthits) output += rch.collider.name + " "; //this is for debugging
Debug.Log(output); //this is for debugging
}
class RaycastSorter implements IComparer //class RaycastSorter extends IComparer //in unity 2.6 { function Compare(a : System.Object, b : System.Object) : int { if ( !(a instanceof RaycastHit) || !(b instanceof RaycastHit)) return; var raycastHitA : RaycastHit = a; var raycastHitB : RaycastHit = b;
return sqDistA.distance.CompareTo(sqDistB.distance);
}
}
Wow - couldn't ask for a better answer. Thanks - you've saved me a ton of time and many headaches!
Update: I found that the square magnitude calculation was a little unreliable, so I'm using raycastHitA.distance ins$$anonymous$$d.
Not sure why it works better, but it does.
Ah, right - my original tests were with FindObjectsOfType(Collider), so I had to grab the distance from Collider objects ins$$anonymous$$d of raycasthit ones - using distance is a lot less code indeed, so changed the example for future readers, thanks :)
Answer by skovacs1 · Jul 13, 2010 at 11:06 PM
This looks like this post. You could write your own comparer class or function or just store an IComparable class within your array.
Using an IComparable
Unity mono
using System.Collections.Generic;
public class RaycastResult: IComparable<RaycastResult> { public float distance; public Collider collider;
public RaycastResult(RaycastHit hit)
{
distance = hit.distance;
collider = hit.collider;
}
public int CompareTo(RaycastResult other)
{
return distance.CompareTo(other.distance);
}
}
//A sorted collection SortedSet<RaycastResult> raycastResults = new SortedSet<RaycastResult>();
void SortDistances() { raycastResults.Clear(); RaycastHit[] hits = Physics.RaycastAll(transform.position, transform.forward, 100.0);
foreach(RaycastHit hit in hits)
{
raycastResults.Add(new RaycastResult(hit));
}
//With an unsorted collection, call raycastResults.sort();
}
Unity js
import System;
class RaycastResult implements IComparable { var distance : float; var collider : Collider;
function RaycastResult(hit : RaycastHit)
{
distance = hit.distance;
collider = hit.collider;
}
function CompareTo(other : System.Object) : int
{
if (!(other instanceof RaycastResult)) return;
var raycastResultOther : RaycastResult = other;
return distance.CompareTo(raycastResultOther);
}
}
var raycastResults : Array = new Array();
function SortDistances() { raycastResults = new Array(); var hits : RaycastHit[] = Physics.RaycastAll(transform.position, transform.forward, 100.0);
for(var hit : RaycastHit in hits)
{
raycastResults.push(new RaycastResult(hit));
}
raycastResults.sort();
}
Using Comparer
Unity mono
public class RaycastComp : Comparer<RaycastHit> { public int Compare(RaycastHit x, RaycastHit y) { return x.distance.CompareTo(y.distance); } }
RaycastHit[] hits = Physics.RaycastAll(transform.position, transform.forward, 100.0); RaycastComp rc = new RaycastComp();
//...Somewhere else put Array.Sort(hits, rc);
Unity js (pretty much what Mike posted)
class RaycastComp extends IComparer { function Compare(x : System.Object, y : System.Object) : int { if ( !(x instanceof RaycastHit) || !(y instanceof RaycastHit)) return; var raycastHitX : RaycastHit = x; var raycastHitY : RaycastHit = x; return raycastHitX .distance.CompareTo(raycastHitY.distance); } }
var hits : RaycastHit[] = Physics.RaycastAll(transform.position, transform.forward, 100.0); var rc : RaycastComp = new RaycastComp();
//...Somewhere else put System.Array.Sort(hits, rc);
Using a comparison function
Unity mono
public int CompareHits(RaycastHit x, RaycastHit y) { return x.distance.CompareTo(y.distance); }
RaycastHit[] hits = Physics.RaycastAll(transform.position, transform.forward, 100.0);
//...Somewhere else put Array.Sort(hits, CompareHits);
Unity js
function CompareHits(var x : RaycastHit, var y : RaycastHit) : int { return x.distance.CompareTo(y.distance); }
var hits : RaycastHit[] = Physics.RaycastAll(transform.position, transform.forward, 100.0);
//...Somewhere else put hits.Sort(CompareHits);
Your answer
Follow this Question
Related Questions
Find gameObject with higher variable 1 Answer
Trying to sort an array. What's wrong here? 1 Answer
Dynamic Turn Order and Display Based On Initiative Value (Javascript)? 2 Answers
How can I order an array of RaycastHits in reverse order of distance? 1 Answer
Ordering an array of GO based on interfaced variables using linq. 1 Answer