In this part of my Video Game Tutorial we completely finish Space Invaders! Well create the Alien AI, Think About when it Makes Sense to Ignore Collisions, Randomize AI Firing, Change Images, Hone AI Movement, Make Objects Appear, Randomize Actions, Animate Explosions, Utilize Sound Effects and use StartCoroutine, SpriteRenderer, Yield and more.
The Images & Sounds are here. All of the code used follows the video below.
If you like videos like this consider donating $1 on Patreon, or just turn off AdBlock. It helps a lot!
[googleplusone]
All the Code for this Course
Alien.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Alien : MonoBehaviour {
public float speed = 10;
public Rigidbody2D rigidBody;
// Starting sprite
public Sprite startingImage;
// Alternative image used for the Alien
public Sprite altImage;
// Used to change the Alien image
private SpriteRenderer spriteRenderer;
// Wait time before switching sprites
public float secBeforeSpriteChange = 0.5f;
// Reference to bullet GameObject
public GameObject alienBullet;
// Minimum time to wait before firing
public float minFireRateTime = 1.0f;
// Maximum time to wait before firing
public float maxFireRateTime = 3.0f;
// Base firing wait time
public float baseFireWaitTime = 3.0f;
// Exploded Ship Image
public Sprite explodedShipImage;
void Start(){
rigidBody = GetComponent<Rigidbody2D>();
// Set the starting direction and speed
rigidBody.velocity = new Vector2 (1, 0) * speed;
// Access the SpriteRenderer component
spriteRenderer = GetComponent<SpriteRenderer>();
// Call changeAlienSprite () to cycle the Alien sprites
StartCoroutine (changeAlienSprite ());
// Defines a random fire wait time for each Alien
baseFireWaitTime = baseFireWaitTime +
Random.Range (minFireRateTime, maxFireRateTime);
}
// Changes the direction for the Alien object
void Turn(int direction) {
Vector2 newVelocity = rigidBody.velocity;
newVelocity.x = speed * direction;
rigidBody.velocity = newVelocity;
}
// Moves the Alien vertically down
void MoveDown() {
Vector2 position = transform.position;
position.y -= 1;
transform.position = position;
}
// Switch direction on collision
void OnCollisionEnter2D(Collision2D col){
if (col.gameObject.name == "LeftWall")
{
Turn (1);
MoveDown ();
}
if (col.gameObject.name == "RightWall")
{
Turn (-1);
MoveDown ();
}
if (col.gameObject.tag == "Bullet")
{
SoundManager.Instance.PlayOneShot (SoundManager.Instance.alienDies);
Destroy (gameObject);
}
}
// Used to change the current sprite and play sounds
public IEnumerator changeAlienSprite(){
while (true) {
if (spriteRenderer.sprite == startingImage) {
spriteRenderer.sprite = altImage;
SoundManager.Instance.PlayOneShot (SoundManager.Instance.alienBuzz1);
} else {
spriteRenderer.sprite = startingImage;
SoundManager.Instance.PlayOneShot (SoundManager.Instance.alienBuzz2);
}
yield return new WaitForSeconds (secBeforeSpriteChange);
}
}
// Have Aliens fire bullets at random times
void FixedUpdate(){
if (Time.time > baseFireWaitTime) {
baseFireWaitTime = baseFireWaitTime +
Random.Range (minFireRateTime, maxFireRateTime);
Instantiate (alienBullet, transform.position, Quaternion.identity);
}
}
void OnTriggerEnter2D(Collider2D col)
{
if (col.gameObject.tag == "Player") {
// Play exploding ship sound
SoundManager.Instance.PlayOneShot (SoundManager.Instance.shipExplosion);
// Change to exploded ship image
col.GetComponent<SpriteRenderer> ().sprite = explodedShipImage;
// Destroy AlienBullet
Destroy (gameObject);
// Wait .5 seconds and then destroy Player
DestroyObject (col.gameObject, 0.5f);
}
}
}
AlienBullet.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class AlienBullet : MonoBehaviour {
private Rigidbody2D rigidBody;
public float speed = 30;
// Exploded Ship Image
public Sprite explodedShipImage;
// Use this for initialization
void Start () {
// Get reference to the ball Rigidbody
rigidBody = GetComponent<Rigidbody2D>();
// When the ball is created move it down
// at the desired speed
rigidBody.velocity = Vector2.down * speed;
}
// Called every time a ball collides with something
// the object it hit is passed as a parameter
void OnTriggerEnter2D(Collider2D col)
{
// If Bullet hits a wall destroy bullet
if (col.tag == "Wall") {
Destroy (gameObject);
}
// If Bullet hits Player destroy Alien and Bullet
if(col.gameObject.tag == "Player")
{
// Play exploding ship sound
SoundManager.Instance.PlayOneShot (SoundManager.Instance.shipExplosion);
// Change to exploded ship image
col.GetComponent<SpriteRenderer> ().sprite = explodedShipImage;
// Destroy AlienBullet
Destroy (gameObject);
// Wait .5 seconds and then destroy Player
DestroyObject(col.gameObject, 0.5f);
}
// If Alien Bullet hits Shield destroy both
if (col.tag == "Shield") {
Destroy (gameObject);
DestroyObject(col.gameObject);
}
}
// Called when the Game Object isn't visible
void OnBecameInvisible(){
Destroy (gameObject);
}
}
Bullet.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// Needed to manipulate the UI
using UnityEngine.UI;
public class Bullet : MonoBehaviour {
public float speed = 30;
private Rigidbody2D rigidBody;
// Exploded alien Image
public Sprite explodedAlienImage;
// Use this for initialization
void Start () {
// Get reference to the ball Rigidbody
rigidBody = GetComponent<Rigidbody2D>();
// When the ball is created move it up
// (0,1) at the desired speed
rigidBody.velocity = Vector2.up * speed;
}
// Called every time a ball collides with something
// the object it hit is passed as a parameter
void OnTriggerEnter2D(Collider2D col)
{
// If Bullet hits a wall destroy bullet
if (col.tag == "Wall") {
Destroy (gameObject);
}
// If Bullet hits Alien destroy Alien and Bullet
if(col.gameObject.tag == "Alien")
{
SoundManager.Instance.PlayOneShot (SoundManager.Instance.alienDies);
// Increase the Score Text component
increaseTextUIScore();
// Change to exploded alien image
// spriteRenderer.sprite = explodedAlienImage;
col.GetComponent<SpriteRenderer> ().sprite = explodedAlienImage;
Destroy (gameObject);
// Wait .5 seconds and then destroy Alien
DestroyObject(col.gameObject, 0.5f);
}
// If Alien Bullet hits Shield destroy both
if (col.tag == "Shield") {
Destroy (gameObject);
DestroyObject(col.gameObject);
}
}
// Called when the Game Object isn't visible
void OnBecameInvisible(){
Destroy (gameObject);
}
// Increases the score the the text UI name passed
void increaseTextUIScore(){
// Find the Score UI component
var textUIComp = GameObject.Find("Score").GetComponent<Text>();
// Get the string stored in it and convert to an int
int score = int.Parse(textUIComp.text);
// Increment the score
score += 10;
// Convert the score to a string and update the UI
textUIComp.text = score.ToString();
}
}
SoundManager.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SoundManager : MonoBehaviour {
// Holds the single instance of the SoundManager that
// you can access from any script
public static SoundManager Instance = null;
// All sound effects in the game
// All are public so you can set them in the Inspector
public AudioClip alienBuzz1;
public AudioClip alienBuzz2;
public AudioClip alienDies;
public AudioClip bulletFire;
public AudioClip shipExplosion;
// Refers to the audio source added to the SoundManager
// to play sound effects
private AudioSource soundEffectAudio;
// Use this for initialization
void Start() {
// This is a singleton that makes sure you only
// ever have one Sound Manager
// If there is any other Sound Manager created destroy it
if (Instance == null) {
Instance = this;
} else if (Instance != this) {
Destroy (gameObject);
}
AudioSource theSource = GetComponent<AudioSource> ();
soundEffectAudio = theSource;
}
// Other GameObjects can call this to play sounds
public void PlayOneShot(AudioClip clip) {
soundEffectAudio.PlayOneShot(clip);
}
}
SpaceShip.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SpaceShip : MonoBehaviour {
public float speed = 30;
// Holds a reference to Bullet objects
public GameObject theBullet;
void FixedUpdate(){
float horzMove = Input.GetAxisRaw ("Horizontal");
GetComponent<Rigidbody2D> ().velocity = new Vector2 (horzMove, 0) * speed;
}
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
// GetButtonDown will only fire once per click
// Jump is assigned to the Space Bar
if (Input.GetButtonDown ("Jump")) {
// Create a Bullet at transform.position which
// is the ships current location
// Quaternion.identity adds Bullet with no rotation
Instantiate (theBullet, transform.position, Quaternion.identity);
// Play bullet fire sound
SoundManager.Instance.PlayOneShot (SoundManager.Instance.bulletFire);
}
}
}