'Unity Rotate Camera by Gyroscope and Touch Swipe

I'm building a 360 video viewer in Unity where i want to add the ability of swiping the screen to look around the Y-axis plus to use the gyroscope of the smartphone to look around. Both scripts already work independently but i've not managed it to combine both yet. It seems like one script always overwrite the other script.


The gyroscope script:

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

public class GyroControls : MonoBehaviour {

    private bool gyroEnabled;
    private Gyroscope gyro;

    private GameObject cameraContainer;
    private Quaternion rot;

    private void Start()
    {
        cameraContainer = new GameObject("Camera Container");
        cameraContainer.transform.position = transform.position;
        transform.SetParent(cameraContainer.transform);

        gyroEnabled = EnableGyro();
    }

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

            cameraContainer.transform.rotation = Quaternion.Euler(90f, 90f, 0f);
            rot = new Quaternion(0, 0, 1, 0);

            return true;
        }

        return false;
    }

    private void Update()
    {
        if(gyroEnabled)
        {
            transform.localRotation = gyro.attitude * rot;
        }
    }
}


The Y rotation script:

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

public class RotateCameraByTouchYOnly : MonoBehaviour
{

    private Touch initTouch = new Touch();
    public Camera cam;

    private float rotX = 0f;
    private float rotY = 0f;
    private Vector3 origRot;

    public float rotSpeed = 0.5f;
    public float dir = -1;


    void Start()
    {
        origRot = cam.transform.eulerAngles;
        rotX = origRot.x;
        rotY = origRot.y;
    }


    void FixedUpdate()
    {
        foreach (Touch touch in Input.touches)
        {
            if (touch.phase == TouchPhase.Began)
            {
                initTouch = touch;
            }
            else if (touch.phase == TouchPhase.Moved)
            {
                //swiping
                float deltaX = initTouch.position.x - touch.position.x;
                float deltaY = initTouch.position.y - touch.position.y;
                rotX -= deltaY * Time.deltaTime * rotSpeed * dir;
                rotY += deltaX * Time.deltaTime * rotSpeed * dir;
                cam.transform.eulerAngles = new Vector3(0f, rotY, 0f);
            }
            else if (touch.phase == TouchPhase.Ended)
            {
                initTouch = new Touch();
            }
        }
    }

}



Thank's a lot for your help! :)



Solution 1:[1]

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

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;
    }
}
}

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);
}
}

Here is a sample project with the solution: https://github.com/danieldourado/gyroscope-touch-camera-rotation

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1