Skip to content

15. Interface and Application

Groupwork

Testing interfaces

Controlling a pinball game with a pinball machine

For my interfaces and applications week I made a simple Unity program that reacts to the pinball machines serial communication. I decided to visualize the program as a pinball machine, so that when user presses the button for paddle on the physical machine, the paddles also move on the Unity screen.

The idea is to connect the pinball machine to the computer via USB-cable, and then have the Unity game react to the things that happen in the machine. Or in other words, make a pinball computer game that can (and must) be controlled by an actual pinball machine.

Unity Scripts

I created a new Unity project using the default 2D template. Then I drew a graphic with a paddle using Affinity Designer, and exported it as a png. Then I dragged it into the Unity project, under assets/sprites.

Then I created four new script files and stored all of them under assets/scripts. Those scipts were:

GameController

Listens for the serial communication and sends events based on it to the other objects in the game.

Listener

A superclass for all the objects that listen for GameControllers events. Contains an id attribute and two methods. CheckMessage() method checks if the event has a correct id, and then calls the abstrach Act() method, which (like all abstrack methods) are defined in the subclass.

PaddleMove

A subclass of Listener. When Act is called with message of “1”, it will rotate the paddle to the set. Otherwise it will rotate it back to the 0 degree rotation. Also has a two private attributes that are defined with [SerializeField] tag, so that they can be edited in the Unity editor: maxAngle and speed. Those define the aspects of rotation that their names would suggest.

Toggle

A subclass of Listener. When Act is called with message “1”, it will scale itself to a bigger size until another message comes. The scaling is based on percentage of the original scale.

The game also includes a ball, but that did not need any new script files, as it is just a physics object.

Unity Objects

Those scripts needed to be attached to Unity objects. Unity uses a component-based architecture, where all game objects (things that exists in world space) can have many components (i.e. scripts) as they need. All those components can edit the object unhindered, which can often cause problems, when multiple scripts want to edit the same attribute in different ways.

There are four types of objects in this screen, with the following components:

GameController

This is a GameObject mostly because it makes it easier for it to search for the other objects from the game. Otherwise it is not visible. The only component it has is the GameController script.

Paddle

This object contains the following componets:

  • SpriteRenderer, to draw the sprite. Uses the paddle.png sprite.
  • Rigidbody2D, all physics objects in Unity need some kind body, and Rigidbody2D is the easiest and most versatile of them. This is set to kinematic so that gravity will not affect it.
  • EdgeCollider2D, all bodies in unity need a collider, so that Unity knows the bounds of the objects.
  • PaddleMover, the script that I made.

Bumper

This object contains the following components:

  • SpriteRenderer, to draw the sprite. Uses the default square texture that is normally used by unity buttons.
  • Toggler, the script that I made to animate bumper movement.

This script does not have any physics simulations, as it was deemed unnecessary. It is only a visual indicator.

Ball

This object contains the following componets:

  • SpriteRenderer, to draw the sprite. Uses default sphere sprite.
  • Rigidbody2D, all physics objects in Unity need some kind body, and Rigidbody2D is the easiest and most versatile of them. This is set to dynamic, as it needs to react to gravity.
  • CircleCollider2D, all bodies in unity need a collider, so that Unity knows the bounds of the objects. Balls can be circular.

Arduino Code

This is the same basic Arduino code that I use in the final project for my main board. The only difference here is that the code displayed there formats the serial comminication code in a way that the Serial Plotter of Arduino IDE can read it. For this project I changed the communication to use json format, as it is easier to deserialize on Unity side.

json object

{
  id: $string,
  value: $string
}

I had some problems reading the Serial communication when I was using the XIAO RP2040 chip as my main board chip. The communication would constantly throw errors, where the Unity SerialCommunication library could not connect to the board. I spent at least 4 hours trying different serial communication methods and functions and libraries, and stood there baffled when the Arduino IDE would show serial communication with its Serial Monitor, but Unity would not show a thing. This was immediately fixed, once I swapped the chip to ESP-32c. Most likely there is some additional layer in the RP2040 communication, that prevents the serial communication from connecting directly.

Anyway I do not no why exactly it happed, but at least these were not the cause:

  • The Serial Monitor was not open in Arduino IDE. (i.e. the port was not busy)
  • The port was correct, or at least the port disconnected when I unplugged the usb cable.
  • Line ending mismatch.
  • Baud rate.

Demo

Currently the Unity code supports the paddles, and they do to work when using dummy data during testing. The problem is that the current iteration of the pinball machine used in the final project does not have PCBs in the paddles, or any other way for the main board to know what they do. The paddles in the device are just a collection of wires that go from 24V power source through the solenoid and the button to the ground.

Thus, in the demo you can only see the bumpers reacting. Also sometimes you can see that both bumpers activate when in press the ball against one of the bumpers. This is most likely caused by the large copper plates acting as antennas when 100W solenoids activate next to them. Or at least the bumper PCBs do report that they detected a ball shorting the copper plates when the bumpers fire erroneously at the same time with other solenoids.

Demo with dummy data

This shows a demo with dummy data, so you can see that the paddles do indeed move.