ITTT Reverse VR Lars Mulder
.
Supplies
1x Arduino UNO
2x Red LED
1x 220 Ohm Resistor
Atleast 9 cables
4x Micro Servo
1x Printplate
Description of the Project
The Reverse VR character is a character made to show what it would be like if the player was in the game, and real life would simulate in-game inputs.
When connecting the USB with the computer, the robot will run a quick initialisation to show that it is completely functional on all it's servos and LEDs. After that, it will patiently wait for the player to start up their Unity project or game, and move their mouse, click their mouse, or press W or S to move forward or backwards.
Simulation of a Circuit
To begin with, let's show the circuit that is used to make the entire thing work, and what parts are mandatory to be welded. For simplicities sake, wires that dont have to be welded to anything in order to work aren't show as such in the image above, even if for this project they were welded to a printplate.
In my design, only the four servos are required to use the 5V input of the arduino. So to make that work, we're going to create a printplate that has a plus line, in which all the servos' plus wires are connected to the islands on one side, and one plus wire runs to the 5V of the arduino on the other side. Then for all the minus wires of the servos, as well as the minus wires of the LED's, we make another row on the print plate and weld them all to one side on seperate islands, with one wire on the other side connecting them all.
After everything is welded and connected to the arduino, run the code from the next section and see if it's working!
Arduino Code
Download the code below to see how the program interacts with the Unity side of things. Make sure that all your pins and servos are connected to the right outputs, or change them to the outputs you've chosen on your own arduino.
Downloads
C# Code
using System.Collections; using System.IO.Ports;//Use .NET 4.0 in Unity to access this library using UnityEngine; using UnityEngine.UI; public class ArduinoTest : MonoBehaviour { [HideInInspector] public SerialPort sp; public Text txt; public PlayerMovement playerMovement; void Start() { txt.text = "Looking for Board"; StartCoroutine(Search()); } /* Codes Fire on 1 - 1 - 0 Fire off 2 - 1 - 0 Head Turn 3 - degree (1-90) - 0 Hip turn 4 - degree (1-90) - 0 Run Speed 5 - 1/2/3/4/5 - 0 */ private void Update() { if (sp != null) { if (sp.IsOpen) { if (Input.GetMouseButtonDown(0)) { byte[] buf = new byte[] { 1, 1, 0 }; sp.Write(buf,0,3); } if (Input.GetMouseButtonUp(0)) { byte[] buf = new byte[] { 2, 1, 0 }; sp.Write(buf, 0, 3); } if (Input.GetKeyDown(KeyCode.W)) { byte[] buf = new byte[] { 5, 4, 0 }; sp.Write(buf, 0, 3); } if (Input.GetKeyUp(KeyCode.W)) { byte[] buf = new byte[] { 5, 3, 0 }; sp.Write(buf, 0, 3); } if (Input.GetKeyDown(KeyCode.S)) { byte[] buf = new byte[] { 5, 2, 0 }; sp.Write(buf, 0, 3); } if (Input.GetKeyUp(KeyCode.S)) { byte[] buf = new byte[] { 5, 3, 0 }; sp.Write(buf, 0, 3); } } } } private IEnumerator Search() { while (sp == null) { //Looks for all connected and open serial ports on the pc/laptop foreach (string str in SerialPort.GetPortNames()) { //Change this string based on what your arduino needs. For me it was COM3 if (str == "COM3") { //Open a new serial connection on this port sp = new SerialPort("COM3", 9600); sp.Open(); sp.ReadTimeout = 1; txt.text = "Board found named: " + str; break; } } yield return new WaitForSeconds(0.04f); } } }
using System; using UnityEngine; public class PlayerMovement : MonoBehaviour { //Links the script that handles arduino related things public ArduinoTest arduino; public GameObject bulletPrefab; public float horizontalTurnSpeed = 2.0f; public float movementSpeed = 5.0f; private float shootTimer; private float headUpdateTimer = 0.1f; private Rigidbody rb; private void Awake() { rb = GetComponent<Rigidbody>(); Cursor.visible = false; Cursor.lockState = CursorLockMode.Locked; } private void Update() { if (Input.GetMouseButton(0)) { Shoot(); } if (Input.GetKey(KeyCode.W)) { MoveForward(); } if (Input.GetKey(KeyCode.S)) { MoveBackward(); } if (headUpdateTimer < 0) { headUpdateTimer = 0.2f; TurnHead((int)transform.eulerAngles.y); } } private void FixedUpdate() { transform.Rotate(0, horizontalTurnSpeed * Input.GetAxis("Mouse X"), 0); shootTimer -= Time.fixedDeltaTime; headUpdateTimer -= Time.fixedDeltaTime; } public void MoveForward() { rb.position += transform.forward * Time.deltaTime * movementSpeed; } public void MoveBackward() { rb.position -= transform.forward * Time.deltaTime * movementSpeed; } public void Shoot() { if (shootTimer < 0) { shootTimer = 0.1f; GameObject bullet = Instantiate(bulletPrefab, transform.GetChild(2).position, Quaternion.identity); bullet.GetComponent<Bullet>().direction = transform.forward; } } public void TurnHead(int degrees) { //if the arduino is connected if (arduino.sp != null) { if (arduino.sp.IsOpen) { //1 tot 90 degrees //degree calculation int headDegrees = Mathf.Abs(degrees / 4) + 1; int hipDegrees = Mathf.Abs(degrees / 4) + 1; //send the degrees in two parts, one for the head and one for the hips byte[] buf = new byte[] { 3, Convert.ToByte(headDegrees), 0 }; arduino.sp.Write(buf, 0, 3); byte[] buf2 = new byte[] { 4, Convert.ToByte(hipDegrees), 0 }; arduino.sp.Write(buf2, 0, 3); } } } }
Building the Reverse VR Robot
Building the RVR robot was quite a challenge for me, as I am not very good at crafting things in real life. I started by trying to see if I could get all four servos connected to the arduino and seeing if they could all run like they should.
After that, I glued the servos together in the right position using hot glue for the body to do all required movements.
After that I started building the different parts of the robot, from his head, with the two led lights inside, to the pole on which his body has to be attached to make sure his legs are off the ground.
When all of that was attached to eachother, I ran the wires down to the arduino through the attachment and plugged everything into the arduino.
Afterwards I crafted a small rifle from wood sticks and an arm, and added it to the body for show.
My Reflection
In this project I have learned two new things.
- How to use servos with Arduino.
- How to connect your Arduino to Unity and send inputs from and to the arduino.
This was a valuable learning experience from me, and despite the hardships a lot of fun to make, and it has inspired me to continue working with Unity even more. If I were to ever play with Arduino again, I would certainly use it with Unity again, but then I would want the arduino to influence the game as well, instead of only having unity influence the arduino.