Search Unity

Randomly generate objects inside of a box

Discussion in 'Scripting' started by jdepew, Jul 1, 2011.

  1. jdepew

    jdepew

    Joined:
    Jul 1, 2011
    Posts:
    1
    What is the best way to go about randomly spawning objects within the bounds of a box but only when the box is moving?

    I am either going to
    1: instantiate empty game objects inside of the box and then make them spawn rigidbody objects randomly from a group of models when they are hit with a collider.
    or
    2: simply randomly instantiate the models inside of the box and then "activate" them when they come into contact with the collider.

    hopefully that makes sense.

    I'm new to scripting and I realize this is a somewhat complicated task. I apologize if I am not communicating this well.
     
  2. BotMo

    BotMo

    Joined:
    Mar 2, 2011
    Posts:
    101
    it's not that complicated, it just seems that way until you get used to thinking like a computer. I'll give you some pseudo-code to help you out, but you'll have to look some things up on your own.

    **note: you'll have to sort out xyz/height, width, depth on your own. I always forget which is which.

    //set up some variables for your box.
    boxx= box position x
    boxy = box position y
    boxz = box position z
    boxw = width of box
    boxh = height of box
    boxd = depth of box

    //theres a randomize function in unity, you set a min and max value. you want it to be half of the dimensions of the box.
    //so for example, if your box is 8 wide you want to randomize between 4 and -4.
    randw = randomize(boxw/2,boxw/2*-1)
    randh = randomize(boxh/2,boxh/2*-1)
    randd = randomize(boxd/2,boxd/2*-1)

    //now see if your box is moving. do this by setting a variable when you tell the box to move and stop
    if(player is hitting a button or whatever){move the box; boxismoving = true;}
    if(player is not hitting the button to move the box){stop moving the box; boxismoving = false;}

    //now, if boxismoving is true, then spawn objects
    if(boxismoving == true)
    {
    coordinatex = boxx - randw;
    coordinatey = boxy - randh;
    coordinatez = boxz - randd;
    }
    //randomize a int to decide which object to spawn
    //in this example, i'll assume you have 10 possible objects to spawn.
    rand = randomize(1,10)
    if(rand == 1){instantiate model1 at (coordinatex,coordinatey,coordinatez)}
    if(rand == 2){instantiate model2 at (coordinatex,coordinatey,coordinatez)}
    if(rand == 3){instantiate model3 at (coordinatex,coordinatey,coordinatez)}
    }

    you'll probably need to set this up so that it doesn't do this every frame, so place the instantiate commands in some timer-like thing
    example:

    update()
    {
    timer++;
    if(timer==100){timer=0}

    if(timer=1){put your instantiate commands here}
    }

    so now it will instantiate and object every 100 frames.
     
  3. bigmisterb

    bigmisterb

    Joined:
    Nov 6, 2010
    Posts:
    4,221
    Not to undermine BotMo, but it is a bit simpler if you stick with the cube from Unity. In theory, the cube should be scaled to the size that you want, then every object that you want to instantiate could easily be spawned by using the localScale as a reference for the location, and TransformPoint to sequence it to the orientation of the cube.

    At first, I was thinking as BotMo, just use a bounds (yes, what he discribed was the long view of the bounds object) when I got to writing it out, it turned out to be far simpler.

    Code (csharp):
    1.  
    2. var spawnObject : Transform;
    3. var rateOfSpawn=0.5; //spawn every 0.5 seconds
    4. private var nextSpawn=0;
    5.  
    6. function Update()
    7. {
    8.     if(Time.time>nextSpawn){
    9.         nextSpawn=Time.time + rateOfSpawn;
    10.         var spawnBox=transform.localScale;
    11.         var position=Vector3(Random.value * spawnBox.x, Random.value * spawnBox.x, Random.value * spawnBox.x);
    12.         position=transform.TransformPoint(position-spawnBox/2);
    13.         var obj=Instantiate(spawnObject, postition, transform.rotation);
    14.     }
    15. }
    16.  
    In this case, we are instantiating every 0.5 seconds. where this is a bit more convenient than every 100th frame, which may be 1 second or 3 seconds depending on the frame rate.
     
    jonathan1440 likes this.
  4. JustinReinhart

    JustinReinhart

    Joined:
    Apr 3, 2012
    Posts:
    6
    Just giving back to the community. This is a C# script for spawning objects inside of a cube. It can be used as sort of a "spray paint" for prefabs. It does not address jdepew's inquiry for only spawning objects if a box is moving.

    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. /// <summary>
    5. /// Spawns a prefab randomly throughout the volume of a Unity transform. Attach to a Unity cube to visually scale or rotate. For best results disable collider and renderer.
    6. /// </summary>
    7. public class SpawningArea : MonoBehaviour {
    8.  
    9. public GameObject ObjectToSpawn;   
    10. public float RateOfSpawn = 1;
    11.    
    12. private float nextSpawn = 0;
    13.  
    14.     // Update is called once per frame
    15.     void Update () {           
    16.        
    17.         if(Time.time > nextSpawn)
    18.         {
    19.             nextSpawn = Time.time + RateOfSpawn;
    20.            
    21.             // Random position within this transform
    22.             Vector3 rndPosWithin;
    23.             rndPosWithin = new Vector3(Random.Range(-1f, 1f), Random.Range(-1f, 1f), Random.Range(-1f, 1f));
    24.             rndPosWithin = transform.TransformPoint(rndPosWithin * .5f);
    25.             Instantiate(ObjectToSpawn, rndPosWithin, transform.rotation);      
    26.         }
    27.     }
    28. }
    29.  
    $SpawningArea.png
     
    Last edited: Jun 4, 2013
  5. monotoan

    monotoan

    Joined:
    Feb 13, 2015
    Posts:
    11
    Another answer to core part of the question:

    Here's a quick function to get a random point inside a box using the same inputs that Unity uses to draw boxes (e.g. Gizmos.DrawWireCube)...

    Code (CSharp):
    1.     private static Vector3 RandomPointInBox(Vector3 center, Vector3 size) {
    2.  
    3.                 return center + new Vector3(
    4.                    (Random.value - 0.5f) * size.x,
    5.                    (Random.value - 0.5f) * size.y,
    6.                    (Random.value - 0.5f) * size.z
    7.                 );
    8.             }
     
  6. cravous

    cravous

    Joined:
    Mar 16, 2018
    Posts:
    1
    Hi, I know this is an old post but is there a way to make the cubes instantiate in a pattern or even on a grid maybe?
    To be exact I'm looking for a way to add a step to the Random.Range?
     
  7. MisterSkitz

    MisterSkitz

    Joined:
    Sep 2, 2015
    Posts:
    833
    Well, you could set up a series of these "Spawning Cubes" in areas with the pattern you'd like. You'd be able to adjust the localScale however you wish for each spawn cube. Otherwise, you could create a tag for each cube based upon the area it's located and have each one do as you wish.