I want to spawn some balls (with CircleCollider2d and static Rigidbody2D) with this code. I use a button to see if it works and when I use it everything is ok. But when I use a loop to create a bunch of balls in a single frame, they appear overlapping. I think it is because you have to wait for the physics to be updated, but I need to spawn all balls at the same time. Any ideas or solutions?
It is my first question and I do not speak English well, but I hope I have explained it well. Thanks a lot
public void CreatePointBall()
{
Vector2 pos;
float x, y;
int tries = 0;
do
{
tries++;
x = Random.Range(MIN_POS_X, MAX_POS_X);
y = Random.Range(MIN_POS_Y, MAX_POS_Y);
pos = new Vector2(x, y);
} while (Physics2D.OverlapCircle(pos, radius, LayerMask.GetMask("PointBall")) != null && tries < MAX_TRIES);
if(tries == MAX_TRIES) Debug.Log("MAX TRIES WITHOUT A CORRECT POS");
GameObject go = Instantiate(pointBallPrefab);
go.name = "PointBall";
go.transform.parent = transform;
go.transform.position = pos;
pointBallsList.Add(go);
}
>Solution :
-
You can try to use Physics.SyncTransforms. Or Physics.Simulate
Actually, it’s not a good practice to do this, it can hurt the performance a lot. -
If you not need to spawn spheres immediately, in a single frame, you can put your code into coroutine, and after spawning each ball, wait for physics update:
yield return new WaitForFixedUpdate(); -
If all of your spheres has a same scale, you can easily use a math instead of physics. For this, you need just to check the distance from current point to all other points.
It can be expensive, if you have a really large amount of points – so you can optimize it, keeping your points sorted – if your points array is sorted, you only need to compare 2 distances, next larger and previous smaller. But it can be tricky to implement.
Also, if you’ll compare many distances, do not use Vector2.magnitude – use Vector2.sqrMagnitude, it’s much faster.