How to enable gyroscope camera at current device orientation - c#

I would like to enable gyro controlled camera onButtonClick event but I want it to start at the camera's current position. Currently when the gyro gets enabled it moves the camera off to a new position (probably the devices current gyro rotation) rather than leaving it where it is and gyro-ing from that point.
Hope I'm making sense, but basically I don't want the user to notice any change in what they are seeing in the game (ie. camera controlled by gyro but not that user would notice that change). Here's the code I'm using:
void Update ()
{
Quaternion attitudeFix = new Quaternion (-gyro.attitude.x, -gyro.attitude.z, -gyro.attitude.y, gyro.attitude.w);
Quaternion offsetRotation = initialGyroRotation * attitudeFix;
rotation = initialRotation * offsetRotation;
transform.rotation = rotation;
}
public void EnableGyro()
{
initialGyroRotation = Input.gyro.attitude;
initialRotation = transform.rotation;
Debug.Log("initialRotation: " + initialRotation.ToString());
Debug.Log("transform.rotation: " + transform.rotation.ToString());
Debug.Log("initialGyroRotation: " + initialGyroRotation.ToString());
}
**
EDIT: Here's a screen of exactly how I want the view to look as the user is holding their device in front of their face (portrait) AND heading north. Regardless of the orientation of the device when the app starts, this is how it should look when heading north with phone in portrait orientation (again as the user is looking through the phone).
EDIT 2:
Tests were getting confusing so I put the code back to exactly how your solution suggests. There is still a slight problem, but it seems like this script is very close. The main problem is the screen doesn't look like the above pic when I run each test, starting the app with the device on strange angles. It really shouldn't matter what angle the device is when the app is started, it needs to look like the above screen when pointing north and portrait.
I need to do more tests, and will do so with a new/clean project.

You need to get the offset camera position in the Awake or Start function. In the Update function, apply that offset value to the value from the gyro sensor.
It looks like you already know offset should be used but you are not doing that the right way. The confusing part is getting the offset which requires subtracting the current camera rotation from the gyro sensor value.
To subtract a Quaternion multiply the Inverse not just the Quaternion:
Quaternion = Quaternion *Quaternion.Inverse
To add a Quaternion multiply the Quaternion:
Quaternion = Quaternion * Quaternion.
This is what your code should look like:
Quaternion offset;
void Awake()
{
Input.gyro.enabled = true;
}
void Start()
{
//Subtract Quaternion
offset = transform.rotation * Quaternion.Inverse(GyroToUnity(Input.gyro.attitude));
}
void Update()
{
GyroModifyCamera();
}
void GyroModifyCamera()
{
//Apply offset
transform.rotation = offset * GyroToUnity(Input.gyro.attitude);
}
private static Quaternion GyroToUnity(Quaternion q)
{
return new Quaternion(q.x, q.y, -q.z, -q.w);
}

I hade trouble with this and it wasn't working in build this is what I found and this script has worked.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class GyroMovement : MonoBehaviour
{
// Start is called before the first frame update
//Movement
[SerializeField] float speed = 3.3f;
private float rotspeed = 90f;
private Vector3 moveDirection = Vector3.zero;
[SerializeField] private CharacterController controller;
//Rotation
private float _initialYAngle = 0f;
private float _appliedGyroYAngle = 0f;
private float _calibrationYAngle = 0f;
private Transform _rawGyroRotation;
private float _tempSmoothing;
//settings
private float _smoothing = 0.1f;
private void Update(){
//Movement
//Vector3 move = new Vector3 (Input.acceleration.x * speed * Time.deltaTime, 0f, -Input.acceleration.z * speed * Time.deltaTime);
//Vector3 rotMovement = transform.TransformDirection(move);
//controller.Move(rotMovement);
//Rotation
ApplyGyroRotation();
ApplyCalibration();
transform.rotation = Quaternion.Slerp(transform.rotation, _rawGyroRotation.rotation, _smoothing);
}
private IEnumerator Start(){
Input.gyro.enabled = true;
Application.targetFrameRate = 60;
_initialYAngle = transform.eulerAngles.y;
_rawGyroRotation = new GameObject("GyroRaw").transform;
_rawGyroRotation.position = transform.position;
_rawGyroRotation.rotation = transform.rotation;
yield return new WaitForSeconds(1f);
StartCoroutine (CalibrateYAngle());
}
private IEnumerator CalibrateYAngle(){
_tempSmoothing = _smoothing;
_smoothing = 1f;
_calibrationYAngle = _appliedGyroYAngle - _initialYAngle;
yield return null;
_smoothing = _tempSmoothing;
}
private void ApplyGyroRotation(){
_rawGyroRotation.rotation = Input.gyro.attitude;
_rawGyroRotation.Rotate(0f, 0f, 180f, Space.Self);
_rawGyroRotation.Rotate(90f, 180f, 0f, Space.World);
_appliedGyroYAngle = _rawGyroRotation.eulerAngles.y;
}
private void ApplyCalibration(){
_rawGyroRotation.Rotate(0f, -_calibrationYAngle, 0f, Space.World);
}
public void SetEnabled (bool value){
enabled = true;
StartCoroutine(CalibrateYAngle());
}
}

Related

How to make my character look in the direction of the camera in Unity 3d?

My character has a chinemachine camera attached to it and it is moving perfectly fine. But when I move my mouse to change the camera direction it is not looking in that direction. And I can't figure out how to make it look in that direction.
I have a reference to the original camera at the top of the script by the name cam.
The script has different functions for movement, rotation, animation, etc.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//so that unity recognises the callbacks ctx passed to the movementinput
using UnityEngine.InputSystem;
public class AnimationAndMovController : MonoBehaviour
{
public Transform cam;
public float speed;
//here we are creadting three vars for the animation
//vector2 currentMovementInput stores the input axis of the player
//vector3 store the current position of the player
PlayerInput playerInput;
CharacterController characterController;
Animator animator;
Vector2 currentMovementInput;
Vector3 currentMovement;
Vector3 currentRunMovement;
Vector3 moveDir;
bool isMovementPressed;
bool isRunPressed;
float rotationFactor = 15.0f;
// float turnSmoothtime = 0.1f;
// float turnSmoothVelocity ;
float runMultiplier = 4.0f;
int walkHash ;
int runHash ;
//runs before start function
void Awake(){
playerInput = new PlayerInput();
characterController = GetComponent<CharacterController>();
animator = GetComponent<Animator>();
// walkHash = Animator.StringToHash("Walking");
// runHash = Animator.StringToHash("run");
//now instead of writing the logic three times we pass the callback ctx to the movementInput() function
playerInput.CharacterControls.Move.started += movementInput;
playerInput.CharacterControls.Move.canceled += movementInput;
playerInput.CharacterControls.Move.performed += movementInput;
playerInput.CharacterControls.Run.started += handleRun;
playerInput.CharacterControls.Run.canceled += handleRun;
}
void handleRun(InputAction.CallbackContext ctx){
isRunPressed = ctx.ReadValueAsButton();
}
//we are going to handle rotations with quaternions
void handleRotation(){
Vector3 positionToLookAt;
positionToLookAt.x = currentMovement.x;
positionToLookAt.y = 0.0f ;
positionToLookAt.z = currentMovement.z;
Vector3 direction = new Vector3(positionToLookAt.x, 0.0f, positionToLookAt.z).normalized;
Quaternion currentRotation = transform.rotation;
//we take the current rotation and the target rotation and slerp them *FYI : Im still not sure how slerp works
if(isMovementPressed){
Quaternion targetRotation = Quaternion.LookRotation(positionToLookAt);
transform.rotation = Quaternion.Slerp(currentRotation, targetRotation, rotationFactor * Time.deltaTime);
}
}
//we are passing the callback ctx to this function so that we dont have to call the function everytime we start, cancel or perform the movement
void movementInput(InputAction.CallbackContext ctx){
//we are setting the movement input to the axis of the player
currentMovementInput = ctx.ReadValue<Vector2>();
currentMovement.x = currentMovementInput.x;
//we are setting the z axis to the y axis of the player because we move y axis on keyboard or joystick but in game we move in z axis
currentMovement.z = currentMovementInput.y;
//now we are setting the run movement to the current movement
currentRunMovement.x = currentMovementInput.x * runMultiplier;
currentRunMovement.z = currentMovementInput.y * runMultiplier;
isMovementPressed = currentMovementInput.x != 0 || currentMovementInput.y != 0;
}
void handleAnimation(){
bool walk = animator.GetBool("walking");
bool run = animator.GetBool("run");
if(isMovementPressed && !walk){
animator.SetBool("walking", true);
}
else if(!isMovementPressed && walk){
animator.SetBool("walking", false);
}
if((isMovementPressed && isRunPressed) && !run){
animator.SetBool("run", true);
}
else if((!isMovementPressed || !isRunPressed)&& run){
animator.SetBool("run", false);
}
}
void handleGravity(){
//we are setting the gravity to -9.8f because we are moving in y axis
if(characterController.isGrounded){
float groundGravity = -0.05f;
currentMovement.y = groundGravity;
currentRunMovement.y = groundGravity;
}
else{
float gravity = -9.8f;
currentMovement.y += gravity * Time.deltaTime;
currentRunMovement.y += gravity * Time.deltaTime;
}
}
// Update is called once per frame
void Update()
{
handleAnimation();
handleRotation();
handleGravity();
if(isRunPressed){
characterController.Move(currentRunMovement * Time.deltaTime);
}
else{
characterController.Move(currentMovement * Time.deltaTime);
}
}
//we are checking if the player script gets enabled or disabled and accordingly we are enabling or disabling the player input
void OnEnable(){
playerInput.CharacterControls.Enable();
}
void OnDisable(){
playerInput.CharacterControls.Disable();
}
}
That quite a lot of code to dive into.
I'd try:
Quaternion cameraRot = Camera.Main.transform.rotation;
transform.rotation = cameraRot;
Or if you have a target Quaternion.LookRotation:
Vector3 relativePos = target.position - transform.position;
// the second argument, upwards, defaults to Vector3.up
Quaternion rotation = Quaternion.LookRotation(relativePos, Vector3.up);
transform.rotation = rotation;
Hope that helps
Use Transform.LookAt, which points a Game Object's rotation towards a target's position.
In your case, this would be
transform.LookAt(cam);
here is the code that I use..
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MoveCamera : MonoBehaviour
{
public float sensitivity = 1000f;
public float xRotation = 0f;
public Transform playerBody;
public Quaternion localRotate;
// Start is called before the first frame update
void Start()
{
Cursor.lockState = CursorLockMode.Locked;
}
// Update is called once per frame
void Update()
{
float MX = Input.GetAxis("Mouse X")*sensitivity*Time.deltaTime;
float MY = Input.GetAxis("Mouse Y")*sensitivity*Time.deltaTime;
xRotation -= MY;
xRotation = Mathf.Clamp(xRotation,-90f,90f);
transform.localRotation = Quaternion.Euler(xRotation,0f,0f);
localRotate = transform.localRotation;
playerBody.Rotate(Vector3.up * MX);
}
}
the player body you see is the player object to you character...
note that the camera is use is not In. cinema chine and is inside of the player...

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.

Android headtracking with gyroscope, initial direction [duplicate]

I would like to enable gyro controlled camera onButtonClick event but I want it to start at the camera's current position. Currently when the gyro gets enabled it moves the camera off to a new position (probably the devices current gyro rotation) rather than leaving it where it is and gyro-ing from that point.
Hope I'm making sense, but basically I don't want the user to notice any change in what they are seeing in the game (ie. camera controlled by gyro but not that user would notice that change). Here's the code I'm using:
void Update ()
{
Quaternion attitudeFix = new Quaternion (-gyro.attitude.x, -gyro.attitude.z, -gyro.attitude.y, gyro.attitude.w);
Quaternion offsetRotation = initialGyroRotation * attitudeFix;
rotation = initialRotation * offsetRotation;
transform.rotation = rotation;
}
public void EnableGyro()
{
initialGyroRotation = Input.gyro.attitude;
initialRotation = transform.rotation;
Debug.Log("initialRotation: " + initialRotation.ToString());
Debug.Log("transform.rotation: " + transform.rotation.ToString());
Debug.Log("initialGyroRotation: " + initialGyroRotation.ToString());
}
**
EDIT: Here's a screen of exactly how I want the view to look as the user is holding their device in front of their face (portrait) AND heading north. Regardless of the orientation of the device when the app starts, this is how it should look when heading north with phone in portrait orientation (again as the user is looking through the phone).
EDIT 2:
Tests were getting confusing so I put the code back to exactly how your solution suggests. There is still a slight problem, but it seems like this script is very close. The main problem is the screen doesn't look like the above pic when I run each test, starting the app with the device on strange angles. It really shouldn't matter what angle the device is when the app is started, it needs to look like the above screen when pointing north and portrait.
I need to do more tests, and will do so with a new/clean project.
You need to get the offset camera position in the Awake or Start function. In the Update function, apply that offset value to the value from the gyro sensor.
It looks like you already know offset should be used but you are not doing that the right way. The confusing part is getting the offset which requires subtracting the current camera rotation from the gyro sensor value.
To subtract a Quaternion multiply the Inverse not just the Quaternion:
Quaternion = Quaternion *Quaternion.Inverse
To add a Quaternion multiply the Quaternion:
Quaternion = Quaternion * Quaternion.
This is what your code should look like:
Quaternion offset;
void Awake()
{
Input.gyro.enabled = true;
}
void Start()
{
//Subtract Quaternion
offset = transform.rotation * Quaternion.Inverse(GyroToUnity(Input.gyro.attitude));
}
void Update()
{
GyroModifyCamera();
}
void GyroModifyCamera()
{
//Apply offset
transform.rotation = offset * GyroToUnity(Input.gyro.attitude);
}
private static Quaternion GyroToUnity(Quaternion q)
{
return new Quaternion(q.x, q.y, -q.z, -q.w);
}
I hade trouble with this and it wasn't working in build this is what I found and this script has worked.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class GyroMovement : MonoBehaviour
{
// Start is called before the first frame update
//Movement
[SerializeField] float speed = 3.3f;
private float rotspeed = 90f;
private Vector3 moveDirection = Vector3.zero;
[SerializeField] private CharacterController controller;
//Rotation
private float _initialYAngle = 0f;
private float _appliedGyroYAngle = 0f;
private float _calibrationYAngle = 0f;
private Transform _rawGyroRotation;
private float _tempSmoothing;
//settings
private float _smoothing = 0.1f;
private void Update(){
//Movement
//Vector3 move = new Vector3 (Input.acceleration.x * speed * Time.deltaTime, 0f, -Input.acceleration.z * speed * Time.deltaTime);
//Vector3 rotMovement = transform.TransformDirection(move);
//controller.Move(rotMovement);
//Rotation
ApplyGyroRotation();
ApplyCalibration();
transform.rotation = Quaternion.Slerp(transform.rotation, _rawGyroRotation.rotation, _smoothing);
}
private IEnumerator Start(){
Input.gyro.enabled = true;
Application.targetFrameRate = 60;
_initialYAngle = transform.eulerAngles.y;
_rawGyroRotation = new GameObject("GyroRaw").transform;
_rawGyroRotation.position = transform.position;
_rawGyroRotation.rotation = transform.rotation;
yield return new WaitForSeconds(1f);
StartCoroutine (CalibrateYAngle());
}
private IEnumerator CalibrateYAngle(){
_tempSmoothing = _smoothing;
_smoothing = 1f;
_calibrationYAngle = _appliedGyroYAngle - _initialYAngle;
yield return null;
_smoothing = _tempSmoothing;
}
private void ApplyGyroRotation(){
_rawGyroRotation.rotation = Input.gyro.attitude;
_rawGyroRotation.Rotate(0f, 0f, 180f, Space.Self);
_rawGyroRotation.Rotate(90f, 180f, 0f, Space.World);
_appliedGyroYAngle = _rawGyroRotation.eulerAngles.y;
}
private void ApplyCalibration(){
_rawGyroRotation.Rotate(0f, -_calibrationYAngle, 0f, Space.World);
}
public void SetEnabled (bool value){
enabled = true;
StartCoroutine(CalibrateYAngle());
}
}

First Person Controller camera rotation doesn't work

I'm looking for some c# script on unity to update first person controller
camera rotation transform. More specificly, I'm running an animation, and by the end of animation, I set "movie camera transform" on fps camera transform, how to show the code. For position variable, everything is ok. However, rotation variable doesn't work well.
The variable get the transform rotation right (the same movie camera transform), but I can't see the change on scene. The "first person controller rotation transform"
always get the last rotation coordinate that happened.
I already tested many rotation functions, like Rotate(Vector3), rotation, localRotation, eulerAngles, localEulerAngles....
Vector3 pos, roteuler;
public Camera fpscam, movie;
void getPosRot(){
roteuler = movie.transform.eulerAngles;
pos = movie.transform.position;
}
void Update(){
fps.transform.position = pos;
fps.transform.eulerAngles = roteuler;
}
Here is the camera part of my FPS script:
public class PlayerController : MonoBehaviour
{
float RotateX;
float RotateY;
public GameObject Camera;
public float RotationSpeed = 3.0f;
public float MaxYAxis = 60.0f;
public float MinYAxis = -48.0f;
private void Start()
{
}
void Update()
{
Rotation();
}
void Rotation()
{
RotateX += Input.GetAxis("Mouse X") * RotationSpeed;
RotateY += Input.GetAxis("Mouse Y") * RotationSpeed;
RotateY = Mathf.Clamp(RotateY, MinYAxis, MaxYAxis);
Camera.transform.localRotation = Quaternion.Euler(-RotateY, 0f, 0f);
transform.rotation = Quaternion.Euler(0f, RotateX, 0f);
}
}

How to make a Game Object point towards the mouse in Unity? (C#)

I am creating a game involving a turret and it needs to "point" (that is, rotate) to the mouse. It's in 3-D environment, but at a bird's eye view. So for my purposes we are in a 2-D environment.
Here is my code:
using UnityEngine;
using System.Collections;
public class Turret : MonoBehaviour {
// Use this for initialization
void Start () {
}
int speed; float friction; float lerpSpeed ; private float xDeg ;
private float yDeg; private Quaternion fromRotation; private Quaternion toRotation;
void Update () {
xDeg -= Input.GetAxis ("Mouse X"); yDeg += Input.GetAxis ("Mouse Y");
fromRotation = transform.rotation;
toRotation = Quaternion.Euler(yDeg,xDeg,0);
transform.rotation = Quaternion.Lerp(fromRotation,toRotation,Time.deltaTime * lerpSpeed);
}
}
If you could tell me what I'm doing wrong or give me the correct code that would be great! Please note that I am using a C# script.
Input and rotation calculations are not right.
xDeg -= Input.GetAxis ("Mouse X"); yDeg += Input.GetAxis ("Mouse Y");
toRotation = Quaternion.Euler(yDeg,xDeg,0);
You are making a top down game. So I assume that you are trying to aim at where mouse points on a 2D plane, which is ground. You should get your input not based on mouse axes but taking account where your mouse cursor is.
That being said, you can use this method to achieve your goal:
public class CharacterInput : MonoBehaviour
{
public Transform CharacterTransform;
void Update()
{
var groundPlane = new Plane(Vector3.up, -CharacterTransform.position.y);
var mouseRay = Camera.main.ScreenPointToRay(Input.mousePosition);
float hitDistance;
if (groundPlane.Raycast(mouseRay, out hitDistance))
{
var lookAtPosition = mouseRay.GetPoint(hitDistance);
CharacterTransform.LookAt(lookAtPosition, Vector3.up);
}
}
}
And to rotate it smoothly:
public class CharacterInput : MonoBehaviour
{
public Transform CharacterTransform;
public float RotationSmoothingCoef = 0.1f;
void Update()
{
var groundPlane = new Plane(Vector3.up, -CharacterTransform.position.y);
var mouseRay = Camera.main.ScreenPointToRay(Input.mousePosition);
float hitDistance;
if (groundPlane.Raycast(mouseRay, out hitDistance))
{
var lookAtPosition = mouseRay.GetPoint(hitDistance);
var targetRotation = Quaternion.LookRotation(lookAtPosition - CharacterTransform.position, Vector3.up);
var rotation = Quaternion.Lerp(CharacterTransform.rotation, targetRotation, RotationSmoothingCoef);
CharacterTransform.rotation = rotation;
}
}
}
Better calculate smoothing in FixedUpdate to make it independent of frames per second. So it rotates at the same speed on every computer configuration:
public class CharacterInput : MonoBehaviour
{
public Transform CharacterTransform;
public float RotationSmoothingCoef = 0.01f;
private Quaternion targetRotation;
void Update()
{
var groundPlane = new Plane(Vector3.up, -CharacterTransform.position.y);
var mouseRay = Camera.main.ScreenPointToRay(Input.mousePosition);
float hitDistance;
if (groundPlane.Raycast(mouseRay, out hitDistance))
{
var lookAtPosition = mouseRay.GetPoint(hitDistance);
targetRotation = Quaternion.LookRotation(lookAtPosition - CharacterTransform.position, Vector3.up);
}
}
void FixedUpdate()
{
var rotation = Quaternion.Lerp(CharacterTransform.rotation, targetRotation, RotationSmoothingCoef);
CharacterTransform.rotation = rotation;
}
}
I think this is a common mistake for a Unity beginner (as I had it wrong the first time as well).
As you probably know by now, the Update() method is called every new frame.
So, every new frame (in your code) you calculate where the mouse is, how to rotate and call Lerp.
What you probably miss is how Lerp works and that is interpolating the motion by making one step every frame , i.e every time Lerp is called it rotates (in your case) by some interval. Your interval is Time.deltaTime * lerpSpeed which changes every frame since Time.deltaTime is the time between 2 consecutive frames.
So to make Lerp work properly (== smooth interpolation) you must call it with the same start and end position and complete the interpolation between them (call Lerp from 0 to 1 with as many intervals as you wish).
What I suggest you do is move this code:
xDeg -= Input.GetAxis ("Mouse X"); yDeg += Input.GetAxis ("Mouse Y");
fromRotation = transform.rotation;
toRotation = Quaternion.Euler(yDeg,xDeg,0);
to a different place (one which Update has access to these variables) and:
Set toRotation everytime it should move (xDeg can be computed along side)
Remove fromRotation and instead call Lerp like this:
Lerp(transform.rotation, toRotation,Time.deltaTime * lerpSpeed)

Categories