How to detect finger drag on either x or y axis for mobile? - unity3d

Anyway to get or recreate this type of input control for mobile touch, I essentially instead of detecting mouse drag on the y I want to detect finger drag on the y, and well honestly x too? Would I have to do this via script and if so what would the code be for that?
Input Manager Mouse Y, but I want finger Y ha :'D

This code is for both drag(pan) and zooming.
I used this code for my game
using UnityEngine;
using UnityEngine.EventSystems;
public class PanZoom : MonoBehaviour
{
Vector3 touchStart;
// Minimum amount pan to move camera
public float panMinX = 2f;
public float panMinY = 2f;
// Minimum and Maximum zoom amount for camera
public float zoomOutMin = 5f;
public float zoomOutMax = 20f;
// Scroll speed of zoom of camera
public float scrollSpeed = 5f;
void Update()
{
if (Input.GetMouseButtonDown(0) && !EventSystem.current.IsPointerOverGameObject())
{
touchStart = Camera.main.ScreenToWorldPoint(Input.mousePosition);
}
#if UNITY_STANDALONE || UNITY_EDITOR || UNITY_WEBGL
if (Input.GetMouseButton(0) && !EventSystem.current.IsPointerOverGameObject())
{
Vector3 direction = touchStart - Camera.main.ScreenToWorldPoint(Input.mousePosition);
if (Mathf.Abs(direction.x) > panMinX || Mathf.Abs(direction.y) > panMinY)
if (!CameraMovement.Instance.IsCameraInBorder)
{
Camera.main.transform.position += direction;
}
}
Zoom(Input.GetAxis("Mouse ScrollWheel") * scrollSpeed);
#endif
#if UNITY_ANDROID || UNITY_IOS
if (Input.touchCount == 2 && !EventSystem.current.IsPointerOverGameObject())
{
Touch touchZero = Input.GetTouch(0);
Touch touchOne = Input.GetTouch(1);
Vector2 touchZeroPrevPosition = touchZero.position - touchZero.deltaPosition;
Vector2 touchOnePrevPosition = touchOne.position - touchOne.deltaPosition;
float prevMagnitude = (touchZeroPrevPosition - touchOnePrevPosition).magnitude;
float currentMagnitude = (touchZero.position - touchOne.position).magnitude;
float difference = currentMagnitude - prevMagnitude;
Zoom(difference * 0.01f);
}
else if (Input.GetMouseButton(0) && !EventSystem.current.IsPointerOverGameObject())
{
Vector3 direction = touchStart - Camera.main.ScreenToWorldPoint(Input.mousePosition);
if (Mathf.Abs(direction.x) > panMinX || Mathf.Abs(direction.y) > panMinY)
Camera.main.transform.position += direction;
}
#endif
}
void Zoom(float increment)
{
if(!EventSystem.current.IsPointerOverGameObject())
Camera.main.orthographicSize = Mathf.Clamp(Camera.main.orthographicSize - increment, zoomOutMin, zoomOutMax);
}
}

Related

Unity3D. C#. Can can i add max and min values to zoom in this code?

In the 3D project I have script and i can rotate/move in the scene without doubts, but i have problem with Zoom, i can do this too close and soo far. I zoom it right to the floor or to far away to sky and i stack then. I use perspective camera.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
class ScrollAndPinch : MonoBehaviour
{
public Camera Camera;
public bool Rotate;
protected Plane Plane;
private void Awake()
{
if (Camera == null)
Camera = Camera.main;
}
private void Update()
{
//Update Plane
if (Input.touchCount >= 1)
Plane.SetNormalAndPosition(transform.up, transform.position);
var Delta1 = Vector3.zero;
var Delta2 = Vector3.zero;
//Scroll
if (Input.touchCount >= 1)
{
Delta1 = PlanePositionDelta(Input.GetTouch(0));
if (Input.GetTouch(0).phase == TouchPhase.Moved)
Camera.transform.Translate(Delta1, Space.World);
}
//Pinch
if (Input.touchCount >= 2)
{
var pos1 = PlanePosition(Input.GetTouch(0).position);
var pos2 = PlanePosition(Input.GetTouch(1).position);
var pos1b = PlanePosition(Input.GetTouch(0).position - Input.GetTouch(0).deltaPosition);
var pos2b = PlanePosition(Input.GetTouch(1).position - Input.GetTouch(1).deltaPosition);
//calc zoom
var zoom = Vector3.Distance(pos1, pos2) /
Vector3.Distance(pos1b, pos2b);
//edge case
if (zoom == 9 || zoom > 10)
return;
//Move cam amount the mid ray
Camera.transform.position = Vector3.LerpUnclamped(pos1, Camera.transform.position, 1 / zoom);
if (Rotate && pos2b != pos2)
Camera.transform.RotateAround(pos1, Plane.normal, Vector3.SignedAngle(pos2 - pos1, pos2b - pos1b, Plane.normal));
}
}
protected Vector3 PlanePositionDelta(Touch touch)
{
//not moved
if (touch.phase != TouchPhase.Moved)
return Vector3.zero;
//delta
var rayBefore = Camera.ScreenPointToRay(touch.position - touch.deltaPosition);
var rayNow = Camera.ScreenPointToRay(touch.position);
if (Plane.Raycast(rayBefore, out var enterBefore) && Plane.Raycast(rayNow, out var enterNow))
return rayBefore.GetPoint(enterBefore) - rayNow.GetPoint(enterNow);
//not on plane
return Vector3.zero;
}
protected Vector3 PlanePosition(Vector2 screenPos)
{
//position
var rayNow = Camera.ScreenPointToRay(screenPos);
if (Plane.Raycast(rayNow, out var enterNow))
return rayNow.GetPoint(enterNow);
return Vector3.zero;
}
private void OnDrawGizmos()
{
Gizmos.DrawLine(transform.position, transform.position + transform.up);
}
}
Sorry for noob question, i've recently started to my journey in unity3D.
How can i set the limits here?
If you mean you want to limit the zoom within a single pinch operation you could probably do e.g.
// Configure these in the Inspector
[SerializeField] private float minZoom = 0.1f;
[SerializeField] private float maxZoom = 10f;
...
var zoom = Vector3.Distance(pos1, pos2) / Vector3.Distance(pos1b, pos2b);
zoom = Mathf.Clamp(minZoom, maxZoom);
...
If you ment you rather want to limit the overall combined zoom you'll have to store and combine the zoom amounts like e.g.
private float finalZoom = 1;
...
var zoom = Vector3.Distance(pos1, pos2) / Vector3.Distance(pos1b, pos2b);
finalZoom *= zoom;
finalZoom = Mathf.Clamp(minZoom, maxZoom);
// And from here use finalZoom instead of zoom
Camera.transform.position = Vector3.LerpUnclamped(pos1, Camera.transform.position, 1 / finalZoom);
...
The answer is to use https://docs.unity3d.com/ScriptReference/Mathf.Clamp.html
Mathf.Clamp(xValue, xMin, xMax);

Joystick controls mixed with rotation

I have a problem with the Fixed joystick when I apply rotation to the main camera. The controls are mixed. How can I resolve this problem? Do I need to use other type of joystick? Where I should put "-" ? in front of which number
using System.Collections.Generic;
using UnityEngine;
[AddComponentMenu("Camera-Control/Mouse Look")]
public class MouseLook : MonoBehaviour
{
public enum RotationAxes { MouseXAndY = 0, MouseX = 1, MouseY = 2 }
public RotationAxes axes = RotationAxes.MouseXAndY;
public float sensitivityX = 15F;
public float sensitivityY = 15F;
public float minimumX = -360F;
public float maximumX = 360F;
public float minimumY = -60F;
public float maximumY = 60F;
float rotationY = 0F;
void Update()
{
if (Input.touchCount > 0)
{
Touch touch = Input.GetTouch(0);
float turnAngleChange = (touch.deltaPosition.x / Screen.width) * sensitivityX;
float pitchAngleChange = (touch.deltaPosition.y / Screen.height) * sensitivityY;
// Handle any pitch rotation
if (axes == RotationAxes.MouseXAndY || axes == RotationAxes.MouseY)
{
rotationY = Mathf.Clamp(rotationY + pitchAngleChange, minimumY, maximumY);
transform.localEulerAngles = new Vector3(-rotationY, transform.localEulerAngles.y, 0f);
}
// Handle any turn rotation
if (axes == RotationAxes.MouseXAndY || axes == RotationAxes.MouseX)
{
transform.Rotate(0f, turnAngleChange, 0f);
}
}
void Start()
{
//if(!networkView.isMine)
//enabled = false;
// Make the rigid body not change rotation
//if (rigidbody)
//rigidbody.freezeRotation = true;
}
}
}
I don't really get your question so I'm gonna answer both of my interpretations.
If the rotation of the camera is inverted (if you put your stick to the left the camera rotates to the right) you just need to add a minus in front of the speed you're rotating the camera with.
If the rotation of the camera happens when you use the left stick and you want to use the right stick. Then you should define in your input a field called something like camera-rotation-x and use the axis shown on the following pictures in the article here: https://gamedev.stackexchange.com/questions/150323/unity3d-how-to-use-controller-joystick-to-look-around If you follow that article, your camera rotation should work.

Joystick intercalate with camera rotation

I make game with fps , when I rotate the camera the joystick doesn't work properly. I have a fixed Joystick , when I try to move by rotation anything in movement change . Do I need to change the joystick ? or do I need to change something in the script for the camera rotation ? When I start the game on the mobile , the rotation affects the joystick . When I move the joystick forward and do some rotation , forward becomes backward , left right , if I move right the rotation , right becomes backward , etc . what can I do
using System.Collections.Generic;
using UnityEngine;
[AddComponentMenu("Camera-Control/Mouse Look")]
public class MouseLook : MonoBehaviour
{
public enum RotationAxes { MouseXAndY = 0, MouseX = 1, MouseY = 2 }
public RotationAxes axes = RotationAxes.MouseXAndY;
public float sensitivityX = 15F;
public float sensitivityY = 15F;
public float minimumX = -360F;
public float maximumX = 360F;
public float minimumY = -60F;
public float maximumY = 60F;
float rotationY = 0F;
void Update()
{
if (Input.touchCount > 0)
{
Touch touch = Input.GetTouch(0);
float turnAngleChange = (touch.deltaPosition.x / Screen.width) * sensitivityX;
float pitchAngleChange = (touch.deltaPosition.y / Screen.height) * sensitivityY;
// Handle any pitch rotation
if (axes == RotationAxes.MouseXAndY || axes == RotationAxes.MouseY)
{
rotationY = Mathf.Clamp(rotationY + pitchAngleChange, minimumY, maximumY);
transform.localEulerAngles = new Vector3(-rotationY, transform.localEulerAngles.y, 0f);
}
// Handle any turn rotation
if (axes == RotationAxes.MouseXAndY || axes == RotationAxes.MouseX)
{
transform.Rotate(0f, turnAngleChange, 0f);
}
}
void Start()
{
//if(!networkView.isMine)
//enabled = false;
// Make the rigid body not change rotation
//if (rigidbody)
//rigidbody.freezeRotation = true;
}
}
}

Rotation on touch with gyroscope in a mobile device behaving in a weird manner

I have been using the gvr sdk in my project to get a 360 view during the video playback through the camera. But when I rotate the camera on touch, the rotation itself is behaving in a weird manner i.e. during the landscape mode, rotation in y-axis is working fine but when the gyroscope is moved towards the right or left, the x-axis rotation is behaving as z-axis rotation. Please help. Below is the code for simple rotation in x and y axis using a touch input on the device.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RCPlayer : MonoBehaviour
{
public static RCPlayer Instance;
//public GameObject Head;
//public GameObject Camera;
Vector3 FirstPoint;
Vector3 SecondPoint;
float xAngle;
float yAngle;
float xAngleTemp;
float yAngleTemp;
void Awake()
{
Instance = this;
}
void Start()
{
xAngle = 0;
yAngle = 0;
transform.rotation = Quaternion.Euler(yAngle, xAngle, 0);
}
void Update()
{
if (Input.touchCount > 0)
{
if (Input.GetTouch(0).phase == TouchPhase.Began)
{
FirstPoint = Input.GetTouch(0).position;
xAngleTemp = xAngle;
yAngleTemp = yAngle;
}
if (Input.GetTouch(0).phase == TouchPhase.Moved)
{
SecondPoint = Input.GetTouch(0).position;
if (FirstPoint - SecondPoint == Vector3.zero)
{
return;
}
else
{
xAngle = xAngleTemp + (SecondPoint.x - FirstPoint.x) * 180 / Screen.width;
yAngle = yAngleTemp - (SecondPoint.y - FirstPoint.y) * 180 / Screen.height;
transform.rotation = Quaternion.Euler(-yAngle * 0.5f, -xAngle * 0.5f, 0.0f);
}
}
}
}
}

Orthographic camera zoom with focus on a specific point

I have an orthographic camera and would like to implement a zoom feature to a specific point. I.e., imagine you have a picture and want to zoom to a specific part of the picture.
I know how to zoom in, the problem is to move the camera to a position that has the desired zone in focus.
How can I do so?
The camera's orthographicSize is the number of world space units in the top half of the viewport. If it's 0.5, then a 1 unit cube will exactly fill the viewport (vertically).
So to zoom in on your target region, center your camera on it (by setting (x,y) to the target's center) and set orthographicSize to half the region's height.
Here is an example to center and zoom to the extents of an object. (Zoom with LMB; 'R' to reset.)
public class OrthographicZoom : MonoBehaviour
{
private Vector3 defaultCenter;
private float defaultHeight; // height of orthographic viewport in world units
private void Start()
{
defaultCenter = camera.transform.position;
defaultHeight = 2f*camera.orthographicSize;
}
private void Update()
{
if (Input.GetMouseButtonDown(0))
{
Collider target = GetTarget();
if(target != null)
OrthoZoom(target.bounds.center, target.bounds.size.y); // Could directly set orthographicSize = bounds.extents.y
}
if (Input.GetKeyDown(KeyCode.R))
OrthoZoom(defaultCenter, defaultHeight);
}
private void OrthoZoom(Vector2 center, float regionHeight)
{
camera.transform.position = new Vector3(center.x, center.y, defaultCenter.z);
camera.orthographicSize = regionHeight/2f;
}
private Collider GetTarget()
{
var hit = new RaycastHit();
Physics.Raycast(camera.ScreenPointToRay(Input.mousePosition), out hit);
return hit.collider;
}
}
hope you find this code example useful, should be a copy / paste.
Note: this script assume it's attached to the camera object, otherwise you should adjust the transform to the camera object reference.
private float lastZoomDistance = float.PositiveInfinity; // remember that this should be reset to infinite on touch end
private float maxZoomOut = 200;
private float maxZoomIn = 50;
private float zoomSpeed = 2;
void Update() {
if (Input.touchCount >= 2) {
Vector2 touch0, touch1;
float distance;
Vector2 pos = new Vector2(transform.position.x, transform.position.y);
touch0 = Input.GetTouch(0).position - pos;
touch1 = Input.GetTouch(1).position - pos;
zoomCenter = (touch0 + touch1) / 2;
distance = Vector2.Distance(touch0, touch1);
if(lastZoomDistance == float.PositiveInfinity) {
lastZoomDistance = distance;
} else {
if(distance > lastZoomDistance && camera.orthographicSize + zoomSpeed <= maxZoomOut) {
this.camera.orthographicSize = this.camera.orthographicSize + zoomSpeed;
// Assuming script is attached to camera - otherwise, change the transform.position to the camera object
transform.position = Vector3.Lerp(transform.position, zoomCenter, Time.deltaTime);
} else if(distance < lastZoomDistance && camera.orthographicSize - zoomSpeed >= maxZoomIn) {
this.camera.orthographicSize = this.camera.orthographicSize - zoomSpeed;
transform.position = Vector3.Lerp(transform.position, zoomCenter, Time.deltaTime);
}
}
lastZoomDistance = distance;
}
}