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+"\nyAngle:"+yAngle+"\ngyroX:"+Input.gyro.attitude.x+"\ngyroY:"+Input.gyro.attitude.y+"\ngyroZ"+Input.gyro.attitude.z+"\nDeltaX:"+deltaX+"\nDeltaY"+deltaY+"\nprevGyroX:"+prevGyroX+"\nprevGyroY"+prevGyroY+"\ngyroz:"+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?
Answer by danieldourado_2 · Mar 17, 2019 at 03:03 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
Answer by GroznyBear · Mar 01, 2018 at 01:16 PM
The easiest way is to place camera controlled by gyro under the empty gameobject and rotate that empty gameobject with touch input.
Your answer
Follow this Question
Related Questions
how to make tilt view 0 Answers
Problems with gyro camera rotation. 0 Answers
Rotate camera like VR on mobile 3 Answers
Multi-display Mac Big Sur and Android Touch display 0 Answers
Unity3D accelerometer camera rotation realistic controls 0 Answers