- Home /
Match the tilted angle of phone to object.
I am trying to link the accelerometer to the angle of an object. This is my code.
function Update () { iphoney=Input.acceleration.y; transform.Rotate(Vector3.forward*iphoney*5.0); }
The problem with this code is the object keeps rotating and is not linked to the phones angle. I need the angle of the object be directly linked to the angle of the phones accelerometer.
Thanks
when holding the android device face-up and titling it right and left, the object does not move only right and left, it also moves a little bit diagonal (up/down). can someone help improve the code so it rotates the object exactly according to the rotation of the android device even when the device is face-up and tilted right/left?
I created a new post with more info and additional scripts. I'm really looking for an answer for this. Any help will be greatly appreciated: http://answers.unity3d.com/questions/1077995/rotate-object-by-tilting-android-device-any-angle.html
Answer by aldonaletto · Jul 04, 2011 at 02:29 PM
You can just set the transform.up vector to the acceleration direction:
transform.up = -(Input.acceleration.normalized);
This will incline the object to be always parallel to the ground, but the object will also be temporarilly tilted when moved horizontally - the accelerometer senses any kind of acceleration, not only gravity. Getting its Y coordinate alone doesn't not work: the Y value is always measured relative to the iPhone Y axis; if you tilt it 90° around the Z axis, for instance, the gravity will be aligned to the iPhone X axis, and the Y value will be close to zero.
EDITED: The accelerometer has some level of electrical noise, as any real world sensor. You can smooth its output using a Moving Average filter. This filter keeps the last N values in an array, and returns their averaged value. The function MovAverage(sample) below does the job. You supply a new accelerometer reading and it returns the average of the last sizeFilter samples. The larger the sizeFilter value, the larger the smooth effect. If sizeFilter = 25 and the function is called each 20mS (as in FixedUpdate), the values returned will be the last 0.5s average value. You can also call it in Update, but if the FPS changes the smoothing will change in the inverse proportion, and in extreme cases you may have to adjust sizeFilter (it can't be changed at runtime).
private var sizeFilter: int = 15;
private var filter: Vector3[];
private var filterSum = Vector3.zero;
private var posFilter: int = 0;
private var qSamples: int = 0;
function MovAverage(sample: Vector3): Vector3 {
if (qSamples==0) filter = new Vector3[sizeFilter];
filterSum += sample - filter[posFilter];
filter[posFilter++] = sample;
if (posFilter > qSamples) qSamples = posFilter;
posFilter = posFilter % sizeFilter;
return filterSum / qSamples;
}
You can use in Update or FixedUpdate this way:
transform.up = -MovAverage(Input.acceleration.normalized);
Thanks, this works well except the object is a bit unstable. i jumps around a bit, is there any way to smooth out the movement.
@Richard 3, I edited the answer and included a moving average filter in order to smooth the accelerometer output.
How would I go about locking the rotation to one axis only? I locked two of the axis under Ridged body / Freeze Rotation, this did nothing. Thanks
FreezeRotation only affects the physics effects. You can limit rotation to one axis by clearing the corresponding coordinate. If you want to enable rotation around the X axis only, zero the X coordinate:
var temp: Vector3 = -$$anonymous$$ovAverage(Input.acceleration.normalized);
temp.x = 0; // rotate around x axis only
transform.up = temp.normalized;
You don't need to worry about Y rotation, since you're setting the up vector.
Your answer
Follow this Question
Related Questions
Issues with accelerometer calibration? 1 Answer
Mapping accelerometer to Camera's position 2 Answers
Calabrate Accelerometer 1 Answer
Accelerometer - accounting for gravity for arbitrary device angle 1 Answer
Accelerometer question 1 Answer