Accelerometer issue with calibration.
Hey everyone :)
I've got a problem with calibrating my accelerometer for my game.
My code is as follows :
Vector3 tilt = Vector3.zero;//variable for accelerometer
Vector3 calibratedtilt = Vector3.zero;
public void Calibrate()
{
//Gets devices physical rotation in 3D space
calibratedtilt.x = Input.acceleration.x;
calibratedtilt.y = 0;
calibratedtilt.z = Input.acceleration.z;
}
void FixedUpdate()
{
//Accelerometer
//get input from accelerometer
tilt.x = Input.acceleration.x - calibratedtilt.x;//left and right
tilt.y = 0;//up and down
tilt.z = -Input.acceleration.z + calibratedtilt.z;//forward and backward
//add force
rb.AddForce(tilt * sensitivity);
}
The calibration works really well except for one strange issue I cannot for all the oxygen in my lunges figure out why..
When you move the ball forward (tilt the phone over 45 degrees *roughly) it comes to a halt and goes in the opposite direction (backwards)
Take note it doesn't happen when going from side to side, instead it increases in speed the more you tilt, which is what I want when moving forward and backward
I removed the calibration functionality completely, and as expected, It works the way it should.
So the issue has to be with how I implement it.
I checked the phones readings with logs, and it seems fine when you calibrate which sets the axis to 0, 0, 0.
Answer by codex97dev · Nov 30, 2017 at 06:38 PM
Managed to fix it myself, for those in need of help in the future...
1) WHY DOES IT HAPPEN ??? When your phone reaches the rotation of 0,0,0 it will go in the opposite direction regardless of how your phone is oriented through calibration. Take note if your phone is upside down it's also 0,0,0.
2) THE FIX After calibrating my phone, I rotated the x -axis by 90 degrees so that it adds it to your calibrated value, therefore never (theoretically) reach the tipping point of changing the balls direction.
Here is my code for reference :
public class PlayerController : MonoBehaviour {
private Rigidbody rb;
private int count; //score
public GameObject respawn; //respawn object
public Text scoreText;
public float sensitivity = 20.0f; //sensitivity
public AudioSource audioSource;
Vector3 tilt = Vector3.zero;//variable for accelerometer
Vector3 calibratedtilt = Vector3.zero;
//Game objects for UI elements
public GameObject PauseMenu;
public GameObject Pausebtn;
public GameObject Calibtn;
public int score = 0;
void Start()
{
Screen.orientation = ScreenOrientation.LandscapeRight;
Input.gyro.enabled = true;
Calibrate();
rb = GetComponent<Rigidbody>();
Time.timeScale = 0;
Pausebtn.SetActive(false);
setScoreText();
}
public void Calibrate()
{
//Gets devices physical rotation in 3D space
calibratedtilt.x = Input.acceleration.x;
calibratedtilt.y = Input.acceleration.y;
calibratedtilt.z = Input.acceleration.z;
}
public void FirstCalibrate() //Forces player to calibrate at beginning of level
{
Pausebtn.SetActive(true);
Calibtn.SetActive(false);
Calibrate();
Time.timeScale = 1;
}
void FixedUpdate()
{
//Accelerometer
//get input from accelerometer
tilt.x = Input.acceleration.x - calibratedtilt.x;
tilt.y = Input.acceleration.y - calibratedtilt.y;
tilt.z = -Input.acceleration.z - calibratedtilt.z;
tilt = Quaternion.Euler(90, 0, 0) * tilt;
rb.AddForce(tilt * sensitivity);
//Touch input and stop
if (Input.touchCount > 0) //check for touches
{
Touch[] myTouches = Input.touches;
for(int i = 0; i < Input.touchCount; i++)
{
//stop
rb.velocity = Vector3.zero;
rb.angularVelocity = Vector3.zero;
}
}
}
}
Hopefully this saves someone's sanity in the future :)
Your answer
![](https://koobas.hobune.stream/wayback/20220612143612im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
Is it possible to access the native step-counter on mobile platforms. 2 Answers
How to pause accelerometer movement 1 Answer
How can I change controls to a accelerometer for mobile 1 Answer
How do i limit my accelerometer movement 1 Answer
Getting linear acceleration not using gyroscope on Android 2 Answers