Game Dev Notes #4 – Tilevania

These are notes from the Complete C# Unity Game Developer 2D Udemy Course

Sprites

We want to change Pixels Per Unit to something that sizes well. 32 might be good.

Splitting Sprites: change Sprite Mode to Multiple, then open in Sprite Editor. Then we Splice -> Automattic and make sure we’re good. Apply and it will automatically create individual assets from the sprite sheet. Neat!

Slice By Grid and choose the pixels you want to be more accurate for retaining space.

Tilemap Grid

Tilemaps are where we can apply a swathe of settings to a single tile set. So we’ll want to create multiple tilemaps for our different layers. Some things to keep in mind:

  • Layer: Refers to the collision layer of the tiles.
  • Sorting Layer: Refers to where the tilemap appears in the layers relative to other tilemaps, so the thing to change when certain layers seem hidden.
  • For collision, you’ll want to make sure to add:
    • Tilemap collider 2d
    • Composite collider 2d

Tilemap Pipeline

  • Sprite Sheet
  • Sliced Sprite
  • Tile Asset
  • Tile Palette

Tile Rules

Right click -> 2d -> tile -> rule tile

Click and drag it into a palette

Collision:

Add component to tilemap

Tilemap Collider 2

Animation

Animator Component: Assigns animations to GameObjects through an Animator Controller

Animator Controller: Arrangement of animatiosn and transitions (go from running to jumping, to idle etc)

Animation: The specific pieces of motion (go from this frame to that frame)

Sprite Renderer: Displays the 2d sprites on screen

Animations get added into the controller and are triggered based on various states.

Set up Character Idle

  • import spritesheet and slice
  • add sprite rendered to player
  • create idle animation clip
  • create character animation controller
  • Add idle animation to animation controller
  • Add animator to player
  • Assign character animator controller to player

Prefabs

  • Original template is called the prefab and the copies added to scene are called instances.
  • Game objects which have turned into reusable templates
  • Create a game object and drag it down into assets to createa pefab
  • To make changes, change on instance, then go to Overrides -> Apply all

Input System

  • Window -> Package Manager -> Make sure on Unity Registry -> Install Input System
  • On your player object, create a new component -> Player Input
  • Create an new Action and set it up, make sure it gets assigned to the component.
  • Next, open Input Settings and create Input System Setting, or whatever it’s called.

Remember that for scripts, you need to using UnityEngine.InputSystem; at the top of the file to be able to use the new package.

Movement is acted against RigidBody, so that’s what we need to access in order to update.

Materials

Right click -> Create -> 2D -> Physical Material 2D

  • Friction to 0: Prevent player from sticking to the sides of things.
  • Bounciness: Whatever this is set to will make the player bounce height X value high.

Putting it all Together

Here’s how you’d add a new game object with some animations:

  • First, add the sprite sheets you want into the sprite folder and cut it up using the steps above.
  • Right click -> Create Empty 2D Object
  • Add the following components:
    • Sprite Renderer (so a sprite can show, assign it a normie sprite from your sheet)
    • Some kind of collider 2d (for collision detection, pay attention to the body type depending on what you need)
    • Rigidbody 2d (to make sure it has weight and can be effected by gravity)
    • Animator (to make sure we can animate it, we’ll be setting the "Controller"

For the animation:

  • In the sprites folder you’ve created, highlight the group of sprites that make up the single animation. Right click -> Create -> Animation. Check the box to make it loop if you gotta.
  • Move this newly created animation thing to your Animations folder.
  • In the animations folder Right click -> Create -> Animation Controller
  • Open up the controller and right click -> Create state -> Empty, assign it a name like "Idle"
  • In "Motion" add your animation thing you created
  • Back to your game object, assign that new Animation controller in the Animator component.

If you need to flip a character, you can set its Scale transform component to -1.

Firing a Bullet

Create an empty object underneath the player to be whatever the "gun" is going to be. Add a sprite to it and a rigidbody as well as a collider. Make this a prefab.

Initializing

Initialize(): We can initialize by:

  • [SerializeField] GameObject objectName
  • [SerializeField] Transform projectilerName
  • `Initialize( objectName, projectilerName.position, transform.rotation )

We use velocity to tell Game Objects to move across the screen.

Hooking Up Levels

Building Scenes

We need to make sure scenes are added to the build so we can load them.

File -> Build Settings -> Click and drag the scenes to "Scenes in Build" and exit.

Scenes

Make sure we add using UnityEngine.SceneManagement;

Then we can use SceneManager.GetACtiveScene().buildIndex to get the current build index.

SceneManager.LoadScene(sceneIndex); will load the next scene.

SceneManager.sceneCountInBuildSettings will return how many scenes there are.

Coroutines

  • a way to create a delay for the game
  • the core concept is to understand that we start a process (Start coroutine) then go off and do other things *yeld) until our condition is met (ie, wait 2 seconds);

We call:

StartCoroutine(NameOfMethod());

Our method:

IEnumerator NameOfMethod()
{
    yield return new WaitForSecondsRealtime(time); // wait for some stuff to happen, then continue on doing whatever you were doing.
}

This waits for the condition set in the yield return new line to finish and then it runs the rest of the method.

Game Controller

Reloading the Scene

This will reload everything, so we will create a Game Session object to keep track of data that we need to persist between loads.

Sound

AudioSource.PlayClipAtPoint( 'clip name', position (like a vector, or the camera) )

Persisting

Creating a singleton, you’ll want an awake like this (if you’ve got one of these alraedy, you don’t need another one):

    void Awake()
    {
        int numGameSessions = FindObjectsOfType<GameSession>().Length;
        if ( numGameSessions > 1 )
        {
            Destroy(gameObject);
        }
        else
        {
            DontDestroyOnLoad(gameObject);
        }
    }

Leave a Reply