In this case the 4 walls and objects I spawn inside the 'wall area' are all cubes. This situation could change to where the walls will be spheres and the other objects can be cylinders or cubes (its not limited to cubes only).
What I'm trying to do is to spawn the objects in random positions but within the 'wall area'. The problem is when some cubes (objects) are spawning too close to the walls, part of the cubes will inside the area and some will be outside.
In the screenshot example on the right, a cube is going out of the wall area. In this case the walls area is sized according to the terrain (500x500) but it could be any size like 45x23 or 100x100.
In the script below I'm getting the 4 walls objects in array.
walls = GameObject.FindGameObjectsWithTag("Wall");
Now I wonder how can I use a ray cast to detect if each cube is spawning too close to one of the walls and if so then re-position the cube randomly, over and over again until it's inside the walls area. I'm not sure if using ray cast is the best way but that's what I had in mind.
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
public class SpawnObjects : MonoBehaviour
{
public int numberOfObjects;
public GameObject objectToPlace;
public Vector3 newObjectsSize;
public float spawnSpeed = 0.1f;
private int wallsLengthX;
private int wallsLengthZ;
private int wallsPosX;
private int wallsPosZ;
private int currentObjects;
private GameObject[] walls;
private List<GameObject> objects = new List<GameObject>();
private GameObject spawnedObjects;
void Start()
{
var wi = GetComponent<Walls>();
wallsLengthX = (int)wi.lengthX;
wallsLengthZ = (int)wi.lengthZ;
wallsPosX = (int)wi.wallsStartPosition.x;
wallsPosZ = (int)wi.wallsStartPosition.z;
walls = GameObject.FindGameObjectsWithTag("Wall");
spawnedObjects = GameObject.Find("Spawned Objects");
StartCoroutine(Spawn());
}
IEnumerator Spawn()
{
for (int i = 0; i < numberOfObjects; i++)
{
GameObject newObject = (GameObject)Instantiate(objectToPlace);
newObject.transform.localScale = GenerateRandomScale(newObject);
newObject.transform.localPosition = new Vector3(GenerateRandomPositions(newObject).x , GenerateRandomPositions(newObject).y + newObject.transform.localScale.y / 2.0f, GenerateRandomPositions(newObject).z);
newObject.name = "Spawned Object";
newObject.tag = "Spawned Object";
newObject.transform.parent = spawnedObjects.transform;
objects.Add(newObject);
yield return new WaitForSeconds(spawnSpeed);
currentObjects += 1;
}
var wp = GetComponent<WayPoints>();
wp.FindMyObjects();
}
private Vector3 GenerateRandomScale(GameObject newObject)
{
Vector3 newScale = new Vector3(UnityEngine.Random.Range(5, 100), UnityEngine.Random.Range(5, 100), UnityEngine.Random.Range(5, 10));
return newScale;
}
private Vector3 GenerateRandomPositions(GameObject newObject)
{
float paddingX = Mathf.Clamp(newObject.transform.localScale.x, 0, wallsLengthX) / 2f;
float paddingZ = Mathf.Clamp(newObject.transform.localScale.z, 0, wallsLengthZ) / 2f;
float originX = wallsPosX + paddingX - wallsLengthX / 2f;
float originZ = wallsPosZ + paddingZ - wallsLengthZ / 2f;
float posx = UnityEngine.Random.Range(originX, originX + wallsLengthX - paddingX);
float posz = UnityEngine.Random.Range(originZ, originZ + wallsLengthZ - paddingZ);
float posy = Terrain.activeTerrain.SampleHeight(new Vector3(posx, 0, posz));
return new Vector3(posx, posy, posz);
}
}