- Home /
Having issues with Creating GameObject through the class
I've tried to create a class Enemy with function to spawn 1 cube with random position, color, scale, etc (it works I guess), but having issues to spawn bunch of them (through the loop. I've tried to use coroutine to create a cycle, but it doesn't work. How do I create a bunch of Enemies with their own unique parameters (unique color, pos, scale, etc...) ?
Enemy file:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Enemy : MonoBehaviour
{
public GameObject SpawnHost;
public GameObject EnemySample;
public int EnemySpeed = 1;
public float SpawnRadius = 4.5f;
int EnemyCounter = 0;
private readonly string[] enemyNames = { "Ranger", "Hunter", "Sniper", "Bulldog", "Alpha", "Rifleman" };
private string enemyName;
private Color enemyColor;
private Vector3 enemyScale;
private float x;
private float y;
void Awake()
{
enemyName = enemyNames[Random.Range(0, enemyNames.Length)];
enemyColor = Random.ColorHSV();
enemyScale = new Vector3(Random.value * 2 + 1, Random.value * 2 + 1, 1);
x = SpawnHost.transform.position.x + Random.Range(-SpawnRadius * 2.14f + enemyScale.x / 2, SpawnRadius * 2.14f - enemyScale.x / 2);
y = SpawnHost.transform.position.y + Random.Range(-SpawnRadius + enemyScale.y / 2, SpawnRadius - enemyScale.y / 2);
SpawnHost = this.gameObject;
}
public void SpawnEnemy()
{
GameObject LocalEnemy = Instantiate(EnemySample);
LocalEnemy.name = enemyName;
LocalEnemy.transform.position = new Vector3(x, y, 0);
LocalEnemy.GetComponent<SpriteRenderer>().color = enemyColor;
LocalEnemy.transform.localScale = enemyScale;
EnemyCounter++;
}
}
EnemySpawn file:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemySpawn : MonoBehaviour
{
private int EnemyCounter = 0;
public int SpawnCooldown = 5;
private IEnumerator EnemySpawnCycleCoroutine;
List<Enemy> Enemies;
IEnumerator EnemySpawnCycle()
{
while (true)
{
Enemies[EnemyCounter] = this.gameObject.GetComponent<Enemy>();
Enemies[EnemyCounter].SpawnEnemy();
EnemyCounter++;
yield return new WaitForSeconds(SpawnCooldown);
}
}
void Awake()
{
EnemySpawnCycleCoroutine = EnemySpawnCycle();
}
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
StartCoroutine(EnemySpawnCycleCoroutine);
}
}
}
Comment
Answer by rh_galaxy · Apr 30 at 11:09 AM
You are probably already creating many enemies, but they are all on the same place with the same scale and rotation.
Things you do in Awake() happens only once so you need to set the values before every time you Instantiate() an enemy. I think you should move everything in Enemy to EnemySpawn. Like this (untested):
public class EnemySpawn : MonoBehaviour
{
public GameObject EnemySample;
public float SpawnRadius = 4.5f;
private readonly string[] enemyNames =
{ "Ranger", "Hunter", "Sniper", "Bulldog", "Alpha", "Rifleman" };
public int SpawnCooldown = 5;
List<Enemy> Enemies = new List<Enemy>();
public Enemy SpawnEnemy()
{
//new values for this object creation
string enemyName = enemyNames[Random.Range(0, enemyNames.Length)];
Color enemyColor = Random.ColorHSV();
Vector3 enemyScale = new Vector3(Random.value * 2 + 1, Random.value * 2 + 1, 1);
float x = SpawnHost.transform.position.x + Random.Range(-SpawnRadius * 2.14f
+ enemyScale.x / 2, SpawnRadius * 2.14f - enemyScale.x / 2);
float y = SpawnHost.transform.position.y + Random.Range(-SpawnRadius
+ enemyScale.y / 2, SpawnRadius - enemyScale.y / 2);
//create object
GameObject LocalEnemy = Instantiate(EnemySample);
LocalEnemy.name = enemyName;
LocalEnemy.transform.position = new Vector3(x, y, 0);
LocalEnemy.GetComponent<SpriteRenderer>().color = enemyColor;
LocalEnemy.transform.localScale = enemyScale;
return LocalEnemy;
}
IEnumerator EnemySpawnCycle()
{
while (true)
{
Enemies.Add(SpawnEnemy());
yield return new WaitForSeconds(SpawnCooldown);
}
}
void Awake()
{
StartCoroutine(EnemySpawnCycle());
}
}