Unable to recalibrate accelerometer to the initial angle of device, so that it doesn't need to be flat.

I have an object being controlled by the accelerometer. However, my device needs to be really flat and hence it is uncomfortable to play. The following is the code I have but it has issues I’m unable to fix.

	Vector3 dir = new Vector3 (Input.acceleration.x, Input.acceleration.y, 0.0f);
		if (dir.sqrMagnitude > 1)
			dir.Normalize();
		dir *= Time.deltaTime;
		transform.Translate(dir * speed);
		
		float inputX = Input.acceleration.x;
		float inputY = Input.acceleration.y;
		
		anim.SetFloat ("SpeedX", inputX);
		anim.SetFloat ("SpeedY", inputY);

		Vector3 recalDir = new Vector3 (Input.acceleration.x - inputX; Input.acceleration.y - inputY; 0.0f);
		if (recalDir.sqrMagnitude > 1)
			recalDir.Normalize();

It sounds like you want to counter-rotate your accelerometer values to adjust for what the player finds to be a comfortable “neutral” pose:

// Play with the "neutralPitch" value until you find one that feels right.
// Or you can adjust it over time to adapt to the player's (changing) pose.
Quaternion accelerometerAdjustment = Quaternion.Euler(neutralPitch, 0f, 0f);

// Each time you want to read the acceleration:
Vector3 adjustedAcceleration = accelerometerAdjustment * Input.acceleration;

float inputX = adjustedAcceleration.x;
float inputY = adjustedAcceleration.y;

// Now you can proceed as before.

Note that raw accelerometer values can be noisy - small linear accelerations like flinches/shivers or device vibration can show up as spikes, polluting the tilt information you get from gravity. You might find that Input.gyro.attitude or Input.gyro.gravity give you a more stable steering input, since they use the device’s other sensors in addition to the accelerometer.

I’m not sure what you’re doing with the recalDir at the bottom. It looks like it will always be a zero vector, since you’re subtracting Input.acceleration.x from itself, and similarly for y.

Managed to get it to work with a different code from the Unity forums. Here it is:

    Matrix4x4 calibrationMatrix;
 
    void calibrateAccelerometer(){
       Vector3 wantedDeadZone = Input.acceleration;;
       Quaternion rotateQuaternion = Quaternion.FromToRotation(new Vector3(0f, 0f, -1f), wantedDeadZone);
       //create identity matrix ... rotate our matrix to match up with down vec
       Matrix4x4 matrix = Matrix4x4.TRS(Vector3.zero, rotateQuaternion, new Vector3(1f, 1f, 1f));
       //get the inverse of the matrix
       this.calibrationMatrix = matrix.inverse;
       }
 
    Vector3 getAccelerometer(Vector3 accelerator){
       Vector3 accel = this.calibrationMatrix.MultiplyVector(accelerator);
       return accel;
       }
 
    void Start(){
       calibrateAccelerometer();
        }
 
    void Update(){ 
    Vector3 dir = getAccelerometer(Input.acceleration);
    if (dir.sqrMagnitude > 1)
       dir.Normalize();
       dir *= Time.deltaTime;
       transform.Translate(dir * speed);
    }