- Home /
Adapting camera movement to touch input
Hello, I've been learning about how to develop for mobile lately. I have a script very similar to Unity's standard FPS MouseLook Script and wanted to add limited camera rotation by tapping and dragging. I had this working for standard Mouse controls, but I just hacked together a way to get the touch controls somewhat working (incorrectly) but that seems to have caused issues with the mouse controls as well. The touch controls are also not translating well into rotating the camera and is giving me very awkward angles. I'm not sure exactly what to do about all of this. Here's my code.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(CameraRig))]
public class MousePOV : MonoBehaviour {
public float XSensitivity = 2f;
public float YSensitivity = 2f;
public bool clampVerticalRotation = true;
public float MinimumX = -90F;
public float MaximumX = 90F;
public bool smooth;
public float smoothTime = 5f;
public bool lockCursor = true;
private Quaternion yAxis;
private Quaternion xAxis;
private bool m_cursorIsLocked = true;
private CameraRig rig;
void Start () {
rig = GetComponent<CameraRig> ();
}
void Update() {
//Mouse Version. Used to work fine
if(Input.GetMouseButton(0) && (Input.GetAxis ("Mouse X") != 0 || Input.GetAxis ("Mouse Y") != 0)){
yAxis = rig.y_axis.localRotation;
xAxis = rig.x_axis.localRotation;
LookRotation ();
}
//Touch Screen Version. Controls don't work very well.
if (Input.touchCount == 1) {
Touch touch = Input.GetTouch(0);
xAxis = Quaternion.Euler (0f, (touch.position.y*0.10f),0);
yAxis = Quaternion.Euler ((touch.position.x*0.10f), 0f,0);
LookRotation ();
}
}
public void LookRotation()
{
float yRot = Input.GetAxis("Horizontal") * XSensitivity;
float xRot = Input.GetAxis("Vertical") * YSensitivity;
yAxis *= Quaternion.Euler (0f, yRot, 0f);
xAxis *= Quaternion.Euler (-xRot, 0f, 0f);
if(clampVerticalRotation)
xAxis = ClampRotationAroundXAxis (xAxis);
if(smooth)
{
rig.y_axis.localRotation = Quaternion.Slerp (rig.y_axis.localRotation, yAxis,
smoothTime * Time.deltaTime);
rig.x_axis.localRotation = Quaternion.Slerp (rig.x_axis.localRotation, xAxis,
smoothTime * Time.deltaTime);
}
else
{
rig.y_axis.localRotation = yAxis;
rig.x_axis.localRotation = xAxis;
}
UpdateCursorLock();
}
public void SetCursorLock(bool value)
{
lockCursor = value;
if(!lockCursor)
{//we force unlock the cursor if the user disable the cursor locking helper
Cursor.lockState = CursorLockMode.None;
Cursor.visible = true;
}
}
public void UpdateCursorLock()
{
//if the user set "lockCursor" we check & properly lock the cursos
if (lockCursor)
InternalLockUpdate();
}
private void InternalLockUpdate()
{
if(Input.GetKeyUp(KeyCode.Escape))
{
m_cursorIsLocked = false;
}
else if(Input.GetMouseButtonUp(0))
{
m_cursorIsLocked = true;
}
if (m_cursorIsLocked)
{
Cursor.lockState = CursorLockMode.Locked;
Cursor.visible = false;
}
else if (!m_cursorIsLocked)
{
Cursor.lockState = CursorLockMode.None;
Cursor.visible = true;
}
}
Quaternion ClampRotationAroundXAxis(Quaternion q)
{
q.x /= q.w;
q.y /= q.w;
q.z /= q.w;
q.w = 1.0f;
float angleX = 2.0f * Mathf.Rad2Deg * Mathf.Atan (q.x);
angleX = Mathf.Clamp (angleX, MinimumX, MaximumX);
q.x = Mathf.Tan (0.5f * Mathf.Deg2Rad * angleX);
return q;
}
}
Any ideas?
What I usually do is shove a joystick somewhere. Basically, the position of the current touch relative to the center of the joystick can be turned in to x/y vectors, which give you your horizontal/vertical input, which is then applied the same way as you would with arrow keys or an actual joystick.