I have having a problem with creating multiple enemies using prefabs, now creating one enemy I don’t really have a problem, but, creating multiple enemies with Unity is a process I don’t really understand and especially when it come to destroying enemies.
Mainly because I don’t now if the prefab I am working with should have code attached to it or not and it’s terribly confusing.
Anyway, this is what someone suggested to me:
Phase 1
use a simple/basic/plain sprite
a simple shape would do, maybe a circle, in one colour
spawn an alien
perhaps on a key press initially just so you can add some whilst play testing
limit the number that can be spawned
perhaps have this as a configurable variable
keep track of the number of spawn aliens
keep the game running as it did before with all of the above new stuff implemented
Phase 2
destroy an alien
again with a key press perhaps
update the number of spawned aliens
So, dealing with the creation of the enemies I came up with the following code in an EnemyController class
(EnemyController.cs), I did want to use a variable to control the amount, but, during testing to figure out what was going on I removed it.
sing UnityEngine;
using System.Collections;
public class EnemyController : MonoBehaviour {
// Use this for initialization
public static int numEnemies;
private LevelManager lm;
//access the prefab
public GameObject enemyPrefab;
private GameObject clone;
Vector3 randomPos;
void Start () {
print ("Enemy Controller: ");
numEnemies = 0;
print ("Number of Enemies:" + numEnemies);
randomPos.x = 8;
randomPos.y = 11;
randomPos.z = 0;
}
// Update is called once per frame
void Update () {
if (Input.GetKeyDown (KeyCode.UpArrow))
{
print ("Up Arrow pressed...");
setRandomValue ();
clone = (GameObject)Instantiate (enemyPrefab, randomPos, Quaternion.identity);
numEnemies++;
print ("Number of Enemies:" + numEnemies);
}
if (Input.GetKeyDown (KeyCode.DownArrow))
{
Destroy (clone);
numEnemies--;
print ("Number of Enemies:" + numEnemies);
}
}//end Update()
public void setRandomValue(){
randomPos.x = Random.Range (1f,15f);
}//end set
}//--> End Enemy controller
Using that code I am only able to destroy the last of the gameobjects,but, not all three (or more) as I would like to so I really am clueless at this point. And don’t know how to proceed!
The reason only the last one is being destroyed is because of the variable clone. That variable is holding the last enemy spawned because of how the script is written so it can only destroy the last one. What exactly do you want to happen? We need to know what you want to try to accomplish because as written, it’s behaving exactly like you programmed it.
When you press the down arrow:
I wasn’t very specific because I am not sure about what I should be asking! I was hoping that someone might be able to point me in a general direction, so, I don’t go off in some weird tangent that is not going to help me reach my goal and just confuses me more than I need to be. I was asking in the most basic matter I could with steps using MVP, minimum viable product.
So, being more specific I have made a somewhat clone of Arkanoid. The blocks break get destroyed, there are various levels of destruction to blocks, others unbreakable, there is a laser style “powerup”, moves on to other levels when the all the breakable blocks are destroyed, a win message is given when you beat the levels. All very simplistic.
Now in the original game - “enemies” are spawned either by time or by number of blocks destroyed I can’t tell. It’s starts of at one and then later there are a maximum of three (!?!), these enemies can be spawned any time after they are destroyed, hit by ball, laser, of bat/paddle/ship whatever you call it.
I initially though of using an array, but, to me that would run into problems with null objects because baddy[0] might be destroyed but with baddy[1] and baddy[2] still available, and every other conceivable variation, and if I’m cycling through all three to keep track of what’s available then I’m in trouble. Then there is another problem with movement - which is another can of worms moving towards the hero ship and with one enemy type in particular pathfinding. Then I thought perhaps the code should be on the prefab so once the enemy is spawned I wouldn’t have to worry about the array but how do I keep track of the amount of enemies - and then my “brain” falls over, because I’m in over my head.
Does that explanation give you a clue as what I’m after?
If you’re looking for some code I’ve seen multiple people point to this. Ive read through it and it’s functional and pretty easy to understand I believe. You should be able to work through it and modify it towards your needs. You’re going to want to change it up but I believe all the pieces are there for you to work on. http://wiki.unity3d.com/index.php?title=Enemy_Spawner
As for how to delete the objects. That link also hints how. No need for another manager to decide what enemy died. Let the enemy decide if it’s dead or not. You should make a script and attach it to the enemy. You will likely have a health system so in the ‘void Update()’ you will have something like 'if (hp <= 0) { Destroy(gameObject);} you then have to tell the spawner that the enemy died so it decreases it count and etc.
That should get you started. Play around with that and you should get somewhere hopefully if not. Post another comment here. For spawning enemies, you can also take a look at mostly any of the Unity tutorials in the Learn section. I believe most of them spawn enemies in a way and the player has to kill them somehow. Those will be a valuable resource.
Another alternative is to give the enemy prefab a script of its own that handles its own behavior. For instance, it would set/control its movement in start or update, and it would check for a collision in OnCollisionEnter2D. If it collided into an object that kills it (ball, laser, etc.) it destroys itself.
As for keeping track of your enemies, you can have a separate, unseen gameobject whose purpose is to handle creating the enemies, when certain conditions are met. In order to count the number of enemies currently in your scene, you could call GameObject.FindGameObjectsWithTag(“Enemy”), after setting your enemy prefab’s tag to “Enemy”. Keep in mind, however, that this function is (relatively) rather resource intensive, and shouldn’t be abused. If you can keep a local variable in your enemy manager and adjust it with the creation and death of each enemy (through calls in the enemy’s script), that would be better.
If you have implementation questions, the Unity Docs should have everything, and you can ask for follow up if you feel this helped.
Thankyou greatly to both of you for responding it really is “greatly” appreciated. I am starting to get a little better understanding of how to create enemies .