Unity quaterion rotatetoward() - c#

Right now, I am working on the Unity camera for first person view using mouse.
Camera is suppose to move toward to direction of mouse.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
namespace input
{
public class CameraControl : MonoBehaviour
{
[SerializeField] private GameObject player;
[SerializeField] private float speed = 20f;
float xRotation;
float yRotation;
private InputAction cameraAction;
public void Initialize(InputAction cameraAction)
{
this.cameraAction = cameraAction;
this.cameraAction.Enable();
}
private void FixedUpdate()
{
Vector2 camera = cameraAction.ReadValue<Vector2>();
float mouseX = camera.x;
float mouseY = camera.y;
xRotation -= mouseY;
yRotation += mouseX;
Quaternion goalRotation = Quaternion.Euler(xRotation, yRotation, 0);
//Quaternion goalRotation = Quaternion.Euler(30, 30, 0);
//Debug.Log(goalRotation);
//Quaternion goalRotation = Quaternion.LookRotation(direction);
transform.rotation = Quaternion.RotateTowards(transform.rotation, goalRotation, speed * Time.deltaTime);
//transform.rotation = goalRotation;
player.transform.rotation = Quaternion.Euler(0, yRotation, 0);
}
}
}
In the code, I am trying to understand how Quaternion.RotateToward() is working. RotateToward is having tree parameters: target from, target to, and speed of rotation.
Target from is current roation of camera. Target to is rotation that camera should rotate.
So, in the code, from the inputAction, I am receiving the Vector2 x and y values from mouse.
For example, if I move the mouse only to the right value would be like (1.0, 0) (2.0) ...
and if I move the mouse to upward (0, 1.0) (0.3)... Then, when I move the mouse diagnal, (1.0 1.0)..
So, using the Quaternion.RotateToward() actually rotate to the point that I want. However, problem is that it is not rotating based on the speed that I set which is 20f.
I know using
transform.rotation = goalRotation;
is eaier way to solve rather than use RotateToward(), however, I want to learn how this function should be working.
Any idea about this?

speed * Time.deltaTime to speed ables to solve the problem

Related

How do I Detect if the Mouse is Moving on Screen in Unity?

I am making a 360 camera movement for my game called PROTOTYPE. I need a function or something to detect if the mouse is moving and in which direction on the x axis it is, to set an offset for the Camera Smoothing script, but I don't know any. Could somebody plz help me? Here is the Camera Smoothing script if u need it:
using UnityEngine;
public class CameraFollow : MonoBehaviour
{
public Transform target;
public float smoothSpeed = 0.125f;
public Vector3 offset;
void FixedUpdate()
{
Vector3 desiredPosition = target.position + offset;
Vector3 smoothedPosition = Vector3.Lerp(transform.position, desiredPosition, smoothSpeed);
transform.position = smoothedPosition;
transform.LookAt(target);
}
}
I suppose you want to move your camera with your mouse, 360° around your character and also that script is attached to your player.
In order to do that, your FixedUpdate should look like this:
void FixedUpdate()
{
float horizontalAxis = Input.GetAxis("Mouse X"); // Getting the current mouse axis (left-right)
float verticalAxis = Input.GetAxis("Mouse Y"); // Getting the current mouse axis (up-down)
transform.RotateAround(player.transform.position, -Vector3.up, horizontalAxis * smoothSpeed);
transform.RotateAround(Vector3.zero, transform.right, verticalAxis * smoothSpeed);
}

How to make the player move according to the camera motion

Now I'm a beginner game developer and I'm working on a game so I have set the camera motion that when you move the mouse the player rotates however I want to make the WASD keys work to the direction the player is rotated. Basically when I rotate the camera to the left the W key still moves the player on the Z dimension. How can I fix this?
Here's my player rotation code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraMovement : MonoBehaviour
{
public float speedH = 2.0f;
public float speedV = 2.0f;
private float yaw = 0.0f;
private float pitch = 0.0f;
// Use this for initialization
void Start()
{
}
// Update is called once per frame
void Update()
{
yaw += speedH * Input.GetAxis("Mouse X");
pitch -= speedV * Input.GetAxis("Mouse Y");
transform.eulerAngles = new Vector3(pitch, yaw, 0.0f);
}
}
Moving in the direction the character is facing is a simple work for Transform.forward and Transform.right because you need to move the player based on local position and rotation and not the world one.
For example, you could have
void Move (float h, float v)
{
movement.Set (h, 0f, v);
movement = movement.normalized * speed * Time.deltaTime;
playerRigidbody.MovePosition (transform.position + (transform.forward * movement.z) + (transform.right * movement.x));
}
The Rigidbody is what you need to move it, if you want an object that is always moving in the direction is facing you could easily do a
transform.position += transform.forward * Time.deltaTime * movementSpeed;
In this case, to go back you should subtract instead of add.
But use my first suggestion for your player :D
EDIT
In your update you can add
Move(yaw, pitch);

Can't rotate and move at the same time

I'm currently developing an FPS shooter in Unity 3D. I'm fairly new to Unity and I've been having a bit of trouble with my player movement script. Individually everything seems to work, I can rotate and move the player freely, however when I try doing the two simultaneously my player seems to lock and won't rotate.
Sometimes jumping or moving to higher ground on the terrain seems to fix the issue, however I ran a few checks with gravity disabled, no colliders, and with the player well above ground, so the problem seems to be with the script. I've also done a bit of debugging and the Rotate() code does run, just the rotation amount doesn't seem to change.
Here is the player movement script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(Rigidbody))]
public class PlayerMov : MonoBehaviour
{
[SerializeField]
private Camera cam;
[SerializeField]
private float speed = 5f;
[SerializeField]
private float looksensitivity = 4f;
[Header("Camera View Lock:")]
[SerializeField] //min and max amount for looking up and down (degrees)
private float lowlock = 70f;
[SerializeField]
private float highlock = 85f;
private Rigidbody rb;
private float currentrotx; //used later for calculating relative rotation
public Vector3 velocity;
public Vector3 rotation; // rotates the player from side to side
public float camrotation; // rotates the camera up and down
public float jmpspe = 2000f;
void Start()
{
rb = GetComponent<Rigidbody>();
}
// Update is called once per frame
void Update()
{
CalcMovement();
CalcRotation();
Rotate();
}
void FixedUpdate()
{
Move();
}
private void CalcRotation()
{
float yrot = Input.GetAxisRaw("Mouse X"); //around x axis
rotation = new Vector3(0f, yrot, 0f) * looksensitivity;
float xrot = Input.GetAxisRaw("Mouse Y"); //around y axis
camrotation = xrot * looksensitivity;
}
private void CalcMovement()
{
float xmov = Input.GetAxisRaw("Horizontal");
float zmov = Input.GetAxisRaw("Vertical");
Vector3 movhor = transform.right * xmov;
Vector3 movver = transform.forward * zmov;
velocity = (movhor + movver).normalized * speed;
}
void Move()
{
//move
if (velocity != Vector3.zero)
{
rb.MovePosition(rb.position + velocity * Time.fixedDeltaTime);
}
//jump
if (Input.GetKeyDown(KeyCode.Space))
{
//add double jump limit later!
rb.AddForce(0, jmpspe * Time.deltaTime, 0, ForceMode.Impulse);
}
}
void Rotate()
{
//looking side to side
rb.MoveRotation(rb.rotation * Quaternion.Euler(rotation));
// camera looking up and down
currentrotx -= camrotation;
currentrotx = Mathf.Clamp(currentrotx, -lowlock, highlock);
cam.transform.localEulerAngles = new Vector3(currentrotx, 0, 0);
}
}
Here are the relevant components attached to my player:
(The player has a couple more components attached but I ran tests without them and the problem still occurs)
Like I said I'm a bit of a unity novice, so i'm sure I missed something small but I just can't seem to place my finger on it, I've been stuck on this for a while so any help is much appreciated.
SOLVED:
It seems the problem I had was because I was running the scene from my laptop and not a desktop which I assume is what the Unity input was built for.

unity 3d rotate object (space.self) toward player

i need your help please.
i want an object to rotate in Y axis (space.self) toward the player position.
i have already tried this code, it works but i think there is a bug in it because the object keep changing position slowly.
public Transform _Playertrs;
public float RotationSpeed = 10f;
private Quaternion _LookRotation;
private Vector3 _direction;
private bool Patroling = true;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
_direction = (_Playertrs.position - transform.position).normalized;
_LookRotation = Quaternion.LookRotation(_direction);
transform.rotation = Quaternion.Slerp(transform.rotation, _LookRotation, Time.deltaTime * RotationSpeed);
}
thank you guys for your answers, the rotation is working perfectly now, but the problem is the object keep moving from its position even that i don't have any movement code, watch the video to understand pls
https://www.youtube.com/watch?v=Gys5xYQ5psw&feature=youtu.be
If you want it to be instantaneous, replace
transform.rotation = Quaternion.Slerp(transform.rotation, _LookRotation, Time.deltaTime * RotationSpeed);
by
transform.rotation = _LookRotation;
The Slerp function gives an intermediate point between the to rotation to make a smooth effect.
Here, this is taken from the Unity Quaternion.LookRotation() official documentation, you can just simply apply the Quaternion that you have _LookRotation and apply it to your desired transform.rotation as such transform.rotation = _LookRotation;
using UnityEngine;
using System.Collections;
public class ExampleClass : MonoBehaviour
{
public Transform target;
void Update() {
Vector3 relativePos = target.position - transform.position;
Quaternion rotation = Quaternion.LookRotation(relativePos);
transform.rotation = rotation;
}
}

Rotate cameran around a gameobject in unity3d

I want to rotate camera around an fbx object when a key is being pressed using unity 3d.How it do? I tried some examples but its not working. First i create a game object and add main camera child of it.
public class CameraOrbit : MonoBehaviour
{
public Transform target;
public float speed = 1f;
private float distance;
private float currentAngle = 0;
void Start()
{
distance = (new Vector3(transform.position.x, 0, transform.position.z)).magnitude;
}
void Update()
{
currentAngle += Input.GetAxis("Horizontal") * speed * Time.deltaTime;
Quaternion q = Quaternion.Euler(0, currentAngle, 0);
Vector3 direction = q * Vector3.forward;
transform.position = target.position - direction * distance + new Vector3(0, transform.position.y, 0);
transform.LookAt(target.position);
}
}
I dont have access to unity at the moment so i might have messed something up.
The idea is keep an angle that you change based on input. Create a Quaternion from the angle (the Quaternion say how to rotate a vector to a certain direction), then rotate a Vector to that direction. Starting from the targets position move in that direction a certain distance and then look at the targets position.
This only implements rotation around the y axis, if you want rotation around the x axis all you need is another angle variable and then change to this Quaternion.Euler(currentAngleX, currentAngleY, 0);

Categories