- Home /
Camera rotation with gyroscope + drag/swipe
I want to emulate the effect of 360 images where you can rotate in your mobile device with the gyroscope but also with the users touch input.
I have two scripts working separately but when I attached them to the camera they have problems. I think this is because of the fact that the gyro movement script is checking the rotation relative to the device position on each update and its not allowing the drag input to change the view.
Portion for moving with user swipe:
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;
Mathf.Clamp(rotX, -45f, 45f);
cam.transform.eulerAngles = new Vector3(rotX, rotY, 0f);
}
Portion of the other script for gyro movement
protected void Update()
{
if (!gyroEnabled)
return;
transform.rotation = Quaternion.Slerp(transform.rotation,
cameraBase * ( ConvertRotation(referanceRotation * Input.gyro.attitude) * GetRotFix()), lowPassFilterFactor);
}
Answer by danieldourado_2 · Mar 17, 2019 at 03:04 AM
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: https://github.com/danieldourado/gyroscope-touch-camera-rotation
Hi, my touch rotation script looks a bit differently from the one you have, I have been trying to figure it out but the absolute value vs differential value is confusing as I am using quaternions. This is what my script looks like, Can you advise?
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; public class MouseLook : MonoBehaviour { public float mouseSensitivity = 100f; public Transform playerBody; float xRotation; // Start is called before the first frame update void Start() { } // Update is called once per frame void Update() { float mouseX = 0; float mouseY = 0; if(Input.touchCount >0 && Input.GetTouch(0).phase == TouchPhase.Moved) { if (EventSystem.current.IsPointerOverGameObject(Input.GetTouch(0).fingerId)) return; mouseX = Input.GetTouch(0).deltaPosition.x; mouseY = Input.GetTouch(0).deltaPosition.y; } mouseX *= mouseSensitivity; mouseY *= mouseSensitivity; xRotation -= mouseY * Time.deltaTime; xRotation = Mathf.Clamp(xRotation, -80, 80); transform.localRotation = Quaternion.Euler(xRotation, 0, 0); playerBody.Rotate(Vector3.up * mouseX * Time.deltaTime); } }
Answer by VRARAPPS · Sep 20, 2017 at 05:32 PM
Have u got the answer ?
have u got solution for that?. i am also doing that king of stuff please help me if u know
@ImDev See If its working..
private Vector3 mouseOrigin;
private bool isRotating;
void Update ()
{
if(Input.Get$$anonymous$$ouseButtonDown(0))
{
// Get mouse origin
mouseOrigin = Input.mousePosition;
isRotating = true;
}
if (!Input.Get$$anonymous$$ouseButton(0)) isRotating=false;
if (isRotating)
{
Vector3 pos = Camera.main.ScreenToViewportPoint(Input.mousePosition - mouseOrigin);
//transform.RotateAround(transform.position, transform.right, -pos.y * turnSpeed); //around x
transform.RotateAround(transform.position, Vector3.up, pos.x * turnSpeed); // around y
}
}