Skip to content

Instantly share code, notes, and snippets.

@sinbad
Last active November 29, 2019 15:52
Show Gist options
  • Save sinbad/98fd062256b453b35cc390cf91537887 to your computer and use it in GitHub Desktop.
Save sinbad/98fd062256b453b35cc390cf91537887 to your computer and use it in GitHub Desktop.
Quick hack to use a single shared array for results from multiple Unity OverlapCollider calls
// I always use the Unity collider calls which place results in a single pre-allocated array to avoid allocations.
// However it's a bit annoying that you can't make a call like `collider2D.OverlapCollider` and tell it to start
// inserting results at a non-zero index in that results array, in order to collect multiple tests in a single
// result array.
// Yes, you can (and should) use CompoundCollider2D if this is a single object you're tracking, but if it's not and
// you just want combined results from different colliders it's a ball-ache to not be able to get all results in a
// single array easily.
// This little snippet shunts results of earlier OverlapCollider calls to the end of the array temporarily,
// then recombines them all at the end so the effect is the same as being able to use an offset in the call.
public int OverlapCollider(ContactFilter2D filter, Collider2D[] results) {
int totalCount = 0;
int stashed = 0;
for (int i = 0; i < colliders.Length && totalCount < results.Length; ++i) {
var coll = colliders[i];
int count = coll.OverlapCollider(filter, results);
if (count > 0 && colliders.Length > 1) {
// Unfortunately Unity doesn't allow an offset to OverlapCollider, so stash previous results
// at the end of the array until we're done
// truncate if need be, should never be exactly zero since outer loop would abort first
if (count + stashed > results.Length)
count -= results.Length - stashed;
if (i == colliders.Length - 1) {
// this was the last one, so recombine the stashed ones (ordering is changed compared to colliders but no biggie)
Array.Copy(results, results.Length - stashed, results, count, stashed);
// free refs at end too
Array.Clear(results, results.Length - stashed, stashed);
} else {
// Stash current results at the end
Array.Copy(results, 0, results, results.Length - stashed - count, count);
stashed += count;
}
}
totalCount += count;
}
return totalCount;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment