I want to rotate a object on the x-axis when I move the mouse up or down (increase the x-rotation when moving mouse up, decrease when moving mouse down).
But I don't know how to do this.
I tried this script:
public float mouseSensitivity = 100.0F;
public float clampAngle = 80.0F;
float rotX = 0.0F, rotY = 0.0F;
void Update()
{
// Mouse Look
float mouseX = Input.GetAxis("Mouse X");
float mouseY = Input.GetAxis("Mouse Y");
rotX += mouseY * mouseSensitivity * Time.deltaTime;
rotY += mouseX * mouseSensitivity * Time.deltaTime;
rotX = Mathf.Clamp(rotX, -clampAngle, clampAngle);
Quaternion localRotation = Quaternion.Euler(rotX, 0, 0.0F);
transform.rotation = localRotation;
}
But this controls also rotation on the y axis. I also have rotation on the y-axis, but they are controlled via keyboard input:
if (Input.GetKey(KeyCode.W) && !Input.GetKey(KeyCode.S))
transform.Translate(Vector3.forward * Time.deltaTime * moveSpeed);
else if (Input.GetKey(KeyCode.S) && !Input.GetKey(KeyCode.W))
transform.Translate(Vector3.forward * Time.deltaTime * -moveSpeed);
if (Input.GetKey(KeyCode.A) && !Input.GetKey(KeyCode.D))
transform.Rotate(Vector3.up * Time.deltaTime * -rotateSpeed, Space.World);
else if (Input.GetKey(KeyCode.D) && !Input.GetKey(KeyCode.A))
transform.Rotate(Vector3.up * Time.deltaTime * rotateSpeed, Space.World);
and I want the mouse up/down only control the rotation on the x-axis.
If someone can help me, that would be great!
void Update()
{
// Mouse Look
float mouseX = Input.GetAxis("Mouse X");
float mouseY = Input.GetAxis("Mouse Y");
rotX = mouseY * mouseSensitivity;
rotY = mouseX * mouseSensitivity;
transform.rotation *= Quaternion.Euler(rotX, 0, 0.0f);
}
Related
I've genuinely gone through a million tutorials, but it doesn't work out. With this code, I either have to activate the last line or the second last line to get x rotation or y rotation respectively, but I obviously want them to work together.
void MouseLook()
{
mouseX = Input.GetAxis("Mouse X") * mouseSensitivity * Time.deltaTime;
mouseY = Input.GetAxis("Mouse Y") * mouseSensitivity * Time.deltaTime;
xRotation -= mouseY;
xRotation = Mathf.Clamp(xRotation, -60, 10);
transform.localRotation = Quaternion.Euler(xRotation, 0f, 0f);
transform.Rotate(Vector3.up * mouseX);
}
The one always seems to cancel the other out. This is from a Brackeys tutorial. I had to tweak some stuff so it's applicable, but I obviously am breaking the code that way. Please help!
Try this Stuff
public float mouseSensitivity = 10.0f;
public Transform target;
public float dstFromTarget = 2.0f;
public float yaw;
public float pitch;
public Vector2 pitchMinMax = new Vector2(-50, 85);
public float rotationSmoothTime = 0.02f;
Vector3 rotationSmoothVelocity;
Vector3 currentRotation;
void LateUpdate()
{
MouseLook();
}
void MouseLook()
{
//Mouse Movement
yaw += Input.GetAxis("Mouse X") * mouseSensitivity;
pitch -= Input.GetAxis("Mouse Y") * mouseSensitivity;
// Claemp
pitch = Mathf.Clamp(pitch, pitchMinMax.x, pitchMinMax.y);
// Positioning
transform.eulerAngles = currentRotation;
// Smoothening
currentRotation = Vector3.SmoothDamp(currentRotation, new Vector3(pitch, yaw), ref rotationSmoothVelocity, rotationSmoothTime);
transform.localRotation = Quaternion.Euler(currentRotation.x,currentRotation.y,currentRotation.z);
}
I'm having an issue with the free roam camera I'm trying to implement. The camera can be rotated via keyboard (only on the Y axis) and via mouse (on the X and Y axis) while holding the middle mouse button. With my current implementation, if I rotate the camera using the keyboard and the rotate it using the mouse, it remove any rotation done by the keyboard as soon as I hit the middle mouse button. Of course I would like to not do that... Code is below. Can someone give tell me what I'm doing wrong?
private void RotateCameraKeyboard()
{
if (Input.GetKey(KeyCode.Q))
{
transform.RotateAround(transform.position, Vector3.up, -rotationSpeed * Time.deltaTime * 30);
}
if (Input.GetKey(KeyCode.E))
{
transform.RotateAround(transform.position, Vector3.up, rotationSpeed * Time.deltaTime * 30);
}
}
private void RotateCameraMouse()
{
if (Input.GetMouseButton(2))
{
pitch -= rotationSpeed * Input.GetAxis("Mouse Y");
yaw += rotationSpeed * Input.GetAxis("Mouse X");
pitch = Mathf.Clamp(pitch, -90f, 90f);
while (yaw < 0f)
{
yaw += 360f;
}
while (yaw >= 360f)
{
yaw -= 360f;
}
transform.eulerAngles = new Vector3(pitch, yaw, 0f);
}
}
Instead of using RotateAround (which in your case of using the transform.position as pivot is redundant anyway .. you could as well just use Rotate) additionally also add the according amount to your pitch and yawn.
I would simply generalize and use the same method for both inputs like e.g.
private void RotateCameraKeyboard()
{
if (Input.GetKey(KeyCode.Q))
{
Rotate(-rotationSpeed * Time.deltaTime * 30, 0);
}
if (Input.GetKey(KeyCode.E))
{
Rotate(rotationSpeed * Time.deltaTime * 30, 0);
}
}
private void RotateCameraMouse()
{
if (Input.GetMouseButton(2))
{
var pitchChange = rotationSpeed * Input.GetAxis("Mouse Y");
var yawChange = rotationSpeed * Input.GetAxis("Mouse X");
Rotate(yawChange, pitchChange);
}
}
private void Rotate(float yawChange, float pitchChange)
{
pitch = Mathf.Clamp(pitch + pitchChange, -90f, 90f);
yaw += yawChange;
while (yaw < 0f)
{
yaw += 360f;
}
while (yaw >= 360f)
{
yaw -= 360f;
}
transform.eulerAngles = new Vector3(pitch, yaw, 0f);
}
I developing an 6DOF game. I have some problems with the auto leveling (so the ship will always goes horizontal). The auto leveling worked, but I can't turn anymore on the x-axis more than 90 degrees. The spaceship must fly free in any direction. I hope someone can help me.
// Update is called once per frame
void Update()
{
yaw = Input.GetAxis("Mouse X") * speed;
pitch = Input.GetAxis("Mouse Y") * speed;
roll = Input.GetAxis("Roll") * speed;
float ver = 0;
float up = 0;
float hor = 0;
up = Input.GetAxis("Up");
hor = Input.GetAxis("Horizontal");
ver = Input.GetAxis("Vertical");
ver *= speed * Time.deltaTime;
up *= speed * Time.deltaTime;
hor *= speed * Time.deltaTime;
transform.Rotate(Vector3.up, yaw);
transform.Rotate(Vector3.left, pitch);
transform.Rotate(Vector3.forward, -roll);
Vector3 cross = Vector3.Cross(Vector3.up, transform.forward);
Quaternion rotator = Quaternion.FromToRotation(transform.right, cross)
// Apply rotation
transform.rotation = Quaternion.Slerp(transform.rotation, rotator * transform.rotation, Time.deltaTime);
transform.Translate(hor, up, ver);
}
As requested in comments (note: untested):
void Update() {
var yaw = Input.GetAxis("Mouse X");
var pitch = Input.GetAxis("Mouse Y");
var roll = Input.GetAxis("Roll");
var up = Input.GetAxis("Up"); // better name is 'heave' (up/down)
var hor = Input.GetAxis("Horizontal"); // better name is 'sway' (left/right)
var ver = Input.GetAxis("Vertical"); // better name is 'surge' (forward/back)
// If no rotation input, then 'auto-correct' for roll (up direction)
if ( Mathf.Approximately(yaw + pitch + roll, 0)) {
// Find what the 'up' rotation is
var levelRotation = Quaternion.LookRotation(transform.forward, Vector3.up);
// Apply it over time (Limit the angular change with Time.deltaTime)
transform.rotation = Quaternion.RotateTowards(transform.rotation, levelRotation, Speed * Time.deltaTime);
}
// Else there IS input rotation, so deal with that instead.
else {
// Scale inputs for speed (rotation speed should probably be different from translation speed)
yaw *= Speed * Time.deltaTime;
pitch *= Speed * Time.deltaTime;
roll *= Speed * Time.deltaTime;
var rotation = Quaternion.Euler(yaw, pitch, roll);
transform.rotation *= rotation;
}
// Acale and apply translation
ver *= speed * Time.deltaTime;
up *= speed * Time.deltaTime;
hor *= speed * Time.deltaTime;
transform.Translate(hor, up, ver);
}
I am doing camera navigation (Movement/Rotation) on Update event in this way:
void UpdateMovement()
{
bool accelerate = Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift);
moveDirection =
new
Vector3(
Input.GetAxisRaw("Horizontal") * moveSpeed,
0,
Input.GetAxisRaw("Vertical") * moveSpeed);
//moveDirection = new Vector3(Input.GetAxis("Horizontal") * moveSpeed, 0, Input.GetAxis("Vertical") * moveSpeed);
moveDirection = transform.TransformDirection(moveDirection);
if (Input.GetButton("Up"))
{
moveDirection.y += moveSpeed;
}
else if (Input.GetButton("Down"))
{
moveDirection.y -= moveSpeed;
}
if (Input.GetAxisRaw("Mouse ScrollWheel") > 0)
{
moveDirection.y = moveDirection.y + scrollSpeed;
}
else if (Input.GetAxisRaw("Mouse ScrollWheel") < 0)
{
moveDirection.y = moveDirection.y - scrollSpeed;
}
moveDirection *= (accelerate ? speed : moveSpeed);
controller.Move(moveDirection * Time.deltaTime);
}
void UpdateRotation()
{
if (!Input.GetMouseButton(1))
return;
rotationX += Input.GetAxis("Mouse X") * lookSpeed;
rotationY += Input.GetAxis("Mouse Y") * lookSpeed;
rotationY = Mathf.Clamp(rotationY, -90, 90);
rotationZ = Input.GetAxis("Mouse ScrollWheel");
transform.localRotation = Quaternion.AngleAxis(rotationZ, Vector3.forward);
transform.localRotation = Quaternion.AngleAxis(rotationX, Vector3.up);
transform.localRotation *= Quaternion.AngleAxis(rotationY, Vector3.left);
}
All working fine but the problem on WebGL canvas when I rotate the camera using mouse and comes out of the bound of WebGl canvas meanwhile, I also continuously press horizontal or vertical key, then release input key doesn't work. Remember I logged the key[Input.GetAxisRaw("Horizontal"),Input.GetAxisRaw("Vertical")] input and found that it is not reset to zero on release.
Debug.Log("Hr GetAxisRaw : " + Input.GetAxisRaw("Horizontal"));
Debug.Log("Vertical : " + Input.GetAxisRaw("Vertical"));
Normally when I don't use camera rotation using mouse and during this time, when i release the horizontal/vertical key, it works fine. I was previously using Input.GetAxis now i am using Input.GetAxisRaw but the problem is same.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MouseOrbit : MonoBehaviour {
public Transform target;
public float distance = 5.0f;
public float xSpeed = 120.0f;
public float ySpeed = 120.0f;
public float yMinLimit = -20f;
public float yMaxLimit = 80f;
public float distanceMin = .5f;
public float distanceMax = 15f;
private Rigidbody rigidbody;
float x = 0.0f;
float y = 0.0f;
float minFov = 15f;
float maxFov = 90f;
float sensitivity = 10f;
// Use this for initialization
void Start()
{
Vector3 angles = transform.eulerAngles;
x = angles.y;
y = angles.x;
rigidbody = GetComponent<Rigidbody>();
// Make the rigid body not change rotation
if (rigidbody != null)
{
rigidbody.freezeRotation = true;
}
}
void Update()
{
// Updating camera distance on every frame
distance = RayCast3.distance3;
//Setting maximum distance so the camera doesnt go too far
if (distance > 2)
{
distance = 2;
}
}
void LateUpdate()
{
if (target)
{
x += Input.GetAxis("Mouse X") * xSpeed * distance * 0.02f;
y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02f;
y = ClampAngle(y, yMinLimit, yMaxLimit);
Quaternion rotation = Quaternion.Euler(y, x, 0);
//distance = Mathf.Clamp(distance - Input.GetAxis("Mouse ScrollWheel") * 5, distanceMin, distanceMax);
//distance += Input.GetAxis("Mouse ScrollWheel") * sensitivity;
float fov = Camera.main.fieldOfView;
fov += Input.GetAxis("Mouse ScrollWheel") * sensitivity;
fov = Mathf.Clamp(fov, minFov, maxFov);
Camera.main.fieldOfView = fov;
RaycastHit hit;
if (Physics.Linecast(target.position, transform.position, out hit))
{
distance -= hit.distance;
}
Vector3 negDistance = new Vector3(0.0f, 0.0f, -distance);
Vector3 position = rotation * negDistance + target.position;
transform.rotation = rotation;
transform.position = position;
}
}
public static float ClampAngle(float angle, float min, float max)
{
if (angle < -360F)
angle += 360F;
if (angle > 360F)
angle -= 360F;
return Mathf.Clamp(angle, min, max);
}
}
Now i'm using fov:
And it's working fine.
float fov = Camera.main.fieldOfView;
fov += Input.GetAxis("Mouse ScrollWheel") * sensitivity;
fov = Mathf.Clamp(fov, minFov, maxFov);
Camera.main.fieldOfView = fov;
But now i want to use the distance variable and not fov.
So i tried first the line:
distance = Mathf.Clamp(distance - Input.GetAxis("Mouse ScrollWheel") * 5, distanceMin, distanceMax);
It didn't work so i tried the line:
distance += Input.GetAxis("Mouse ScrollWheel") * sensitivity;
But in both lines the character is stuttering and it's not zooming in out with the mouse wheel.
It's really simple. Get mouse scroll wheel speed then multiply it by some speed value. You can also multiply it by Time.deltaTime if you want. Finally use transform.Translate to move the camera with that value.
This will move in z-axis:
private float zoomSpeed = 2.0f;
void Update()
{
float scroll = Input.GetAxis("Mouse ScrollWheel");
transform.Translate(0, 0, scroll * zoomSpeed, Space.World);
}
Or where camera is facing:
private float zoomSpeed = 5.0f;
void Update()
{
float scroll = Input.GetAxis("Mouse ScrollWheel");
transform.position += this.transform.forward * scroll * zoomSpeed;
}
You should calculate a delta between your camera point and your target point. Normalize it and multiply it with the scrollwheel delta. Add this on your camera position. I used the camera target as angle to zoom-in.
Pseudo:
var delta = cameraTarget - cameraPosition;
delta.Normalize();
cameraPosition += delta * ScrollWheel.delta * sensitivity;
// you can even move your cameraTarget in the same direction
cameraTarget += delta * ScrollWheel.delta * sensitivity;
You can use the distance instead of calculating a delta.