Select Page
Game Design
Class 03: UI & Code Interaction

Topics

  • UI
  • Code Interaction
  • Basic Sprite Creation
  • Platformer (stats) Lab Demonstration
  • Supporting Sprites Assignment

Third time’s the charm

UI

UI:

Unity has a built-in UI system. The UI uses a Canvas object that the various UI objects (text, image, button, etc.) are attached to. This is excellent because the Canvas will stretch and auto-orient to the resolution of the device it is viewed on with the UI element flexing to match. This makes it possible to create one UI for all builds.

GUI:

GUI or graphical user interface is exactly as the name suggests. It is artwork that the user views and interacts with. In our case it will be used for the menu system as well as the HUD (heads up display).

Notice how the Left Corner UI object “sticks” to the same position regardless of how the screen is sized.

Code Interaction

Manual Selection:

If you create a public (or serialized) variable you can drag the object you want to fill it in the Unity editor. This is the easiest way to connect items but not the cleanest.

    public Rigidbody2D playerRB2D;

    void Update()
    {
        playerRB2D.velocity = new Vector2(Input.GetAxis("Horizontal") * playerSpeed, playerRB2D.velocity.y); 
        if(Input.GetAxis("Jump") > 0 && ground)
        {
           playerRB2D.AddForce(transform.up * playerJumpStrength); 
        }
    }

Hierarchical Connection:

It is possible (and most efficient) to connect objects using their relationship to each other. This obviously only really works on elements within a hierarchy.

    private Rigidbody2D playerRB2D;

    void Start()
    {
        playerRB2D = GetComponent<Rigidbody2D>();
    }

    void Update()
    {
        playerRB2D.velocity = new Vector2(Input.GetAxis("Horizontal") * playerSpeed, playerRB2D.velocity.y); 
        if(Input.GetAxis("Jump") > 0 && ground)
        {
           playerRB2D.AddForce(transform.up * playerJumpStrength); 
        }
    }
for components attached on the same object
GetComponent

playerRB2D = GetComponent<Rigidbody2D>();
for components attached on parent object
GetComponentInParent

playerControllerScript = GetComponentInParent<PlayerControllerScript>();
for components attached on child object
GetComponentInChildren

groundCheckScript = GetComponentInChildren<GroundCheckScript>();

Find Object:

If you cannot manually connect something and it is not directly connected you can use the Find method to search for it.

gameControllerScript = GameObject.Find("GameController").GetComponent<GameControllerScript>();
find objects in scene
Find

gameControllerScript = GameObject.Find(“GameController”).GetComponent<GameControllerScript>();

Basic Sprite Creation

Piskel:

I am going to use Piskel in this class but you may use whatever you like.

You should start by making the following:

Platformer (stats) Lab Demonstration

This is what we are making today

You may download the Unity project here.

Assets

Environment
Midground
The imagery that the player character can actually contact, ground, platforms, walls, etc.
Characters
Player
The protagonist controlled by the player
Other(pickups, UI, etc.)
Lives
Add lives to the player lives total
Points
Adds to the total score
we will use stand-in sprites to start off with but you will eventually make your own graphics.

Scripts

New Scripts
PlayerPickupScript
Detects pickups such as lives or score
Updated Scripts
PlayerControllerScript
Add the ability to flip the graphic left or right
PlayerStatsScript
Add the score
Old Scripts
GroundCheckScript
Checks that the player character is on the ground
DeathboxScript
Runs the death function when player enters
VictoryboxScript
Loads next level when player enters
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 Vector2 startPos;

    private PlayerStats pStats;

    void Awake()
    {
        pRB2D = GetComponent<Rigidbody2D>();
        pStats = GetComponent<PlayerStats>();
    }
    // Start is called before the first frame update
    void Start()
    {
        startPos = transform.position;
    }

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

        if(Input.GetButtonDown("Jump"))
        {
            if(ground)
            {
                pRB2D.AddForce(Vector2.up * (jmpStr * jmpBst));
                ground = false;
                doubleJump = true;
            }
            else 
            {
                if(doubleJump)
                {                    
                    pRB2D.AddForce(Vector2.up * (jmpStr * jmpBst));
                    doubleJump = false;
                }
            }
        }    

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

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

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

    IEnumerator JumpBoost()
    {
        jmpBst = 2;
        yield return new WaitForSeconds(10);
        jmpBst = 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;
    }
}
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!");
        }
    }
}
StartMenu.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class StartMenuScript : MonoBehaviour
{
    public void StartGame()
    {
        SceneManager.LoadScene("Level01");
    }

    public void QuitGame()
    {
        Application.Quit();
    }
}
Pickup.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Pickup : MonoBehaviour
{
    public string pickup = "life";

    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);
                    Destroy(gameObject);
                    break;
                case "Jump Boost":
                    col.gameObject.GetComponent<PlayerController>().PowerUp("Jump Boost");
                    Destroy(gameObject);
                    break;
            }
        }
    }
}
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;

    public TextMeshProUGUI livesText;
    public TextMeshProUGUI scoreText;

    void Start()
    {
        UpdateLives(0);
        UpdateScore(0);
    }

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

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

Supporting Sprites Assignment

Supporting Sprites:

The game we have created thus far now has a player character sprite but the rest of the game has only simple shapes. In this assignment you will create the sprites for the supporting elements of the game. This means everything but the environment tiles. The enemy, pickups, detials, etc. should all have graphics created. Once completed you should combine them into one sprite sheet and saved as a png image.

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

Wait! Before you go!

Did you remember to?

  • Read through this webpage
  • Submit Supporting Sprites Assignment on Blackboard