Select Page
Game Design
Class 06: Audio and Effects

Topics

  • Particles
  • Audio
  • Platformer (effects and audio) Lab Demonstration
  • Asset Collection Assignment

Class 07…007

Particles

There are a lot of options and settings when it comes to the Unity particle system. This video has great quick explanations of the various properties.

Audio

Audio:

Sound may be attached to any Unity game object. It can be set to play play once, indefinitely, or not at all. Typically you will want to have the different audio clips to be attached to a single object and ordered when to play via code.

 

Platformer (refined mechanics) Lab Demonstration

This is what we are making today

You may download the Unity project here.

Assets

Environment
Foreground
The imagery that is in front of the player
Midground
The imagery that the player character can actually contact, ground, platforms, walls, etc.
Background
The imagery behind the player
Characters
Player
The protagonist controlled by the player
Enemies
The antagonist that kills the player
Other(pickups, UI, etc.)
Lives
Adds life to the players total lives
Points
Adds to the player’s total score

We now have our graphics complete. You can create more as you go.

Scripts

New Scripts
None
No new scripts this week
Updated Scripts
PlayerControllerScript
Add audio and effects
Old Scripts
PlayerPickupScript
Detects pickups such as lives or score
DeathboxScript
Runs the death function when player enters
VictoryboxScript
Loads next level when player enters
PlayerStatsScript
Keeps track of the player stats such as lives and score
EnemyControllerScript
Moves the enemy sprite and kills the player
GroundCheckScript
Checks that the player character is on the ground
PlayerController.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerController : MonoBehaviour
{
    public float movSpd = 2.5f;
    public float jmpStr = 50f;
    public float jmpBst = 1f;

    public bool ground = false;
    public bool doubleJump = false;

    private Rigidbody2D pRB2D;
    private Animator pAnim;
    private SpriteRenderer pSprite;
    private AudioSource pAudio;
    private GameObject pJumpParticle;

    public AudioClip enemyDeath;
    public AudioClip playerJump;

    private PlayerStats pStats;

    void Awake()
    {
        pRB2D = GetComponent<Rigidbody2D>();
        pAnim = GetComponent<Animator>();
        pSprite = GetComponent<SpriteRenderer>();
        pAudio = GetComponent<AudioSource>();
        pStats = GetComponent<PlayerStats>();
        pJumpParticle = transform.GetChild(0).gameObject;
    }

    void Start()
    {
        pJumpParticle.transform.SetParent(null);
    }

    // Update is called once per frame
    void Update()
    {
        pRB2D.velocity = new Vector2(Input.GetAxis("Horizontal") * movSpd, pRB2D.velocity.y);

        if(pRB2D.velocity.x > 0.1f) pSprite.flipX = false; 
        if(pRB2D.velocity.x < -0.1f) pSprite.flipX = true; 


        if(Input.GetButtonDown("Jump"))
        {
            if(ground)
            {
                pAudio.clip = playerJump;
                pAudio.Play();
                pJumpParticle.transform.position = transform.position;
                pJumpParticle.GetComponent<ParticleSystem>().Play();
                pRB2D.AddForce(Vector2.up * (jmpStr * jmpBst));
                ground = false;
                doubleJump = true;
            }
            else 
            {
                if(doubleJump)
                {       
                    pAudio.clip = playerJump;  
                    pAudio.Play();           
                    pRB2D.AddForce(Vector2.up * (jmpStr * jmpBst));
                    doubleJump = false;
                }
            }
        }  

        pAnim.SetBool("Ground", ground);
        pAnim.SetFloat("Speed", Mathf.Abs(Input.GetAxis("Horizontal")));  

        if(transform.position.y <= -10)
        {
            //transform.position = startPos;
            pStats.UpdateLives(-1);
        }        
    }

    void OnCollisionEnter2D(Collision2D col)
    {
        if(col.gameObject.CompareTag("Ground"))
            ground = true;
    }

    void OnCollisionExit2D(Collision2D col)
    {
        if(col.gameObject.CompareTag("Ground"))
            ground = false;
    }

    public void PowerUp(string type)
    {
        switch(type)
        {
            case "Jump Boost":
                StartCoroutine(JumpBoost());
                break;                
        }
    }

    IEnumerator JumpBoost()
    {
        jmpBst = 2;
        yield return new WaitForSeconds(10);
        jmpBst = 1;
    }

    void FixedUpdate()
    {
        CheckEnemyBelow();
    }

    void CheckEnemyBelow()
    {
        RaycastHit2D hit = Physics2D.Raycast(new Vector2(transform.position.x, transform.position.y - .5f), -Vector2.up, .5f);
        Debug.DrawRay(new Vector2(transform.position.x, transform.position.y - .5f), -Vector2.up * 0.5f, Color.blue, 2, false);

        if(hit.collider != null)
        {
            if(hit.collider.CompareTag("Enemy"))
            {
                pAudio.clip = enemyDeath;
                pAudio.Play();
                Destroy(hit.collider.gameObject);
            }                
        }
    }
}
EnemyController.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class EnemyController : MonoBehaviour
{
    public float enemySpeed = 2;

    private int enemyDirection = 1;

    private Rigidbody2D eRB2D;
    private SpriteRenderer eGraphic;

    void Awake()
    {
        eRB2D = GetComponent<Rigidbody2D>();
        eGraphic = GetComponentInChildren<SpriteRenderer>();
    }

    void Update()
    {
        Move();
    }

    void Move()
    {
        eRB2D.velocity = new Vector2 ((enemySpeed * enemyDirection), transform.position.y);
    }

    void OnTriggerExit2D(Collider2D col)
    {
        enemyDirection *= -1;
        if(eGraphic.flipX) eGraphic.flipX = false; 
        else eGraphic.flipX = true;

        if(eGraphic.flipY) eGraphic.flipY = false; 
        else eGraphic.flipY = true;
    }

    void OnTriggerEnter2D(Collider2D col)
    {
        if(col.gameObject.CompareTag("Player"))
        {
            col.gameObject.GetComponent<PlayerStats>().UpdateLives(-1);
        }
    }
}
CameraController.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CameraController : MonoBehaviour
{
    public Transform pTransform;
    public Vector3 offset;

    void Update()
    {
        transform.position = pTransform.position + offset;
    }
}
Pickup.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Pickup : MonoBehaviour
{
    private Animator pickupAnim;

    public string pickup = "life";

    void Awake()
    {
        pickupAnim = GetComponentInChildren<Animator>();
    }

    void OnTriggerEnter2D(Collider2D col)
    {
        if(col.gameObject.CompareTag("Player"))
        {
            switch(pickup)
            {
                case "Life":
                    col.gameObject.GetComponent<PlayerStats>().UpdateLives(1);
                    Destroy(gameObject);
                    break;
                case "Point":
                    col.gameObject.GetComponent<PlayerStats>().UpdateScore(1);
                    if(pickupAnim)
                        pickupAnim.SetTrigger("Score");
                    StartCoroutine(WaitToKill(0.25f));
                    break;
                case "Jump Boost":
                    col.gameObject.GetComponent<PlayerController>().PowerUp("Jump Boost");
                    Destroy(gameObject);
                    break;
            }
        }
    }

    IEnumerator WaitToKill(float timeToKill)
    {
        yield return new WaitForSeconds(timeToKill);
        Destroy(gameObject);
    }
}
PlayerStats.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;

public class PlayerStats : MonoBehaviour
{
    public int playerLives = 3;
    public int playerScore = 0;

    private Vector2 startPos;

    public TextMeshProUGUI livesText;
    public TextMeshProUGUI scoreText;

    void Start()
    {
        UpdateLives(0);
        UpdateScore(0);
        startPos = transform.position;
    }

    public void UpdateLives(int lives)
    {
        playerLives += lives;
        livesText.text = "Lives: " + playerLives;

        if(lives < 0)
            transform.position = startPos;
    }

    public void UpdateScore(int points)
    {
        playerScore += points;
        scoreText.text = "Score: " + playerScore;
    }

}
StartMenu.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class EnemyControllerScript : MonoBehaviour
{

    public float enemySpeed; 
    private int enemeyDirection = 1;

    private Vector2 enemyScale;
    private Rigidbody2D enemyRB2D;

    void Start()
    {
        enemyScale = transform.localScale;
        enemyRB2D = GetComponent<Rigidbody2D>();
    }

    void Update()
    {
        Move();
    }

    void Move()
    {
        enemyRB2D.velocity = new Vector2 ((enemySpeed * enemeyDirection), transform.position.y);
    }

    void OnTriggerEnter2D(Collider2D col)
    {
        if(col.tag == "EnemyBlock")
        {
            enemeyDirection *= -1;
            transform.localScale = new Vector2 ((enemyScale.x * enemeyDirection), enemyScale.y);
        }
        else if(col.tag == "Player")
        {
            col.gameObject.GetComponent<PlayerStatsScript>().PlayerLifeDeath(-1);
        }
    }
}
Victory.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Victory : MonoBehaviour
{

    void OnTriggerEnter2D(Collider2D col)
    {
        if(col.gameObject.CompareTag("Player"))
        {
            Debug.Log("you won!");
        }
    }
}

Asset Collection Assignment

Asset Collection Assignment:

It is nearly impossible to make all the assets for your game by yourself. In this assignment you will gather any additional resources you need for your game. That includes audio, artwork, scripts, and other assets. Once you have gathered all of the extra assets you need for your game you will screenshot the folder with all of the elements and submit a jpeg.

You will be graded on the following:
  • Lab Requirements
    • Techniques and processes covered in the instructional material is followed and implemented.
  • Creativity & Craftsmanship
    • Excellent design choices, novel & appealing, and solid clean caliber work.
Resources:
Assignment Video Tutorials
You may watch the tutorial videos below to help you complete your assignment.

Assignment Video Tutorials

You may download the sprite and audio used in the lab here.

Wait! Before you go!

Did you remember to?

  • Read through this webpage
  • Submit Asset Collection Assignment on Blackboard