Hello guys, i want instatiate object random on screen but with order.

I’m genearting object random on X and Y axis but i need to make it with my object size. I mean object must be pass way everytime. I hope you will understand that sorry for my english.

Here is my code;

public Gameobject block1
    
 for (int i = 0; i < 30; i++)
     {
     Vector3 rndVector = new Vector3(Random.Range(-2.55f, 2.55f), Random.Range(-1.6f, 4.1f), 0);
     GameObject block = Instantiate(block1, rndVector, Quaternion.identity);
     float XYZ = Random.Range(0.27f,0.7f);
     block.transform.localScale = new Vector3(XYZ, XYZ, XYZ);
    }

In Game Looking Like This:

Ok I think I finally understood what this question is about. You just want to create 30 circular objects on the screen, randomly distributed, but without any overlap. It seems your [other question][1] was about the same issue but your approach was a bit strange. You probably should delete your other question as it’s far more confusing what the outcome should be, so it’s unlikely anybody will be able to answer it.

To distribute objects on the screen there are several approaches that would work. The most easiest way is to just put every object on its own vertical line and make sure that line is as far away from the previous line as the sum of the previous radius and your current radius. That way no matter where you place your object on that line it can never intersect with the previous one. However this will produce some constraints how the objects are distributed. With this approach it’s impossible to have two objects next to each other on about the same line, even though there’s enough space to put it there. So this approach will generally produce certain patterns and highly limit the amout of objects we can put on the screen since we essentially stack the objects on top of each other one-dimensionally.

Properly distribute objects randomly is a bit more tricky. In general you have to track / remember / save the position and dimension of all your previous created objects in order to check if there might be an overlap. There are several approaches to do this. I will quickly show some of them:

  • Just rely on Unity’s physics system and use colliders and OverlapSphere (when 2d physics is used OverlapCircle). Just pick a random point and radius and see if you get an overlap, if you do generate a new position / radius and try again.
  • Just store all your object data in a list so you can easily access the generated position and radius. Now when generating a new object you can manually iterate through the list and see if the new position / radius wouldl overlap with any of the existing ones. If not we can create an object there and add it to the list. There’s a [CodingTrain video about this approach][2]
  • The last approach uses a completely different approach. We just generate 30 random objects like you already did. But then we essentially run refinement steps over all objects. We essentially build a simple seperation logic. If we detect two object are overlapping we seperate them by moving them apart by half the overlap amount. This will ensure those two object do not overlap anymore. However by pushing them apart we might move one or both object over other objects or out of the viewing area. This doesn’t matter since we do this process several times until there’s no overlap anymore.

All these algorithms are not cheap from a performance point of view and all have the possibility of running forever. This happens when you just picked too many objects and you can not possibly fit that many circles into the screen area without overlap. So in all 3 approaches we have to ensure to stop at some point. Otherwise your application would just freeze and has to be force closed.

Physics based approach

So now tackle them one by one. For the first approach it’s important to remember that creating objects with a collider in a loop has the issue that those new objects are unknown to the physics system until the next physics step runs. Since everything happens inside a loop the physics system can not detect any of the objects we have already created. Though we can now use [Physics2D.SyncTransforms][3] / [Physics.SyncTransforms][4] after we created an object to ensure the physics system is up to date. To actually create the object we could use a nested loop or just a variable to track how many tries we had and how many objects we have created already. This can be done with a single for loop:

float minSpacing = 0f;
Physics2d.SyncTransforms();
for (int i=0,c=0; i < 1000 && c < 30; i++)
{
    Vector3 rndVector = new Vector3(Random.Range(-2.55f, 2.55f), Random.Range(-1.6f, 4.1f), 0);
    float radius = Random.Range(0.27f,0.7f);
    if (Physics2D.OverlapCircle(rndVector, radius + minSpacing) == null)
    {
        GameObject block = Instantiate(block1, rndVector, Quaternion.identity);
        block.transform.localScale = new Vector3(radius, radius, 1f);
        c++;
        Physics2d.SyncTransforms();
    }
}

So this loop will end when we either have created 30 objects, or when we run that loop 1000 times. So in case there is no room left to fit another circle in we just stop even though we did not create 30 objects. Note that “minSpacing” adds some extra amount to the radius to ensure two circles are not “touching” each other. Just increase this value if you want to have a minimum space between circles.

Even this approach uses Unity’s 2d physics system it’s probably one of the cheapest solutions because the physics system is highly optimised. However if performance is a concern, do a benchmark and test it.

Simple manual overlap test

Here we just create a List of custom objects which hold the information we need to define a circle object. At each step, like in the last approach, we generate a new position and radius and see if it overlaps with other circles and if it does, create a new one until we don’t have an overlap…

static float minSpacing = 0f;
public class Circle
{
    public Vector2 pos;
    public float radius;
    public bool Overlap(Circle aOther)
    {
        float rad = radius + aOther.radius + minSpacing;
        return (aOther.pos - pos).sqrMagnitude < rad*rad;
    }
}

List<Circle> circles = new List<Circle>();

void Start()
{
    for (int i=0,c=0; i < 1000 && c < 30; i++)
    {
        Vector3 rndVector = new Vector3(Random.Range(-2.55f, 2.55f), Random.Range(-1.6f, 4.1f), 0);
        float radius = Random.Range(0.27f,0.7f);
        var newCircle = new Circle{ pos = rndVector, radius = radius };
        
        bool validCircle = true;
        foreach(var c in circles)
        {
            if (c.Overlap(newCircle))
            {
                validCircle = false;
                break;
            }
        }
        
        if (validCircle)
        {
            GameObject block = Instantiate(block1, rndVector, Quaternion.identity);
            block.transform.localScale = new Vector3(radius, radius, 1f);
            circles.Add(newCircle);
            c++;
        }
    }
}

So this is the same approach as the first one but without any physics system involvement.

Refinement approach

In this case we create 30 random Circle objects right away. We run several refinement steps which wil gradually seperate the objects. Note that the end result will differ from the other two cases. In the first to approaches if we can’t fit enough circles into the area we simply give up adding more circles after some point. So we end up with less circles than we wanted. This approach will always create as many circles as we want. However if there are too many circles they might still overlap after we run out max refinement steps. There’s no nice way to solve this issue with this approach.

static float minSpacing = 0f;
public class Circle
{
    public Vector2 pos;
    public float radius;
    public bool Refine(Circle aOther)
    {
        float rad = radius + aOther.radius + minSpacing;
        var dir = aOther.pos - pos;
        float overlap = rad*rad - dir.sqrMagnitude;
        if ( overlap > 0 )
        {
            overlap = Mathf.Sqrt(overlap);
            dir = dir.normalized * overlap * 0.5f;
            pos -= dir;
            aOther.pos += dir;
        }
    }
}

List<Circle> circles = new List<Circle>();

void Start()
{
    for (int c = 0; c < 30; c++)
    {
        Vector3 rndVector = new Vector3(Random.Range(-2.55f, 2.55f), Random.Range(-1.6f, 4.1f), 0);
        float radius = Random.Range(0.27f,0.7f);
        var newCircle = new Circle{ pos = rndVector, radius = radius };
        circles.Add(newCircle);
    }
    for(int i = 0; i < 100; i++)
    {
        bool refined = false;
        for (int a = 0; a < circles.Count; a++)
        {
            for (int b = a; b < circles.Count; b++)
            {
                if(circles[a].Refine(circles**))**

refined = true;
}
}
if (!refined)
break;
// ensure points are not pushed outside our initial range
foreach(var c in circles)
{
c.pos.x = Mathf.Clamp(c.pos.x, -2.55f, 2.55f);
c.pos.y = Mathf.Clamp(c.pos.y, -1.6f, 4.1f);
}
}
foreach(var c in circles)
{
GameObject block = Instantiate(block1, c.pos, Quaternion.identity);
block.transform.localScale = new Vector3(c.radius, c.radius, 1f);
}
}
Note that all of this code is untested. I have just written it here from scratch. If you find any error, let me know in a comment.
[1]: https://answers.unity.com/questions/1697894/how-to-check-with-random-range-if-exits-float.html
[2]: 9.8: Random Circles with No Overlap - p5.js Tutorial - YouTube
[3]: Unity - Scripting API: Physics2D.SyncTransforms
[4]: Unity - Scripting API: Physics.SyncTransforms

Anyone can help on this please.
Nobody not know it?

You most call block.transform.localScale = new Vector3(XYZ, XYZ, XYZ); before Instantiate it
It must be that way:

 public Gameobject block1
     
  for (int i = 0; i < 30; i++)
      {
      Vector3 rndVector = new Vector3(Random.Range(-2.55f, 2.55f), Random.Range(-1.6f, 4.1f), 0);
      float XYZ = Random.Range(0.27f,0.7f);
      block.transform.localScale = new Vector3(XYZ, XYZ, XYZ);
      GameObject block = Instantiate(block1, rndVector, Quaternion.identity);
     }

Instantiate can be used to create new objects at runtime. Examples include objects used for projectiles, or particle systems for explosion effects. Instantiate can also clone script instances directly. Prepaidcardstatus