Unity C# - Spawning GameObjects randomly around a point - c#

I am not sure how to approach this problem or whether there are any built in Unity functions that can help with this problem so any advice is appreciated.
Here is an image that'll help describe what I want to do:
I want to spawn Game Objects around a given point within the limits of a set radius. However their position in this radius should be randomly selected. This position should have the same Y axis as the origin point (which is on the ground). The next main problem is that each object should not clash and overlap another game object and should not enter their personal space (the orange circle).
My code so far isn't great:
public class Spawner : MonoBehaviour {
public int spawnRadius = 30; // not sure how large this is yet..
public int agentRadius = 5; // agent's personal space
public GameObject agent; // added in Unity GUI
Vector3 originPoint;
void CreateGroup() {
GameObject spawner = GetRandomSpawnPoint ();
originPoint = spawner.gameObject.transform.position;
for (int i = 0; i < groupSize; i++) {
CreateAgent ();
}
}
public void CreateAgent() {
float directionFacing = Random.Range (0f, 360f);
// need to pick a random position around originPoint but inside spawnRadius
// must not be too close to another agent inside spawnRadius
Instantiate (agent, originPoint, Quaternion.Euler (new Vector3 (0f, directionFacing, 0f)));
}
}
Thank you for any advice you can offer!

For personal space you can use colliders to avoid overlapping.
For spawning in circle you can use Random.insideUnitSphere. You can modify your method as,
public void CreateAgent() {
float directionFacing = Random.Range (0f, 360f);
// need to pick a random position around originPoint but inside spawnRadius
// must not be too close to another agent inside spawnRadius
Vector3 point = (Random.insideUnitSphere * spawnRadius) + originPoint;
Instantiate (agent, point, Quaternion.Euler (new Vector3 (0f, directionFacing, 0f)));
}
Hope this helps you.

For spawning the object within the circle, you could define the radius of your spawn circle and just add random numbers between -radius and radius to the position of the spawner like this:
float radius = 5f;
originPoint = spawner.gameObject.transform.position;
originPoint.x += Random.Range(-radius, radius);
originPoint.z += Random.Range(-radius, radius);
For detecting if the spawn point is to close to another game object, how about checking the distance between them like so:
if(Vector3.Distance(originPoint, otherGameObject.transform.position < personalSpaceRadius)
{
// pick new origin Point
}
I'm not that skilled in unity3d, so sry for maybe not the best answer^^
Also:
To check which gameobjects are in the spawn area in the first place, you could use the Physics.OverlapSphere Function defined here:
http://docs.unity3d.com/ScriptReference/Physics.OverlapSphere.html

Related

Moving Prefabs, Unity Spawner, Move Position

I have one problem. I want my prefabs to spawn every time my player picks them up. I did research on Google and YouTube and I tried to use the random function and instantiate. I don't know how to use them. I wrote this code I saw on YouTube and my prefab Sphere moves like 1cm to z position. I want to every time when I pick up object or my player go to spawn more of this on the z position. How do I do this?
My smaller script:
public GameObject Sphere;
public float zrange;
// Use this for initialization
void Start () {
RandomPosition();
}
void RandomPosition()
{
zrange = Random.Range(0f, 2f);
this.transform.position = new Vector3(0, 0, zrange);
}
You achieve that by not messing with the x and y values (your code sets them both to 0).
Vector3 p = transform.position;
p.z = zrange;
transform.position = p;
This assumes that your code to instantiate the object is already correctly placing the object. If not, more information is needed.

Get the center point between many GameObjects in Unity

I have created a game in which you can control X characters at the same time in the same form and they can die at any time. My problem is when I want the game camera to include all these gameobjects.
I thought that a good option is to calculate the central point between the gameobjects in the scene and make the camera follow that point at a certain distance.
I already have the camera code, but I still need to know how to get that central point or another way of doing it. In addition, the camera does not follow any of the axes (X, Y, Z) linearly, since it is placed in such a way that is the view is isometric (the game is in 3D).
As a last important fact, it is that all gameobjects that are running in the game (that are alive), are stored in a public static List <GameObject> to be able to access the components of these gameobjects at any time. Also, if a character (gameobject) dies or is born, the list is updated without problems.
I leave you a graphic example with three different cases, being the black points, the characters that are in the scene (gameobjects) and the red points, the central point (vector) that I would like to find.
Also, I leave the camera code so you can test if you have any solution:
public class Camera_Movement : MonoBehaviour {
Vector3 newPos;
public static List<GameObject> playersInGame = new List<GameObject>();
void Update() {
// Get Central Vector
// Replace playersInGame[0].transform.position with central vector
//newPos = Vector3.Lerp(gameObject.transform.position, "central vector", Time.deltaTime);
newPos = Vector3.Lerp(gameObject.transform.position, playersInGame[0].transform.position, Time.deltaTime);
gameObject.transform.position = new Vector3(newPos.x, newPos.y, newPos.z);
}
}
Thank you very much in advance!
You need to take the average x and and average y.
That would look like the following:
var totalX = 0f;
var totalY = 0f;
foreach(var player in playersInGame)
{
totalX += player.transform.position.x;
totalY += player.transform.position.y;
}
var centerX = totalX / playersInGame.Count;
var centerY = totalY / playersInGame.Count;
Let me know if this works for you (don't have access to Unity at the moment), but I put together an example here: https://dotnetfiddle.net/jGd99I
To have a solution that your camera can be best positioned to see all of your objects, then try this:
public Vector3 FindCenterOfTransforms(List<Transform> transforms)
{
var bound = new Bounds(transforms[0].position, Vector3.zero);
for(int i = 1; i < transforms.Count; i++)
{
bound.Encapsulate(transforms[i].position);
}
return bound.center;
}

Unity2D C# Randomly Spawn GameObject in an Area over another GameObject

I'm new to Unity2D (Unity 5.0.2f1) and have been searching for a solution which I'm sure is staring me in the face!
I have a game object (essentially a road) like below (DirtTrack1):
I have a spawner which spawns GameObjects (vehicles). I want to spawn those vehicles over this road.
I have tried the following code to do this, essentially trying to spawn the vehicle within the Y-axis area of the road by getting the bottom Y co-ordinate of the road and the top Y co-ordinate, so I get the min and max vertical positions of where I can place the vehicle:
void FixedUpdate() {
// Repeat spawning after the period spawn
// route has finished.
if (!_inSpawningIteration)
StartCoroutine (SpawnVehiclePeriodically());
}
IEnumerator SpawnVehiclePeriodically()
{
// First, get the height of the vehicle and road.
float vehicleHeightHalf = vehiclePreFab.GetComponent<SpriteRenderer>().bounds.size.y / 2f;
float roadHeightHalf = roadObject.GetComponent<SpriteRenderer>().bounds.size.y / 2f;
float roadTopY = roadObject.transform.position.y + roadHeightHalf;
float roadBottomY = roadObject.transform.position.y - roadHeightHalf;
// Next, ensure that maxY is within bounds of this farm vehicle.
roadMaxY = roadTopY - vehicleHeightHalf;
roadMinY = roadBottomY + vehicleHeightHalf;
// Set the position and spawn.
Vector3 newPosition = new Vector3 (Const_RoadItemsPositionX, randomY, 0f);
GameObject vehicle = (GameObject)GameObject.Instantiate (vehiclePreFab, newPosition, Quaternion.identity);
}
This does spawn randomly but most times it is always not within the road itself. It is either part on the road or at the outside edge of it.
I can't figure out what I'm doing wrong here but I'm sure it is something very simple!
Tick the kinematic check of your vehicle, physics may be moving it out of the road if you don't do that.
You are using localPosition. From documentation:
Position of the transform relative to the parent transform.
If the transform has no parent, it is the same as Transform.position.
Looking at your scene, your road has a parent object and the relative position you are getting might be messing up with the spawn position of cars.

Unity2D: troubles with spawning script

So basically I have a spawning script (2D game) that spawns in a enemy after spawn delay. I've also adding an array of enemy prefabs so that the SpawnerScript will spawn in a random enemy. However I'm having some problems with spawning in the prefabs in a random position within a transform (a.k.a: a 3D cube). You see My spawner isn't spawning in anything when I play the game, I made sure that I have included the size of how many enemies I want to spawn in. and made sure I have attach my prefabs. I also made sure that my unity project file hasn't got a bug. Maybe my code is wrong, i'm not sure.
My SpawnerScript:
public float RateOfSpawn = 1;
public float spawnTime = 2;
public GameObject[] enemy;
void Start(){
InvokeRepeating ("addEnemy", spawnTime, spawnTime);
}
void Spawn () {
// Random position within this transform- 3Dcube
var x1 = transform.position.x - GetComponent<Renderer> ().bounds.size.x / 2;
var x2 = transform.position.x + GetComponent<Renderer> ().bounds.size.x / 2;
var spawnPoint = new Vector2 (Random.Range (x1, x2), transform.position.y);
int enemyIndex = enemy.Length;
Instantiate (enemy[enemyIndex],spawnPoint,Quaternion.identity);
}
}
Thank you :)
You have to call the proper function to make it work.
void Start()
{
InvokeRepeating ("Spawn", spawnTime, spawnTime);
}
You have to call "Spawn" instead of "addEnemy".
Also change Instanatiate for proper instantiation.
Instantiate (enemy[Random.Range (0, enemyIndex)], spawnPoint, Quaternion.identity);
enemy[Random.Range (0, enemyIndex)] helps you choose random enemy from array of enemies' index 0 to enemyIndex-1.
The cause of exception is putting the length of array as index. Max Index limit is always length-1.

Unity3D: Spawn random objects one after another (2D)

I want to create a terrain made out of randomly generated objects. I have created couple of prefabs and made a script that has all 3 prefabs in an array, and spawns them randomly.
The problem that I have is that the objects (of different sizes) are being spawned in 1 unit distance, so basically over each other, instead of right after each other.
The second problem is that I am not sure how to limit the spawning to a decent number. I have created a script that destroys the objects once I pass them, but in the code, at the moment, they are spawning infinitely, too fast (I know the code isn't the nicest, I am still practicing).
I did look for possible solutions or similar problems, but haven't found anything that can help me.
Here is the code from my script:
using UnityEngine;
using System.Collections;
public class SpawnScript : MonoBehaviour {
public GameObject[] obj;
public Vector3 pos = new Vector3(-8,-4,0);
public float size = 1.0f;
private Vector3 dir = Vector3.right;
void Start () {
Spawn();
}
void Spawn() {
for (int i = 0; i<30; i++)
{
Instantiate (obj [Random.Range (0, obj.Length)], pos, Quaternion.identity);
pos += dir * size;
}
Invoke ("Spawn", 2);
}
}
I hope I can get any advises, references or help.
They are being spawned at 1 unit distance because you defined size as 1.0f. Take the real size of the object instead:
GameObject go = obj[Random.Range(0, obj.Length)];
Vector3 size = go.renderer.bounds.size;
pos += new Vector3(dir.x * size.x, dir.y * size.y, dir.z * size.z);
Instantiate(go, pos, Quaternion.identity);
See: Find Size of GameObject

Categories