- Home /
Prevent Overlap with Prefabs Instantiating themselves
I am working on a script that starts with one object (say, a cube), that has a script on it that spawns a prefab (which is the object itself) on one of the immediate sides of the object in the four cardinal directions. So basically, the cube is supposed to spawn 1-4 adjacent cubes, which in turn spawn 1-4 adjacent cubes, and so on until a limit of the instantiating objects that I determine beforehand is hit. However, I am trying to make them not spawn where other cubes have already been spawned, and my results are either: A) They only spawn once from the initial cube then do not branch out because they believe there are other cubes in the adjacent positions. B) They spawn until the limit and stack on each other regardless of any collision detection.
here is the complete code for the spawning of the adjacent cubes(check collisions is commented out because it was doing nothing to change the situation. to see one or the other of my results, just remove the "north occupied = false, east occupied = false, etc" in the first script to get result A, and leave it in for result B):
static var room_limit : int = 10;
static var room_total : int = 0;
var north_occupied : boolean;
var north_position : GameObject;
var east_occupied : boolean;
var east_position : GameObject;
var south_occupied : boolean;
var south_position : GameObject;
var west_occupied : boolean;
var west_position : GameObject;
var room_prefab : GameObject;
var number_of_adjacents : int;
var selected_adjacent : int;
function Start () {
north_occupied = false;
east_occupied = false;
south_occupied = false;
west_occupied = false;
//CheckCollisions();
number_of_adjacents = Random.Range(1,5);
if(room_total < room_limit)
{
for(var rooms : int = 0; rooms < number_of_adjacents; rooms++)
{
if(room_total >= room_limit)
{
rooms = number_of_adjacents;
Debug.Log("Hit Room Limit");
}
selected_adjacent = Random.Range(1,5);
if(selected_adjacent == 1 && north_occupied != true && room_total < room_limit)
{
var new_room_north : GameObject = Instantiate(room_prefab,north_position.transform.position,Quaternion.identity);
room_total++;
north_occupied = true;
}
else if(selected_adjacent == 1 && north_occupied == true)
{
rooms++;
}
if(selected_adjacent == 2 && east_occupied != true && room_total < room_limit)
{
var new_room_east : GameObject = Instantiate(room_prefab,east_position.transform.position,Quaternion.identity);
room_total++;
east_occupied = true;
}
else if(selected_adjacent == 2 && east_occupied == true)
{
rooms++;
}
if(selected_adjacent == 3 && south_occupied != true && room_total < room_limit)
{
var new_room_south : GameObject = Instantiate(room_prefab,south_position.transform.position,Quaternion.identity);
room_total++;
south_occupied = true;
}
else if(selected_adjacent == 3 && south_occupied == true)
{
rooms++;
}
if(selected_adjacent == 4 && west_occupied != true && room_total < room_limit)
{
var new_room_west : GameObject = Instantiate(room_prefab,west_position.transform.position,Quaternion.identity);
room_total++;
west_occupied = true;
}
else if(selected_adjacent == 4 && west_occupied == true)
{
rooms++;
}
}
}
}
function Update () {
}
function OnTriggerEnter(collision : Collider){
if(collision.tag == "room")
{
Destroy(gameObject);
Debug.Log("Collision Fixed");
}
}
function CheckCollisions(){
Debug.Log("Checking");
if(north_position.GetComponent(PreventOverlap).collision_detected == true)
{
north_occupied = true;
Debug.Log("North Found Collision");
}
else
{
north_occupied = false;
}
if(east_position.GetComponent(PreventOverlap).collision_detected == true)
{
east_occupied = true;
Debug.Log("East Found Collision");
}
else
{
east_occupied = false;
}
if(west_position.GetComponent(PreventOverlap).collision_detected == true)
{
west_occupied = true;
Debug.Log("West Found Collision");
}
else
{
west_occupied = false;
}
if(south_position.GetComponent(PreventOverlap).collision_detected == true)
{
south_occupied = true;
Debug.Log("South Found Collision");
}
else
{
south_occupied = false;
}
}
and here is the code for the box colliders (which have kinematic rigidbodies and are set to "is trigger") to detect if there is an object there beforehand.
var central_room : GameObject;
var horizontal_hallway : GameObject;
var vertical_hallway : GameObject;
var collision_detected : boolean;
function Start () {
collision_detected = false;
}
function OnTriggerEnter(collision : Collider){
if(collision.tag == "room")
{
collision_detected = true;
}
}
Answer by RPGstandard · Jul 31, 2013 at 11:26 AM
Try this approach
Spawn the first object, randomly choose a cardinal direction to spawn the next object, check to see if there is already an object there using coordinate system rather than the true/false you have now, if there is no object there it then places the new object in that spot and continues. If there was a object there have it randomly choose another direction to spawn the next object in but reducing the possible directions for each failed attempt.
Hope this makes sense
How do you use the coordinate system to detect if an object if there first? I've never used it before.
Is this for a 2d game or a 3d game? Do you have a screenshot so I can get a better idea on how you should implement the coordinate system using Vector2 or Vector3 .
Well the objects are spawned on a 2D plane, but the game is fully 3D. I'm not at my desktop right now so I can't provide screenshots. The four cardinal directions are on the X and Z axis
okay, easy enough. you want to get the X and Z coordinate and the scale of both for the original object.
Randomly generate a X or Z coordinate based on the current game objects coordinates plus or $$anonymous$$us their scale.
take these figures and build a function that spawns the next object at a X or Z coordinate when X or Y is equal to X coordinate + X scale if moving in a positive direction, (same for Z), and X coordinate - x scale if moving in a negative direction.
Check the X and Z coordinate of each game object that is currently being rendered. If the X or Z coordinate of the space you want to render your next game object in is not occupied, allow it to render there, however if it is occupied, then run another instance of the coordinate generator but with the occupied coordinate excluded from the possibilities.
Lots of info on Vector3s in the docs here http://docs.unity3d.com/Documentation/ScriptReference/30_search.html?q=vector3
So like this? var number_of_adjacents : int; var adjacent_prefab : GameObject; var random_axis : int; var random_direction : int;
function Start() {
number_of_adjacents = Random.Range(1,5);
for(var i : int = 0; i < number_of_adjacents; i++)
{
var new_adjacent : GameObject = Instantiate(adjacent_prefab, transform.position,Quaternion.identity);
random_axis = Random.Range(0,2);
if(random_axis == 0)
{
random_direction = Random.Range(0,2);
if(random_direction == 0)
{
new_adjacent.position.x += transform.scale.x;
}
else
{
new_adjacent.position.x -= transform.scale.x;
}
}
else if(random_axis == 1)
{
random_direction = Random.Range(0,2);
if(random_direction == 0)
{
new_adjacent.position.z += transform.scale.z;
}
else
{
new_adjacent.position.z -= transform.scale.z;
}
}
total_rooms++;
}
}
for spawning the objects? I'm still lost on how to check if an object is already there to prevent the objects from moving on top of each other. $$anonymous$$aybe I could add all the spawned objects to an array or vector then use a for loop after all are spawned to check every individual object to see if it is on top of another object then delete the stacked object? I have no idea, I really wish I was at my desktop right now so I could think...
Your answer
Follow this Question
Related Questions
instantiate prefabs/gameObjects 1 Answer
OnCollisionEnter doesn't work if enemies and allies have rigidbody ? 1 Answer
Instantiating Prefabs into an Array with Indexing 1 Answer
Network.Destroy and collision; destroying correct object. 1 Answer
How can you make a Instanciate prefab follow a scene object? 1 Answer