0

I'm working on developing a game, and my current roadblock is Camera Rotation. I want the mouse to control the camera, and when the camera turns, I want to rotate the player as well. However, the code I am using rotates the player object COMPLETELY with the player, causing the player to turn like this:

Forward Rotation of player

The player rotating forward not only looks strange, but causes clipping problems with the terrain. How do I make my code only rotate the player along one axis, while allowing the camera to rotate along any axis (to allow the audience to look around, without the player object being turned upwards or down).

this is the code that is rotating the player:

Quaternion QT = Quaternion.Euler(_LocalRotation.y, _LocalRotation.x, 0);
    this._XForm_Parent.rotation = Quaternion.Lerp(this._XForm_Parent.rotation, QT, Time.deltaTime * OrbitDampening);

    if (this._XForm_Camera.localPosition.z != this._CameraDistance * -1f)
    {
        this._XForm_Camera.localPosition = new Vector3(0f, 0f, Mathf.Lerp(this._XForm_Camera.localPosition.z, this._CameraDistance * -1f, Time.deltaTime * ScrollDampening));
    }

and this is the complete script I am using:

using System.Collections;

using System.Collections.Generic; using UnityEngine;

public class CameraOrbit : MonoBehaviour {

protected Transform _XForm_Camera;
protected Transform _XForm_Parent;

protected Vector3 _LocalRotation;
protected float _CameraDistance = 10f;

public float MouseSensitivity = 4f;
public float ScrollSensitvity = 2f;
public float OrbitDampening = 10f;
public float ScrollDampening = 6f;

public bool CameraDisabled = false;


// Use this for initialization
void Start()
{
    this._XForm_Camera = this.transform;
    this._XForm_Parent = this.transform.parent;
}


void LateUpdate()
{
    if (Input.GetKeyDown(KeyCode.LeftShift))
        CameraDisabled = !CameraDisabled;

    if (!CameraDisabled)
    {
        //Rotation of the Camera based on Mouse Coordinates
        if (Input.GetAxis("Mouse X") != 0 || Input.GetAxis("Mouse Y") != 0)
        {
            _LocalRotation.x += Input.GetAxis("Mouse X") * MouseSensitivity;
            _LocalRotation.y += Input.GetAxis("Mouse Y") * MouseSensitivity;

            //Clamp the y Rotation to horizon and not flipping over at the top
            if (_LocalRotation.y < 0f)
                _LocalRotation.y = 0f;
            else if (_LocalRotation.y > 90f)
                _LocalRotation.y = 90f;
        }
        //Zooming Input from our Mouse Scroll Wheel
        if (Input.GetAxis("Mouse ScrollWheel") != 0f)
        {
            float ScrollAmount = Input.GetAxis("Mouse ScrollWheel") * ScrollSensitvity;

            ScrollAmount *= (this._CameraDistance * 0.3f);

            this._CameraDistance += ScrollAmount * -1f;

            this._CameraDistance = Mathf.Clamp(this._CameraDistance, 1.5f, 100f);
        }
    }
    //Actual Camera Rig Transformations
    Quaternion QT = Quaternion.Euler(_LocalRotation.y, _LocalRotation.x, 0);
    this._XForm_Parent.rotation = Quaternion.Lerp(this._XForm_Parent.rotation, QT, Time.deltaTime * OrbitDampening);

    if (this._XForm_Camera.localPosition.z != this._CameraDistance * -1f)
    {
        this._XForm_Camera.localPosition = new Vector3(0f, 0f, Mathf.Lerp(this._XForm_Camera.localPosition.z, this._CameraDistance * -1f, Time.deltaTime * ScrollDampening));
    }


}

}

A picture of my heirarchy: (Please note that Player is an empty object containing all of my scripts and physics components, whereas the GFXs component is simply the model, with an animator component clean of any physics components.)

Unity Heirarchy

1 Answer 1

0

It sounds like what you want is basically to rotate the player around its local Y axis until it is facing the same direction as the camera. You can find out if things are facing the same direction using Vector3.SignedAngle and passing in the axis that you care about. Here is some sample code that should get you going.

float turnThresholdDegrees = 15;
float playerTurnSpeed = 1;

// Get delta angle in degrees on the Y axis between the direction player is facing and the direction camera is facing
float angleDelta = Vector3.SignedAngle(player.transform.forward, camera.transform.forward, Vector3.up);

// Calculate a rotation speed, clamping it to 0 when the angle delta is < some threshold
float rotateSpeed = Mathf.Abs(angleDelta) > turnThresholdDegrees ? Mathf.Sign(angleDelta) * playerTurnSpeed : 0;

// Rotate the player around its local Y axis by the rotation speed
player.transform.Rotate(0, rotateSpeed * Time.deltaTime, 0, Space.Self);
Sign up to request clarification or add additional context in comments.

5 Comments

the line float rotateSpeed = Mathf.Abs(angleDelta) > turnThresholdDegrees : Mathf.Sign(angleDelta) * playerTurnSpeed : 0; throws a bunch of errors. Could you explain how I would use this code to make the player rotation(Y axis) match the camera rotation (y axis) ?
What are the errors? I wrote this without a compiler so there may be some typos. This should be pretty much drop-in compatible, you just need to change names of things to reference your camera / player transforms. So in the place where you are currently trying to rotate the player to match the camera, you'd put this code instead (replacing names where necessary)
Here's a picture of it it Visual Studio Code: imgur.com/a/2nYazt2
Ah oops, I accidently put a : where there should be a ?, float rotateSpeed = Mathf.Abs(angleDelta) > turnThresholdDegrees ? Mathf.Sign(angleDelta) * playerTurnSpeed : 0; sorry about that!
That line by the way, is just shorthand for float rotateSpeed = 0; if (Mathf.Abs(angleDelta) > turnThresholdDegrees) rotateSpeed = Mathf.Sign(angleDelta);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.