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.
Related
My game characters keep spawning at one position and they get squashed together i want them to spawn one after another from the door of the shop and after they recieve their product they leave from the door again This is a picture of how they look when they spawn since i'm putting them in a group spawn:
This is the script i'm using to spawn them:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CharacterSpawn : MonoBehaviour
{
[SerializeField]
private float spawnRadius = 7, time = 1.5f;
public GameObject[] enemies;
public Transform groupTransform;
void Start()
{
StartCoroutine(SpawnAnEnemy());
}
IEnumerator SpawnAnEnemy()
{
Vector2 spawnPos = GameObject.Find("Bengal").transform.position;
Instantiate(enemies[Random.Range(0, enemies.Length)], spawnPos, Quaternion.identity, groupTransform);
yield return new WaitForSeconds(time);
StartCoroutine(SpawnAnEnemy());
}
}
EDIT: They still spawn together even after trying the solution bellow check this picture:
I think you will need two scripts for this. One to handle selecting enemy to spawn and another to handle where to place the enemy.
This will pick a random enemy prefab:
public GameObject[] enemies; //Add to enemy prefabs
int spawnEnemy; //Random enemy index
void Start()
{
Pick();
}
void Pick()
{
spawnEnemy = Random.Range(0, enemies.Length);
GameObject Spawn = Instantiate(enemies[spawnEnemy], transform.position, Quaternion.identity);
This will place the enemy prefab in a random position. To avoid overlapping, a float "spaceBetweenEnemies" is introduced.
//Add to your enemy manager. Create an empty game object if you don't have one
//This will place the enemies in random position
public GameObject enemyDistribution;
GameObject spawn;
public int numberOfEnemiesToSpawn;
public float spaceBetweenEnemies = 2; //This is the space between enemies. To avoid overlapping
public float xPos = 5; //x axis
public float yPos = 5; //y axis
void Start()
{
for (int i = 0; i < numberOfEnemiesToSpawn; i++)
{
SpreadItem();
}
}
void SpreadItem()
{
Vector3 ranPos = new Vector3(Random.Range(-xPos, xPos) + spaceBetweenEnemies, Random.Range(-yPos, yPos) + spaceBetweenEnemies, 0f) + transform.position; //z axis is set to zero
spawn = Instantiate(enemyDistribution, ranPos, Quaternion.identity);
}
This may not prevent the enemies from spawning outside the screen parameters. I recommend writing a simple script to attract the enemies towards the centre of the screen of to the player. You can use an "OnTriggerEnter2d" method to check for collision between enemies and to move away from each other. There are good tutorials on "Flocking" on YouTube. You enemies will behave like swarms. This might come in handy for your game.
Hope this helps.
Add a float value called spaceBetweenObjects and add it to the spawnPos
//start with and small value and gradually increase or decrease it until you are happy with the result.
public float spaceBetweenObjects = 1;
Instantiate(enemies[Random.Range(0, enemies.Length)], spawnPos + spaceBetweenObjects, Quaternion.identity, groupTransform);
I am making a game in Unity2D i which you have to match the correct projectiles with the enemies but I can't randomly spawn them, it just spawns one... (btw this is my first game)
{
timeBTWSpawn = StartTimeBTWSpawn;
private void Update()
{
if(timeBTWSpawn <= 0 )
{
rand = Random.Range(0, enemies.Length);
Instantiate(enemies[0], SpawnPoint.transform.position, Quaternion.identity);```
timeBTWSpawn = StartTimeBTWSpawn;
}
else
{
timeBTWSpawn -= Time.deltaTime;
}
}
}
i expect 3 different enemies to be randomly spawned but it only spawns the first one in the array.
there is one minor mistake. You are not actually using "rand" variable inside the instantiate method. having 0 in the index will always spawn the first element inside enemies array.it should be like this:
Code:
Instantiate(enemies[rand], SpawnPoint.transform.position, Quaternion.identity);
this will fix :)
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.
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
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