How do I use both touch and gyro to transform rotate the camera?

I have written a script to rotate the camera with respect the gyro. As well as when panned using touch.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;


public class WithoutBox : MonoBehaviour {

	private Vector3 firstpoint; //change type on Vector3
	private Vector3 secondpoint;
	private float xAngle = (float) 0.0; //angle for axes x for rotation
	private float yAngle = (float) 0.0;
	private float xAngTemp = (float) 0.0; //temp variable for angle
	private float yAngTemp = (float) 0.0;
	private float deltaX = (float) 0.0;
	private float deltaY = (float) 0.0;
	public Text text;
	private float prevGyroY = 0.0f;
	private float prevGyroX = 0.0f;
	private float prevGyroZ = 0.0f;
	private bool flagTouched = false;


	public Camera m_Camera;
	// Use this for initialization
	void Start () {
		//Initialization our angles of camera
		xAngle = (float) 0.0;
		yAngle = (float) 0.0;
		this.transform.rotation = Quaternion.Euler(yAngle, xAngle, (float) 0.0);

	}
	
	// Update is called once per frame
	void Update () {
		if (Input.touchCount > 0) {
			//Touch began, save position
			if (Input.GetTouch (0).phase == TouchPhase.Began) {
				firstpoint = Input.GetTouch (0).position;
				xAngTemp = prevGyroY - deltaY;
				yAngTemp = prevGyroX - deltaX;
			}
			//Move finger by screen
			if (Input.GetTouch (0).phase == TouchPhase.Moved) {
				flagTouched = true;
				secondpoint = Input.GetTouch (0).position;
				//Mainly, about rotate camera. For example, for Screen.width rotate on 180 degree
				xAngle = xAngTemp + (firstpoint.x - secondpoint.x) *(float) 180.0 / Screen.width;
				yAngle = yAngTemp - ( firstpoint.y - secondpoint.y) *(float) 90.0 / Screen.height;

				//Rotate camera
				this.transform.rotation = Quaternion.Euler (yAngle, xAngle,(float) 0.0);
			}
		} else {
		    //m_Camera.transform.rotation = Quaternion.Euler (90.0f, 0.0f, 0.0f) * new Quaternion (Input.gyro.attitude.x, Input.gyro.attitude.y, -Input.gyro.attitude.z, -Input.gyro.attitude.w);
			Quaternion q =  Quaternion.Euler (0.0f, 0.0f, 0.0f) * new Quaternion (Input.gyro.attitude.x, Input.gyro.attitude.y, -Input.gyro.attitude.z, -Input.gyro.attitude.w);
			prevGyroY = q.eulerAngles.y;
			prevGyroX = q.eulerAngles.x;
			prevGyroZ = q.eulerAngles.z;
			if (flagTouched) {
				deltaX = prevGyroX + yAngle;
				deltaY = prevGyroY + xAngle;
				flagTouched = false;
			}
			q.eulerAngles.Set (prevGyroX - deltaX, prevGyroY - deltaY, prevGyroZ);
			m_Camera.transform.rotation = q;
		}
		text.text = "xAngle:"+xAngle+"

yAngle:“+yAngle+”
gyroX:“+Input.gyro.attitude.x+”
gyroY:“+Input.gyro.attitude.y+”
gyroZ"+Input.gyro.attitude.z+"
DeltaX:“+deltaX+”
DeltaY"+deltaY+"
prevGyroX:“+prevGyroX+”
prevGyroY"+prevGyroY+"
gyroz:"+prevGyroZ;
}
}

When I pan using touch the camera rotates perfectly but it doesn’t stay there. I’ve been staring at this code from the past two days wasn’t able to crack it. Is there anyone out there who can?

It can be done using one script to turn the camera using touch, and another script to turn the camera using the gyroscope.

BasicCameraRotation .cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class BasicCameraRotation : MonoBehaviour
{
    public void RotateUpDown(float axis)
    {
        transform.RotateAround(transform.position, transform.right, -axis * Time.deltaTime);
    }

    //rotate the camera rigt and left (y rotation)
    public void RotateRightLeft(float axis)
    {
        transform.RotateAround(transform.position, Vector3.up, -axis * Time.deltaTime);
    }
}

GyroscopeCameraRotation.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GyroscopeCameraRotation : BasicCameraRotation
{
    private float x;
    private float y;

    public bool gyroEnabled = false;
    readonly float sensitivity = 50.0f;

    private Gyroscope gyro;

    void Start()
    {
        gyroEnabled = EnableGyro();
    }

    private bool EnableGyro()
    {
        if (SystemInfo.supportsGyroscope)
        {
            gyro = Input.gyro;
            gyro.enabled = true;
            return true;
        }

        return false;
    }
    void Update()
    {
        if (gyroEnabled)
        {
            GyroRotation();
        }
    }
    void GyroRotation()
    {
        x = Input.gyro.rotationRate.x;
        y = Input.gyro.rotationRate.y;

        float xFiltered = FilterGyroValues(x);
        RotateUpDown(xFiltered*sensitivity);

        float yFiltered = FilterGyroValues(y);
        RotateRightLeft(yFiltered * sensitivity);
    }

    float FilterGyroValues(float axis)
    {
        if (axis < -0.1 || axis > 0.1)
        {
            return axis;
        }
        else
        {
            return 0;
        }
    }
}

TouchCameraRotation.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TouchCameraRotation : BasicCameraRotation
{
    Vector3 firstPoint;
    float sensitivity = 2.5f;

    void Update()
    {
       TouchRotation();
    }
    void TouchRotation()
    {
        if (Input.touchCount > 0)
        {
            if (Input.GetTouch(0).phase == TouchPhase.Began)
            {
                firstPoint = Input.GetTouch(0).position;
            }
            if (Input.GetTouch(0).phase == TouchPhase.Moved)
            {
                Vector3 secondPoint = Input.GetTouch(0).position;

                float x = FilterGyroValues(secondPoint.x - firstPoint.x);
                RotateRightLeft(x * sensitivity);

                float y = FilterGyroValues(secondPoint.y - firstPoint.y);
                RotateUpDown(y * -sensitivity);

                firstPoint = secondPoint;
            }
        }
    }
    float FilterGyroValues(float axis)
    {
        float thresshold = 0.5f;
        if (axis < -thresshold || axis > thresshold)
        {
            return axis;
        }
        else
        {
            return 0;
        }
    }
}

Here is a sample project with the solution: GitHub - danieldourado/gyroscope-touch-camera-rotation: Enables your camera to rotate using the gyroscope and touch at the same time

Did you solve this problem?

The easiest way is to place camera controlled by gyro under the empty gameobject and rotate that empty gameobject with touch input.