Customizable Button Controller for Unity
by miyulake in Circuits > Arduino
621 Views, 1 Favorites, 0 Comments
Customizable Button Controller for Unity
Customizable buttons to use in Unity! While working on simulating keypresses in processing I got curious and wondered if I could do something similar, but in Unity using the arduino instead. This led me to create an easily customizable setup for a controller in Unity.
Doing this I learned how to read data from the datastream directly into Unity.
The way I wanted to create this was to leave a lot of room for things to add and customize without having to rewrite lots of code or removing components from the project.
Supplies
What you'll need is a computer and the following items;
Software:
- Unity
- Arduino IDE
Tools:
- Soldering Iron
- Perfboard (Breadboard for testing)
Components:
- Buttons
- Wires
- USB B Cable
- Arduino Uno
- Anything else you want to experiment with
Setting Up Two Buttons
To start testing some buttons right away we need to get our Arduino, breadboard and buttons ready!
I recommend starting with two or even one simple button like in the schematic shown in the attached image to start testing whether the code and the Arduino are doing their job correctly.
Its very simple to setup and you can use the code in the next step right away using the Arduino IDE to see if it works.
Doing it my way means you now have two buttons!
- D8 - Down button
- D7 - Up button
And ofcourse you can change or switch this around if you want.
Easy Coding
Open your aruino IDE and use this script, but in order for this to work in Unity your gonna need to use the library below!
Luckily its very easy to import libraries. Just drag and drop the library file onto the Arduino sketch and it should open a seperate window with the library.
#include "signalenzo.h" //Thanks to Aeralius for creating this library -w-7
float lastValue;
void setup()
{
//Opening connection
Serial.begin(9600);
//Regestering all the buttons
pinMode(8, INPUT_PULLUP);
registerSignalCommand(8);
pinMode(7, INPUT_PULLUP);
registerSignalCommand(7);
pinMode(8, INPUT_PULLUP);
registerSignalCommand(4);
pinMode(7, INPUT_PULLUP);
registerSignalCommand(2);
}
void loop()
{
//Don't torture the Arduino :)
delay(50);
checkSignals();
}
The script registers buttons and let's Unity know when something is pressed.
The libary;
//From Aeralius
bool signalPins[14] = {};
bool signalPinsUps[14] = {};
bool signalPinsDowns[14] = {};
void registerSignalCommand( int Pin )
{
signalPins[Pin]=true; //Add the pin to the pin list thing :)
}
void checkSignals()
{
for(int i=0;i<14;i++)
{
if(signalPins[i]==true)
{
//DOWN
if(!digitalRead(i) and !signalPinsUps[i])
{
signalPinsUps[i] = true;
signalPinsDowns[i] = false;
Serial.print("D");Serial.print(i); Serial.println(",1");
}
//UP
if(digitalRead(i) and !signalPinsDowns[i])
{
signalPinsUps[i] = false;
signalPinsDowns[i] = true;
Serial.print("D");Serial.print(i); Serial.println(",0");
}
}
}
}
This is the actual managing system for letting Unity know!
Testing (finally) Two Buttons
Open the serial monitor and see if you can toggle the buttons like shown in the attached image above;
(Full demonstration in the video attached)
- Down button: D8 (0 or 1)
- Up button: D7 (0 or 1)
Moving Onto Unity
Using Unity and the System.IO.Ports namespace we can read the data generated from the arduino in Unity.
(Caution! If Unity doesn't detect this namespace check your Api Compatibility Level in the Player settings. My project was using the .NET Framework!)
With the code setup in the Arduino IDE we can use some simple code in Unity to recreate the same results.
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO.Ports;
public class ArduinoTest : MonoBehaviour
{
private SerialPort stream;
private bool pressedUp;
private bool pressedDown;
private void Awake()
{
LookForArduino();
}
private void Start()
{
StartCoroutine(ReadDataFromSerialPort());
}
private void Update()
{
CustomMove();
}
private void LookForArduino()
{
Time.timeScale = 0;
for (int i = 0; i < 12; i++)
{
try { stream = new SerialPort($"COM{i}", 9600); stream.Open(); i = 14; }
catch { }
}
if (stream.IsOpen) Debug.Log("Arduino found!");
Time.timeScale = 1;
}
//Getting the inputs
private IEnumerator ReadDataFromSerialPort()
{
while (true)
{
try
{
if (stream.BytesToRead > 0)
{
string tmpA = stream.ReadLine();
string[] tmpB = tmpA.Split(',');
if (tmpB[0] == "D7")
{
pressedDown = Convert.ToBoolean(int.Parse(tmpB[1]));
}
if (tmpB[0] == "D8")
{
pressedUp = Convert.ToBoolean(int.Parse(tmpB[1]));
}
}
}
catch
{
LookForArduino();
}
yield return new WaitForSecondsRealtime(0.05f);
}
}
private void CustomMove()
{
if (pressedDown && !pressedUp)
{
pressedDown = false;
Debug.Log("Pressed Down");
}
if (pressedUp && !pressedDown)
{
pressedUp = false;
Debug.Log("Pressed Up");
}
}
}
The code might look a bit confusing at first, but the most important part is the last function CustomMove().
Within this function you can customize the buttons to do whatever you want.
Just add or change the Debug.Log with something else!
Keep Expanding!
Personally this is where I slightly messed up with both the placing of the components on the perfboard and the soldering causing two buttons on the right to work inconsistently.
I reworked the placing on the perfboard in the attached image above and if you solder better than I did then it should work perfectly fine.
Also! When soldering the two cables to the button make sure you don't solder them both to the internally connected side. I had to unfortunately learn about this the hard way.
During this step you can keep expanding the code and add as many buttons as you want!
Final Version (for Now)
Sadly due to time constraints I couldn't do more with the custom controls. I spend most of my time studying the code so making another project to properly showcase its usability was unfortunately not in my time budget.
However I hope this helped out someone who was struggling to find good ways to do this like I did. Thanks once again to Aeralius for helping me figure out some of my issues with the Arduino and overall I had a fun time making this.