- Home /
Are there any ways to check collision?
I create an object and wanna check collision this new object with others. cause i don't want to place trees too close to each other. So there is a code from one script.
private IEnumerator GenerateTrees()
{
//yield return new WaitForSecondsRealtime(2f);
for (int i = 0; i < amountTrees; i++)
{
var border = sizeX - delta;
var pos = new Vector3(Random.Range(-border, border), 0, Random.Range(-border, border));
var tree = GenerateObject(treesPrefabs);
SetRandomPosition(tree, border);
yield return new WaitForEndOfFrame();
//yield return new WaitForSecondsRealtime(2f);
while (tree.GetComponent<CollisionDetector>().hasCollision)
{
print("while");
SetRandomPosition(tree, border);
yield return new WaitForEndOfFrame();
//yield return new WaitForSecondsRealtime(2f);
}
}
}
And there is from other which is attached for every prefab.
public class CollisionDetector : MonoBehaviour
{
public bool hasCollision;
private void OnTriggerEnter(Collider collision)
{
if (collision.gameObject.layer == 6)
{
hasCollision = true;
}
}
private void OnTriggerExit(Collider collision)
{
if (collision.gameObject.layer == 6)
{
hasCollision = false;
}
}
}
It seems that code in the second can't update in time. That's why the first script doesn't generate new position for tree. But when coroutine is done, i can see in inspector that hasCollision is true. Maybe there is a way to wait for end of the seconds cript update?
Answer by HammockHead21 · Sep 23, 2021 at 06:21 AM
Few ways/alternatives I can think of
Use PhysicsScene / PhysicsScene2D
Place trees at grid coordinates where the width/height of a cell are the minimum distance radius
void PlaceTrees(int maxCount, int maxIterations) { bool[,] used = new bool[width, height]; int count = 0; for (int i = 0; i < maxIterations && count < maxCount; ++i) { int x = RandomValue(); int y = RandomValue(); // place tree if (!used[x,y]) { used[x,y] = true; ++count; } } }
Bite the bullet and implement some collision checking yourself. If you aren't placing that many trees you could just nest two for loops
bool CanPlaceTree(Vector3 candidatePosition, List trees) { for (int i = 0; i < trees.Length; ++i) { Vector3 delta = candidatePosition - trees[i]; if (delta.sqrMag < minSqrDistance) { return false; } } return true; }
You could look up an implementation of a QuadTree to help
Answer by AlgoUnity · Sep 23, 2021 at 08:15 AM
You want to yield return WaitForFixedUpdate() to wait for the collision checking to happen. If your problem is that you don't want the tree to appear and then teleport once the collision checking happens, you could maybe just make it invisible by disabling the renderer by default and activate it when a valid position has been verified.
Your answer
Follow this Question
Related Questions
Detecting inside an area without a collider 1 Answer
[2D] Is it possible to un-ignore collisions between colliders? 1 Answer
Punching a crate 0 Answers
Detecting a collider in 3D space. 1 Answer
How to detect a collider in a particle? 4 Answers