Cant get character to rotate as intended

Good afternoon!

I am starting to play with unity, and am trying to create a 3rd person camera with some specific traits. Most of what I have is working but no matter what I do I cant get it to rotate when holding down a/d

Currently the character uses the following script. and when I turn the camera (using Q and E) it updates and moves along the camera’s front axis, But what I want to do is when its not moving I want the transform to rotate and look in the direction I am pressing (Weather it is A or D , Kind of like a strafe).

Any help would be great, Here is the script I have modified.

void FixedUpdate ()
{

		var targetVelocity = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
		targetVelocity = transform.TransformDirection(targetVelocity);
		targetVelocity *= speed;


		Vector3 velocity = rigidbody.velocity;
		Vector3 velocityChange = (targetVelocity - velocity);
		velocityChange.x = Mathf.Clamp(velocityChange.x, -maxVelocityChange, maxVelocityChange);
		velocityChange.z = Mathf.Clamp(velocityChange.z, -maxVelocityChange, maxVelocityChange);
		velocityChange.y = 0;
		rigidbody.AddForce(velocityChange, ForceMode.VelocityChange);

                   //update traveling forward position relative to the camera.
		Vector3 toLook = Camera.allCameras[0].transform.forward*TurnSpeed;
		transform.rotation = Quaternion.LookRotation(new Vector3(toLook.x,0.0f,toLook.z), Vector3.up);

		// Jump
		if (canJump && Input.GetButton("Jump") && grounded)
		{
			rigidbody.velocity = new Vector3(velocity.x, CalculateJumpVerticalSpeed(), velocity.z);
		}

	// We apply gravity manually for more tuning control
	rigidbody.AddForce(new Vector3 (0, -gravity * rigidbody.mass, 0));

	grounded = false;
}

You can track whether the player is moving or not by checking the velocityChange value. To ease things, create a boolean value in order to show whether moving or not.

private bool isMoving;

isMoving = velocityChange > 0.1f ? true : false; // I wrote 0.1f just to be sure, if there occurs any problem, you can debug the velocityChange value when moving and not moving, and increase 0.1f according to that.

And now we have to check if any of A or D keys is pressed, if so and if not moving, apply rotation change.

public float rotateAmount;
public float rotateSpeed;

void Update()
{
 if(Input.GetAxis("Horizontal") != 0 && !isMoving)
 {
   
   float rotationValue = Input.GetAxis("Horizontal") * rotateAmount;
   Quaternion newRot = Quaternion.Euler(transform.eulerAngles.x, rotationValue, transform.eulerAngles.z);
   transform.rotation = Quaternion.Lerp(transform.rotation, newRot, Time.deltaTime * rotateSpeed);
   
 }
}

Now this will keep rotating as long as the user presses A or D keys, in order to limit that rotation, for example to 90 degrees, you have couple of ways. First, clamping the rotationValue :

float rotationValue = Input.GetAxis("Horizontal") * rotateAmount;
rotationValue = Mathf.Clamp(rotationValue, -90,90);

Second, you can directly rotate the player to a desired rotation. You can achieve this by creating coroutines or managing booleans in update.

private bool rotateLeft;
private bool rotateRight;

    void Update()
    {
     if(Input.GetKeyDown("a"))
     {
      rotateLeft = true;
      rotateRight = false;
     }
    
     if(Input.GetKeyDown("d"))
     {
      rotateLeft = false;
      rotateRight = true;
     }
    
     if(rotateLeft)
     {
      transform.rotation = Quaternion.Lerp(transform.rotation, Quaternion.Euler(transform.eulerAngles.x, -60, transform.eulerAngles.z); // rotate to -60 along Y Axis
     }
    
     if(rotateRight)
     {
      transform.rotation = Quaternion.Lerp(transform.rotation, Quaternion.Euler(transform.eulerAngles.x, 60, transform.eulerAngles.z); // rotate to 60 along Y axis
     }
    }

Also another way, you can create just one bool, and a value for desired rotation and manage them with inputs.

private bool canRotate;
public float desiredAngle;

void Update()
{
 if(Input.GetAxis("Horizontal") < 0)
 {
  canRotate = true;
  desiredAngle = -60;
 }
 else if(Input.GetAxis("Horizontal") > 0)
 {
  canRotate = true;
  desiredAngle = 60;
 }
 else{
 canRotate = false;
 }

 if(canRotate) 
  trasform.rotation =  Quaternion.Lerp(transform.rotation, Quaternion.Euler(transform.eulerAngles.x, desiredAngle, transform.eulerAngles.z);
 
}
  • PS. I am not exactly sure how
    quaternions going to react to a
    negative rotation values, it should
    just do fine. ( I mean it may rotate
    from the wrong side, but I don’t
    think there will be a problem.)

  • PS. I wrote these lines thinking that
    your player does not have any parent,
    if so using local rotations will be a
    better idea. To achieve that, just
    change transform.rotation to
    transform.localRotation, and
    transform.eulerAngles to
    transform.localEulerAngles.

Hope that these helped :slight_smile: