Dear students:
We have formed teams and are hashing out game ideas. Some of us are feeling the repressed artist inside of us wake up to the call of pixel art. We should keep that progress going. Right after a lab exercise!
Let’s make a game—one that uses a two-axis joystick. We’ll move an avatar around the screen with the joystick, and when it runs into something, that something will disappear.
Behold, the controller that we’ll make today:
The joystick is an analog component. An analog component yields readings across a broad spectrum of values, whereas a digital component, like a button, only yields 0 and 1. This means that the joystick supports degrees of intensity that we cannot achieve with a button.
Assemble the controller as follows:
The fifth pin on the joystick is for the button press that you can achieve by pressing the joystick toward the board. We’re not using it today.
Once assembled, follow these steps to get your firmware up and running:
setup
, prepare pins A0
and A1
for INPUT
.loop
, read the two pin values with analogRead
.A0
. We’ll add the vertical reading later.What values do you see in the Serial Monitor?
Compare your answers against mine.It’d be nice if pushing left made the number go negative, idle was 0, and pushing right made the number go positive. Let’s make that happen. We want to turn a number in the top range into a number in the bottom range:
What calculation do we perform?
What if we want to perform this mapping, which is a reverse of the previous?
What math would we use here?
Let’s keep going.
Once you have both numbers printing, we want to send them across the serial port to Unity. Last time we used Serial.write
to send over a byte value in binary. We could try that here, but our numbers exceed what can be stored in a single byte. Perhaps we could do some bit twiddling to decompose the values into two separate bytes? All told, each message would be 4 bytes long.
However, we’re going to run into another issue with serial communication. The Arduino will be pushing out a steady stream of bytes. At some point our Unity game will start drawing from this stream of bytes and interpreting its contents. But it might not start at the first byte of a message. If it starts reading at the third byte, then x and y will be effectively flipped. If it starts reading at the second or fourth bytes, we’ll get some unintelligible results.
To help get our game and the Arduino in sync, let’s insert start and end markers around each message. And let’s eschew binary for the ASCII format.
[HORIZONTAL VERTICAL]
, with HORIZONTAL
and VERTICAL
replaced by the actual numeric values. Here we have used square brackets as markers. Use your favorite markers that won’t appear in the body of the message.As you develop your controller firmware, you’ll need to establish a protocol like this describing your message format.
Now that we have a working controller, let’s turn to our game. Complete the following to establish our scene:
PlayerController
to the object.Start
function, establish a serial connection.Update
function, read a line of input with the ReadLine
method of your serial connection.Once you have confirmed that messages are getting through, it’s time to push the game object around the scene based on the intensity and direction of the joystick. Follow these steps to get your object moving:
ReadLine
yields a string with the linebreak still attached.)float
.Vector3
using the two numbers. Scale the x- and y-components down to avoid big jumps. Set the z-component to 0.transform.position
.You should now have a moving game object. For our final step, let’s add a second, stationary game object. When the player collides with it, the object disappears and the player wins. Follow these steps to achieve this endgame:
OnTriggerEnter
method to PlayerController
.OnTriggerEnter
has a gameObject
property representing the object with which we are colliding. Delete this object.Does it work? If so, show your working game to your instructor to receive credit for this lab.
Here’s your TODO list for next time:
See you next time!
Comments