WebGL RPG In Unity - Part 01: Organization & Movement
Overview
The very first thing we have to do is some general set-up of our workspace. We
will place down a few ground rules regarding where and how files should be placed so as to help us find and use
stuff in the long term. Once we have that done, we'll get started on implementing a very basic player movement
system which will be useful in testing just about everything else we will be adding to the game.
The Organization
Our file hierarchy will be as follows:
Project
|
|- Art
|
|- Sprites
|- Menu
|- Audio
|
|- BGM
|- SFX
|- Data
|- Fonts
|- Materials
|- Prefabs
|- Scenes
|- Scripts
Art:
In this folder we will put all the images and graphics we will be using in our game.
It is split up into two sections. "Sprites" will be for sprite sheets, loose sprites, and animations while "Menu" will hold menu and background art.
Audio:
We will put all of our audio files in here. We'll separate
our audio into two folders. "BGM" will be for background music, or longer music tracks that play in the background of
a level or scene. "SFX" will be for sound effects, or short clips used for actions sounds such as the casting of a spell
or the clang of metal.
Data:
Data will be our dumping ground for all the miscellaneous files
that have no other place. These include start-up preferences, save files, dialogue storage files, etc.
Fonts:
It's a folder for holding fonts, or "typefaces" if you want to be
"that guy", to be used in the game. Pretty simple. Unless we want to be stuck with nothing but Arial for the rest of time, it's
necessary.
Materials:
As we will be working mostly with sprites, we will not have any
use for materials in the finished product. However, materials are a very quick and easy way to distinguish one object from
another. Simply make a material for the player object, pink for instance, and another for some sort of collider and bam! Nice,
easy way to keep from confusing your game objects. Since we are not working in a 3D space with proper lighting set up, we will
just have to make each material to render as an unlit color to circumvent said issue.
Prefabs:
Prefabs are quite useful is setting up a game scene. Essentially, a prefab
is a template of a game object. Say you were to create a player object, tricking it out with all the correct scripts, textures, and other
such things, and made it into a prefab. Placing this prefab into any scene would be placing an instance of the game object, kind of like
reading the object template we had created and plopping down a copy. The bonus is that changing the prefab will also change any game objects
that use that prefab, so you would not have to go through and edit every single wall in your scene.
Scenes:
Scenes are files that store game objects. The most easy way to think of them is
as levels, or scenes, of a game. They are used to split a game up into smaller, more manageable chunks.
Scripts:
Ah, this is the meat of our project: the actual code.
The Movement
With that out of the way, we will create some sort of object that we can move around a scene. We'll initially just make a
testing scene, "testScene.unity", (I know; I am very creative) and place a quad right in there. Why a quad? I don't know; I just like quads. Unity 2D is,
after all, just Unity 3D with the view edited to be 2D, so why not? Let's also make sure to make that into a player object prefab and stick some material
on it.
Now we have a colored square on the screen. The game is almost complete! Our next step is to crack open Visual Studio, or
Monodevelop if you are some sort of weirdo, and get, uh, cracking.
So here is our totally blank C# file:
using UnityEngine;
public class playerInput : MonoBehavior {
void Start () {
}
void Update () {
}
}
The only part of this we will actually need for now is Update (). Update () will trigger on every game frame, which makes it
pretty good for minimizing dropped inputs. In order to make our character move, we need two things: the players actual input and then a conversion of that
into movement. Simple enough. In order to capture key pressed for movement in a 2D plane, we'll make a vector2D.
using UnityEngine;
public class playerInput : MonoBehavior {
public static Vector2 input;
void Update () {
input = new Vector2 ((Input.GetKey (KeyCode.A) ? -1 : 0) + (Input.GetKey (KeyCode.D) ? 1 : 0),
(Input.GetKey (KeyCode.W) ? 1 : 0) + (Input.GetKey (KeyCode.S) ? -1 : 0));
}
}
It's a bit of a funky line, so let's break it down. Clearly, we are using standard game input: W for up, S for down, A for left,
and D for right. For each direction, we are using a ternary operator to convert that key press into either 0 (no press) or 1 / -1 (press detected). Now, the
magic of this statement is that we add the results of opposite sides, like left and right or up and down. If you look top down at a Cartesian plane, you will
notice that if you go to the left, you are moving into the negatives with respect to the x axis. Going right, conversely, will lead you into the positives. In
Unity, our scene works the same way. If we are pressing A (move left), our sum for the x axis movement (input.x) will be -1 + 0, which is -1. Pressing "move
right" will yield 1. Pressing both, however, cancels each other out, getting 0.
You have likely already noticed that input is nothing more than a way to convert key pressed into a unit vector. We will use this
vector along with some sort of speed variable in order to move at a steady velocity in the requested direction. I've already found a fairly good speed via messing
around with the value in the editor, so I will just use that value.
Now that we have a way to store the velocity as well as some sort of speed reference, we must actually turn that into something the
game can use to move the player object. In order to do that, we will translate this (this being the object the script is attached to) by the total distance the
object would travel in the time frame of each frame.