- Home /
Only one cloned enemy shoots
Currently I have 3 enemies spawning on the screen and I'm trying to get only my blue and red enemies to shoot and right now, the code works and finds a spawned enemy and allows only one to shoot. What I want is for all of my enemies that are present on the scene to shoot. I'll post my code so you can see what I'm doing. Note that it is WORKING, but it is not allowing all of my enemy clones to shoot. How can I fix this?
function shootLazer() {
Debug.Log("shootLazer Called");
shootTimer += Time.deltaTime;
if (shootTimer < shootCoolDown) {
return;
}
if(GameObject.Find("Enemy_Blue(Clone)")) {
Debug.Log("Blue Enemy Shooting");
shootCoolDown = 1.5;
shootTimer = 0; //Reset Timer
var blueClone : GameObject;
var blueProjectileOriginX = GameObject.Find("Enemy_Blue(Clone)").transform.position.x;
var blueProjectileOriginY = GameObject.Find("Enemy_Blue(Clone)").transform.position.y-1;
var blueProjectileOriginZ = GameObject.Find("Enemy_Blue(Clone)").transform.position.z;
blueClone = Instantiate(enemyProjectile, Vector3(blueProjectileOriginX, blueProjectileOriginY, blueProjectileOriginZ), transform.rotation);
blueClone.rigidbody.AddForce(blueClone.transform.up * -300);
Destroy(blueClone.gameObject, 2);
}
if(GameObject.Find("Enemy_Red(Clone)")) {
Debug.Log("Red Enemy Shooting");
shootCoolDown = 1.25;
shootTimer = 0; //Reset Timer
var redClone : GameObject;
var redProjectileOriginX = GameObject.Find("Enemy_Red(Clone)").transform.position.x;
var redProjectileOriginY = GameObject.Find("Enemy_Red(Clone)").transform.position.y-1;
var redProjectileOriginZ = GameObject.Find("Enemy_Red(Clone)").transform.position.z;
redClone = Instantiate(enemyProjectile, Vector3(redProjectileOriginX, redProjectileOriginY, redProjectileOriginZ), transform.rotation);
redClone.rigidbody.AddForce(redClone.transform.up * -300);
Destroy(redClone.gameObject, 2);
}
}
Answer by wildex999 · Mar 12, 2014 at 11:23 PM
Well, GameObject.Find only returns the first one it finds with the given name. To make them all fire you could tag Enemy_Red and Enemy_Blue in the editor, and then use GameObject.FindGameObjectsWithTag to get a list of all active GameObjects with the given tag, and then iterate that list.
Another way to do it could be to use a static list, and then on the Start() function of Enemy_Red and Enemy_Blue just Add them to this list. This seems a much easier method of doing it, and will probably be much less taxing on the engine.
In code of Enemy_Red:
public static List<Enemy_Red> redEnemies = new List<Enemy_Red>();
on Start():
Enemy_Red.redEnemies.Add(this);
And then in your shootLazer function:
foreach(Enemy_Red enemy in Enemy_Red.redEnemies)
{
//Fire code here
}
And then same for Blue.
The only thing with this is the fact that I have all of my enemies spawning and tied to one script. I'm spawning them all in one "Enemy_Controls.js" script so is there a way that when I'm spawning all of the enemies to store them all in a red enemy array and blue enemy array and then find each enemy from there?
Sure, just as easy. You just define two lists in your scripts:
var redEnemies = new Array();
var blueEnemies ...
And then when you spawn your red enemy:
var newEnemy = Instantiate(...);
redEnemies.Add(newEnemy);
And for looping through them:
for(var currentRedEnemy in redEnemies)
{
var redProjectileOriginX = currentRedEnemt.transform.position.x;
}
Please note that my javascript is a bit shaky, I usually code in C# so just look at this as an example =)
Ahhhhh! That works! Thank you so very much! Now all I need is to figure out how to stop the loop from breaking when I destroy one of the objects!
That is always an annoying problem. Best is to never remove from the list while iterating. One way to do this is to keep a list of items to remove, and remove them all AFTER you are done iterating.
var toRemoveRed = new Array();
for(var currentRedEnemy in redEnemies)
{
//This soldier must die
currentRedEnemy.dead = true; //In case you want to check later, not necessary
toRemoveRed.Add(currentRedEnemy);
}
///.. other code
//Clean up dead enemies after you are done with them for this step
for(var item in toRemoveRed)
{
redEnemies.splice(redEnemies.indexOf(item), 1);
}
This might not be the best way if you start destroying hundreds of objects per seconds, but for a start it should hold up rather well =) Again I'm not too good with Javascript, so you will need to tinker a bit with the code ;)
Do you think there's any way to avoid doing this or a different way because if I add the item to an array, how can I get it to disappear from the screen and then "destroy" the element? Should I just set the objects texture in the array to null?
Answer by RoboticSarcasm · Mar 13, 2014 at 12:29 PM
Besides the other way of doing it, you could have the position you are shooting from as a child of the object, and use FindChildren. I didn´t look into your code too deeply so maybe this is irrelevant, just saying this as i often use this technique.
EDIT: by this i mean having an empty child object you shoot from.
Your answer
Follow this Question
Related Questions
The problem of Enemy scale when he follow the player (script) . How to fix? 0 Answers
Detect collision and destroy one object 0 Answers
get enemy to chase and shoot at player wherever hes facing. 0 Answers
How do I make the enemy stop walking and shoot the player? 1 Answer
Clones of enemies will not shoot 0 Answers