So, I've been bored, and trying to learn the limits of Unity3d free edition. I also work with arduino (obviously), and came up with the idea that many people have.
Why can't use use an accelerometer and use it to view the 3d world that way?
Well, I did some research on the matter, and it seemed that everyone decided that you had to have a plugin in order to send and receive information. I've found that is not true... to a point. (plugins mean you have to have the pro version which is currently $1200usd)
Importing the right stuff gets you to be able to read serial, and after a bit of annoyance on getting it to read the information right, and delaying the arduino by 10ms so that I could actually read the information, it works fine. At least in the standalone player in Windows. I'm not sure on mac, but I know that web player doesn't support it.
So, here I sit with some spiffy code, and decided that even though I haven't been in the Unity3d community long, I would simply post a bit of code that lets you get information from a serial device. (Note: You can use ANY serial device as long as you know how to read the information.)
C# Code:
using UnityEngine;
using System.Collections;
using System.IO.Ports;
public class serialRotation : MonoBehaviour {
SerialPort stream = new SerialPort("COM4", 9600); //Set the port (com4) and the baud rate (9600, is standard on most devices)
float[] lastRot = {0,0,0}; //Need the last rotation to tell how far to spin the camera
void Start () {
stream.Open(); //Open the Serial Stream.
}
// Update is called once per frame
void Update () {
string value = stream.ReadLine(); //Read the information
string[] vec3 = value.Split(','); //My arduino script returns a 3 part value (IE: 12,30,18)
if(vec3[0] != "" && vec3[1] != "" && vec3[2] != "") //Check if all values are recieved
{
transform.Rotate( //Rotate the camera based on the new values
float.Parse(vec3[0])-lastRot[0],
float.Parse(vec3[1])-lastRot[1],
float.Parse(vec3[2])-lastRot[2],
Space.Self
);
lastRot[0] = float.Parse(vec3[0]); //Set new values to last time values for the next loop
lastRot[1] = float.Parse(vec3[1]);
lastRot[2] = float.Parse(vec3[2]);
stream.BaseStream.Flush(); //Clear the serial information so we assure we get new information.
}
}
void OnGUI()
{
string newString = "Connected: " + transform.rotation.x + ", " + transform.rotation.y + ", " + transform.rotation.z;
GUI.Label(new Rect(10,10,300,100), newString); //Display new values
// Though, it seems that it outputs the value in percentage O-o I don't know why.
}
}
Arduino test code:
float value = 0;
boolean flip = false;
void setup()
{
Serial.begin(9600);
}
void loop()
{
if(value >= 1023)
{
flip = true;
}else if(value <= 0)
{
flip = false;
}
if(flip == false)
{
value += 1;
}else{
value -= 1;
}
float values[] = {0,0,value};
Serial.flush(); //clears any possible left over information
Serial.print(map(values[0],0,1023,0,360)); //Resizes values from the range on arduino input to 360 of rotation.
Serial.print(",");
Serial.print(map(values[1],0,1023,0,360));
Serial.print(",");
Serial.print(map(values[2],0,1023,0,360));
Serial.println();
delay(10);
}
What's the practical use? Well, I want to stick a screen to my face and the arduino to the top of my head and get some VR kind of effects from it. Wouldn't be too bad to get true VR effects for less then $200. Add to that a decent controller and a great game and you have the VR of the future!
I'd also like to be able to use my arms and such in this kind of system, but that's going a little overboard at this point. (though, with some bend sensors and some potentiometers I could probably create a decent control system)
So, let me know what you guys think! And, yeah... I don't have an accelerometer yet. Bought one today though, so it should be here with in the week.