- Home /
best way to check if a Vector3 point is within any of multiple colliders
I've been building a system to lay out building prefabs across a grid at random. there's also trees laid out first, and some other items.
I've got a procedural river and along the river I have multiple box colliders to keep trees and buildings out of the river, as well as colliders in other areas to block spawning of items.
as I intentionally need to animate all the buildings appearing one by one, I am trying to build arrays of valid Vector3 locations from the start() method of my main GameObject, so that I have it all ready before the game starts
In order to make sure nothing overlaps, I only know of two ways to check if a Vector3 is within the bounds of a collider, bounds.contains or oncollisionenter/ontriggerenter
as there are multiple colliders , for efficiency, I'd prefer not to iterate through all colliders and use bounds.contains, but I need to make sure a point is not within any of the colliders.
if possible I'd like to combine all the colliders as one mesh collider but this seems difficult if not impossible, as well as potentially inefficient ?
so the next thing I thought of was to use triggers / isKinematic to check, but that will need to be done while the game is running and physics is in play , so I assume that's not possible in start() ?
so I need some advice , maybe I need to better understand update() ? is there any way to defer some work untili the first few update() runs ?
any help is very much appreciated!
Answer by pojomcbooty · May 18, 2018 at 11:34 PM
I was looking at this all wrong. I was thinking about start() method like it was awake(), just because some of my code worked one way when attached to an object, and differently in start(). Convinced now it was just bad code.
Anyway, in the end I created a temporary cuboid at the Vector3, and used Physics.OverlapBox (yes even from start method) and it works well. two things to note would be:
exact location of the fake cuboid is very important
layermasking or tag checking is important (ignore terrains etc)
size of the overlapbox is very important , I used the colliders ".extents"
public static bool SpawnLocationValid(Vector3 potentialLocation){
GameObject tempObj = new GameObject("temporary cube with collider (SpawnLocationValid)"); tempObj.transform.position = potentialLocation + Vector3.up * 1.0f; var bCol = tempObj.AddComponent<BoxCollider>(); bCol.isTrigger = true; var rb = tempObj.AddComponent<Rigidbody>(); rb.isKinematic = true; rb.useGravity = false; Collider[] colls = Physics.OverlapBox(potentialLocation, bCol.extents); foreach (Collider c in colls){ if (c.CompareTag("NoSpawnAnything")){ GameObject.Destroy(tempObj); return false; }else{ Debug.Log("tag = " + c.tag + ", object = " + c.name); GameObject.Destroy(tempObj); } } GameObject.Destroy(tempObj); return true; }
oh for #3 , the colliders extents in this case were a cube of size (1,1,1) but you would probably need larger cubes to check the size of a house, a tree, etc.