I am trying to create a side scrolling game sort of like Gradius and I am spawning in enemies at random positions at the edge of the screen so it looks like they fly in. Right now I only have one enemy spawning in but I am copying the same enemy in with its prefab from the hierarchy and spawning it in with a gameController object and script. The problem I am having is when I shoot the enemies they seem to be inheriting the Scripts and properties of the GameObject prefab that was spawned just before causing the player to have to shoot the one in front or wait for it to be destroyed before attacking the enemies in the back. If the player shoots the ships in the back first, it causes the ship in the front to blow up, basically in order (also giving me a ‘Could not find GameObject’ error). I will supply code if needed, I am hoping it is a simple fix, I haven’t been able to find any solid solution online and I have been searching for days. I would greatly appreciate any help I can get.
I think you should use a level manager, that is to say an empty GO with a script that holds all the generic info about your level (number of enemies, rate of spawning etc).
The spawning of enemies would be managed by this script, and not within the enemy script.
This way I think each enemy would behave independently from the others.
Hope that helps.
The problem lies in your PlayerShot script where it acquires its target information.
In the shot’s Start() function, it finds an enemy using
GameObject enemyObject = GameObject.FindWithTag ("Enemy");
… and gets the enemy’s script using
Enemy = enemyObject.GetComponent<EnemyShip> ();
This results in a few specific problems:
• Your target is already acquired before your shot hits a target. This is when the wrong target takes damage
• The target is chosen (somewhat) arbitrarily. By simply looking for a GameObject with the right tag, you’re simply being given the first-found result.
• If the enemy is gone after a shot is fired, you will have a null reference for the Enemy variable.
Fortunately, the solution to this problem is very simple.
You don’t need to prepare your Shot's target when you first create it. With that in mind, you will likely have no need for your private EnemyShip Enemy;
variable.
Instead, you can get target information when the projectile hits something:
void OnTriggerEnter(Collider other)
{
if(other.CompareTag ("Enemy") )
{
EnemyShip enemy = other.GetComponent<EnemyShip>();
if(enemy != null)
{
enemy.EnemyTakeDamage(damageAmount);
}
}
else if(other.CompareTag("") || other.CompareTag(""))
{
// Currently unused
}
}