Joystick controls mixed with rotation - unity3d

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.

Related

Unity, script for rotating the camera by swiping (3d)

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraScript : MonoBehaviour
{
[SerializeField] private float sensitivityHor = 9.0f;
[SerializeField] private float sensitivityVert = 9.0f;
[SerializeField] private float minimumVert = -45.0f;
[SerializeField] private float maximumVert = 45.0f;
private float _rotationX = 0;
private Rigidbody PlayerRigidbody;
void Start()
{
PlayerRigidbody = GetComponent<Rigidbody>();
if (PlayerRigidbody != null)
{
PlayerRigidbody.freezeRotation = true;
}
}
void Update()
{
_rotationX -= Input.GetAxis("Mouse Y") * sensitivityVert;
_rotationX = Mathf.Clamp(_rotationX, minimumVert, maximumVert);
float delta = Input.GetAxis("Mouse X") * sensitivityHor;
float rotationY = transform.localEulerAngles.y + delta;
transform.localEulerAngles = new Vector3(_rotationX, rotationY, 0);
}
}
Good evening. I have written a script to rotate the camera by swiping a finger across the screen
(it is on my camera), everything works correctly with one finger, but if you touch with two fingers at the same time, the application will react incorrectly (suddenly change the camera rotation). How can I fix it using Input.GetAxis or what can I use to write a script for multiple touches?
You may use only the first touch for your movement, so that if there is a second nothing happens and change Input.GetAxis("Mouse Y") by Input.GetTouch(0).deltaPosition.y with x and y respectively. Like this:
if (Input.touchCount > 0) {
_rotationX -= Input.GetTouch(0).deltaPosition.y * sensitivityVert;
_rotationX = Mathf.Clamp(_rotationX, minimumVert, maximumVert);
float delta = Input.GetTouch(0).deltaPosition.x * sensitivityHor;
float rotationY = transform.localEulerAngles.y + delta;
transform.localEulerAngles = new Vector3(_rotationX, rotationY, 0);
}
Code not debugged, as its just your code with the substitution.
If handling the first touch acts weird, you can handle the rotation with the middle point maybe. Like this:
//get the touch middle when the second finger touches
if (Input.GetTouch(1).phase == TouchPhase.Began) {
touchMiddle = (Input.GetTouch(0).position +
Input.GetTouch(1).position) / 2;
touchDistSqr = (Input.GetTouch(0).position -
Input.GetTouch(1).position).sqrMagnitude;
return;
}
if (Input.touchCount == 2) {
var deltaMidde = touchMiddle - (Input.GetTouch(0).position + Input.GetTouch(1).position) / 2;
transform.localEulerAngles = new Vector3(deltaMidde.x, deltaMidde.y, 0);
}
All the code in the LateUpdate().
Preferably camera movements needs to be done in the LateUpdate() for the objects that might have moved inside Update to be at their final state for each frame. As per adviced in the documentation.
Not really relevant but note that you can use Vector2 instead of Vector3for the screen operations most of the time.
Also it is very interesting in the Update or LateUpdate operations to have them multiplied by Time.deltaTime so that the movement is frame rate independent.

How can I make an objects rotatable only for the player?

the problem is that if the player touches something that rotate, the player automatically starting rotating too because the object that is rotation right now pushed the player's colliders and and player starting rotating. I want to make my player un rotatable to another objects in the game but rotatable if the player rotate by himself
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class camera : MonoBehaviour
{
public enum RotationAxis
{
MouseX = 1,
MouseY = 2
}
public RotationAxis axes = RotationAxis.MouseX;
public float minimumVert = -45.0f;
public float maximumVert = 45.0f;
public float sensHorizontal = 10.0f;
public float sensVertical = 10.0f;
public float _rotationX = 0;
// Update is called once per frame
void Update()
{
if (axes == RotationAxis.MouseX)
{
transform.Rotate(0, Input.GetAxis("Mouse X") * sensHorizontal, 0);
}
else if (axes == RotationAxis.MouseY)
{
_rotationX -= Input.GetAxis("Mouse Y") * sensVertical;
_rotationX = Mathf.Clamp(_rotationX, minimumVert, maximumVert); //Clamps the vertical angle within the min and max limits (45 degrees)
float rotationY = transform.localEulerAngles.y;
transform.localEulerAngles = new Vector3(_rotationX, rotationY, 0);
}
}
}
You could store the rotation in a field and thus making sure the only thing changing it is your script:
move it to LateUpdate in order for it to be the last thing called in a frame (also see Order of Execution for Event Functions)
float xRotation;
float yRotation;
void Start()
{
xRotation = transform.localEulerAngles.x;
yRotation = transform.localEulerAngles.y;
}
void LateUpdate()
{
if (axes == RotationAxis.MouseX)
{
yRotation += Input.GetAxis("Mouse X") * sensHorizontal;
}
else if (axes == RotationAxis.MouseY)
{
xRotation -= Input.GetAxis("Mouse Y") * sensVertical;
//Clamps the vertical angle within the min and max limits (45 degrees)
xRotation= Mathf.Clamp(lastXRotation , minimumVert, maximumVert);
}
// always overwrite with fixed values instead of using transform.rotation based ones
transform.localRotation = Quaternion.Euler(xRotation, yRotation, 0);
}
just to be sure you could also additionally but it to FixedUpdate in order to also reset changes from the Physics. If there is any RigidBody in play this should be the way to go anyway but then not using the Transform but rather the Rigidbody component.
void FixedUpdate()
{
transform.localRotation = Quaternion.Euler(xRotation, yRotation, 0);
}
Note however: As you currently have it setup you will get unexpected rotations. Rotating around the two axis here has the problem of also rotating along the local coordinate system.
In general you should rather have a parent object for the Y rotation and only do the X rotation on the object itself.

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

Unity3D - How to rotate a camera like Google Earth?

I'm creating a game in Unity3D that contains a planet in a scene. I want the camera to move around the planet and rotate in the vector direction of the mouse when the player is holding down the right click anywhere on the screen. I have code written out as seen below. The code works great, however the player is only able to rotate the camera around the planet if the mouse is on the planet and not off the planet. How do I change it so that the camera will rotate around the planet even if the mouse is not on the planet?
public class CameraHumanMovement : MonoBehaviour
{
[Header("Settings")]
public float planetRadius = 100f;
public float distance;
public GameObject planet;
public Transform camTransform;
public Transform holderTransform;
private Vector3? mouseStartPosition1;
private Vector3? currentMousePosition1;
public bool dog;
private void LateUpdate()
{
if (Input.GetMouseButtonDown(1))
mouseStartPosition = GetMouseHit();
if (mouseStartPosition != null)
DragPlanet();
if (Input.GetMouseButtonUp(1))
StaticPlanet();
}
private void DragPlanet()
{
currentMousePosition1 = GetMouseHit();
RotateCamera((Vector3)mouseStartPosition1, (Vector3)currentMousePosition1);
}
private void StaticPlanet()
{
mouseStartPosition1 = null;
currentMousePosition1 = null;
}
private void RotateCamera(Vector3 dragStartPosition, Vector3 dragEndPosition)
{
//normalised for odd edges
dragEndPosition = dragEndPosition.normalized * planetRadius;
dragStartPosition = dragStartPosition.normalized * planetRadius;
// Cross Product
Vector3 cross = Vector3.Cross(dragEndPosition, dragStartPosition);
// Angle for rotation
float angle = Vector3.SignedAngle(dragEndPosition, dragStartPosition, cross);
//Causes Rotation of angle around the vector from Cross product
holderTransform.RotateAround(planet.transform.position, cross, angle);
}
private static Vector3? GetMouseHit()
{
RaycastHit hit;
if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out hit))
{
return hit.point;
}
return null;
}
}
A simple code could be like this :
public class CameraHumanMovement : MonoBehaviour
{
//Rotation speed exposed on the inspector
public float RotationSpeed = 10f;
private void Update()
{
//Whenever the left mouse button is pressed rotate this object that holds this script in the x and y axis.
//You can reference your planet and put this script in another object if you want and it will be "yourplanetobject.transform etc.."
if(Input.GetMouseButton(0))
{
float rotX = Input.GetAxis("Mouse X") * RotationSpeed * Time.deltaTime;
float rotY = Input.GetAxis("Mouse Y") * RotationSpeed * Time.deltaTime;
transform.Rotate(Vector3.up, -rotX);
transform.Rotate(Vector3.right, rotY);
}
}
}
Cheers!

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