- Home /
Recalibrated 'zero' point for Input.acceleration messes up when goes to upside-down
My issue is a little hard to explain, but I'll try. In my game you control a ball by tilting the phone. Simple code. The problem comes with the recalibration option in the game.
If Recalibration Mode is enabled, the player holds the phone in the position they want to be the 'flat' position, then touches the screen to start. Doing that calls this code:
public void InitializeAxis () {
offsetX = Input.acceleration.x;
offsetY = Input.acceleration.y;
offsetZ = Input.acceleration.z;
}
Basically, the calculations that normally go into adding force to the ball simply subtract the offset value. This makes it so any position can be the 'flat' position, and all of the movements are based on the relativity to that position.
It works great, but there is a HUGE flaw with it. I've been working on it nonstop for over 5 hours today, and I've pretty much given up. This is the problem: once the phone is 'flipped' into an upside down position (basically indicated by the Z value becoming positive instead of negative), ball flies off the stage erratically.
I thought I had it figured out, because the X and Y accelerometer values basically get to 1 or -1 once it reaches it's peak, then starts counting back to zero. I somewhat figured out how to solve that problem...at least I thought I did. Here's what my code looks like for when the phone was started screen-side-up:
else { // phone started screen side up (z was negative)
if (Input.acceleration.z <= 0) { // if it's still screen side up, process normally
x = Input.acceleration.x - offsetX;
y = Input.acceleration.y - offsetY;
movement = new Vector3(x, 0.0f, y);
}
else { // now it's screen side down (z is positive now)
if (Input.acceleration.x >= 0) {
x = (2 - Input.acceleration.x) - offsetX;
}
else {
x = (-2 - Input.acceleration.x) - offsetX;
}
if (Input.acceleration.y >= 0) {
y = (2 - Input.acceleration.y) - offsetY;
}
else {
y = (-2 - Input.acceleration.y) - offsetY;
}
movement = new Vector3(x, 0.0f, y);
}
}
rigidbody.AddForce(movement * speed * Time.deltaTime);
}
Here's the big problem: say, for example I tilt the top of the phone upward towards me (Y axis going down, ball rolling down on the screen). Once it reaches the point where it's facing directly toward me, phone 'standing' upright, and I pass that threshold where the phone has now become upside-down (Z axis has become positive instead of negative), the Y value is fine. Because of the code, it basically just adds how far it's moved past that threshold to the value.
But then, the X value just gets incredibly close to 2, flailing the ball of the stage. It's almost like I need some way to tell which axis actually pushed it over that threshold. If I could do that, I could solve it (say the Y made it flip over; I could just do: x = Input.acceleration.x * -1; and everything would be fine).
I feel like there is some incredibly simple solution to this, and I'm just overthinking it. Or maybe it really is a problem, and I need a mathmegician to figure it out for me.
I know this was a long explanation, but it's 5:30 a.m. and I am incredibly frustrated and exhausted after a night of trying to solve this one silly problem. Ask any questions you might have, or tell me if you need any information. Just please help me!