So I’ve been trying to recreate the classic space invaders as a way to practice game development but now I have run up against a problem that I do not fully understand why it is happening and would very much appreciate if some one could take a look at this.
My main problem resides in my EnemyMovement Script. In this script, I control in which direction the invaders move and at what rate.
using UnityEngine;
public class EnemyMovement : MonoBehaviour
{
private Animator invaderAnimator;
private static Vector3 invaderHorizontalVelocity = new Vector3(0.1f, 0, 0); // needs to be static so that every invader X position gets updated accordingly.
private readonly Vector3 INVADER_VERTICAL_SPEED = new Vector3(0, -0.1f, 0);
public readonly string[] INVADER_TRIGGERS = {"GoToMovement2", "GoToMovement1"};
private float timePassed = 0.0f;
private float movementDelay = 1.0f;
private int animationIndex;
private static bool collidedWithWall = false; // needs to be static so that every invader is aware that we have hit a wall.
void Start()
{
invaderAnimator = GetComponent<Animator>();
animationIndex = 0;
}
void Update()
{
timePassed += Time.deltaTime;
if (canMove() && !isDead())
{
setAnimationTrigger();
if (!collidedWithWall)
transform.position += invaderHorizontalVelocity;
else
{
transform.position += INVADER_VERTICAL_SPEED;
invaderHorizontalVelocity.x = -invaderHorizontalVelocity.x;
collidedWithWall = false;
}
timePassed = 0.0f;
}
}
private bool canMove()
{
return timePassed > movementDelay;
}
private bool isDead()
{
return invaderAnimator.GetBool("InvaderDies");
}
private void setAnimationTrigger()
{
invaderAnimator.SetTrigger(INVADER_TRIGGERS[animationIndex]);
animationIndex++;
animationIndex %= INVADER_TRIGGERS.Length;
}
void OnTriggerEnter2D(Collider2D collision)
{
if (collision.gameObject.tag == "WestWall" || collision.gameObject.tag == "EastWall")
{
collidedWithWall = true;
}
}
}
In the main game scene, I have two colliders with the tag East and West Walls that are used to detected if one of my invaders have hit a wall. This also means that each invader has its own rigidbody2D and box2D collider with kinematic mode and isTrigger mode enabled.
Now, everything works great up until the point where either the right most or left most invaders collide with the wall. What happens in my game scene is this line code
transform.position += INVADER_VERTICAL_SPEED;
only updates one of my invaders(This is out of the 55 invaders that I have active); particularly, the top left most invader. Why only one of them? I do not know why exactly. What I do know is that once I added this few lines of code, then all the invaders Y position got updated.
if (!collidedWithWall)
transform.position += invaderHorizontalVelocity;
else
{
moveDown()
invaderHorizontalVelocity.x = -invaderHorizontalVelocity.x;
collidedWithWall = false;
}
......
private void moveDown()
{
GameObject[] invaderArmy = GameObject.FindGameObjectsWithTag("Invader");
foreach (GameObject invader in invaderArmy)
{
if(invader.activeInHierarchy)
invader.transform.position += INVADER_VERTICAL_SPEED
}
}
Which I dont want to do because I going to be constantly doing a find each time one of the invaders collide with a wall and that is unnecessary.
The unity version that I’m running is 5.5.2f1. Just in case you were wondering.
So if you know why it is only updating one of my invaders in the Y position when one of the invaders collide with the wall, please post your answer because I’ve tried everything I could think of.