The goal:
No physics flying object rotating around it’s local z and x axis based on joystick input. So if I pull back, it goes back by a fixed angle. If I push right, it rolls right by fixed angle increments. I don’t want to use forces since I want the controls to feel very “tight” without having to counteract all the forces to straighten out the object.
The problem:
I can get it to work along their independent axis. If I push only right at the start, it rotates correctly. If I push only back, it does it correctly. When I start combining the two (doing a bank turn for example) it all goes wack.
I’ve been hammering away for a while trying to get this to work right, but it just doesn’t seem to want to work as expected. For some reason when the transform’s “forward” is no longer along the z plane, pulling back has very different behavior than just pulling back. Gifs for reference (you’ll note in the second gif, I get off the x and z plane, and when pulling straight back or forward, left or right (values at bottom left of recording) the square moves completely off axis.):
Irregular movements when two axis are combined
The code:
public Rigidbody body;
public int SPEED = 20;
public float tiltAngle = .5f;
public Text debugText;
private float previousX;
private float previousY;
private float previousZ;
....
void FixedUpdate() {
Vector3 forward = body.transform.forward;
Vector3 right = body.transform.right;
// static forward movement (working fine)
body.velocity = new Vector3(SPEED * forward.x, SPEED * forward.y, SPEED * forward.z);
// Inverse tilt angle so it matches with roll left - left on thumbstick
float tiltAroundZ = Input.GetAxis("Horizontal") * -tiltAngle;
float tiltAroundX = Input.GetAxis("Vertical") * tiltAngle;
// Modifying tilt around axis to be relative to transforms local axis by
// using it's identity vectors. Likely where the issue is.
previousX += (tiltAroundX * right.x) + (tiltAroundZ * forward.x);
previousY += (tiltAroundX * right.y) + (tiltAroundZ * forward.y);
previousZ += (tiltAroundX * right.z) + (tiltAroundZ * forward.z);
Quaternion target = Quaternion.Euler(previousX, previousY, previousZ);
// Removed slerp since I felt the imprecision might build up from it's actual position
// and the previous x/y/z. Am I wrong in this assumption?
transform.rotation = target;
}