简体   繁体   中英

clamping a vertical rotation in Unity

I started a FPS project. I have a capsule as a Player, an empty GO as the head and the camera is the child object of the head.

On the vertical Axis, I clamp my y-rotation to -70 (min) and 70 (max). Surprisingly the value does not get clamped.

    [SerializeField]
    private Transform playerHead;

    float inputHorizontal;
    float inputVertical; 

    float sensitivity = 50;

    float yMin = -70;
    float yMax = 70;

    Vector2 direction; // movement direction

Transform playerTransform;

void Start()
{
playerTransform = GameObject.FindGameObjectWithTag("Player").transform;
}

    private void Update()
    {
        inputHorizontal = Input.GetAxisRaw("Mouse X");
        inputVertical = -Input.GetAxisRaw("Mouse Y"); // Inverted Input!

        direction = new Vector2(
                inputHorizontal * sensitivity * Time.deltaTime,
                Mathf.Clamp(inputVertical * sensitivity * Time.deltaTime, yMin, yMax)); // The horizontal movement and the clamped vertical movement

        playerTransform.Rotate(0, direction.x, 0);
        playerHead.Rotate(direction.y, 0, 0);
    }

The value

direction.y

gets clamped but I can still turn around my head by 360 degrees..

You are clamping your delta rotation - not your actual rotation. Said in another way, direction is not the final rotation, it is the change in rotation. What you are effectively doing, is limiting the rotation to 70 degrees per frame.

You probably want to limit the actual rotation of playerHead , for example by adding the following lines to the end of update:

Vector3 playerHeadEulerAngles = playerHead.rotation.eulerAngles;
playerHeadEulerAngles.y = Mathf.Clamp(playerHeadEulerAngles.y, yMin, yMax);
playerHead.rotation = Quaternion.Euler(playerHeadEulerAngles);

There is also no reason to create a direction vector, when you are using each component separately anyway.

Clamp the final Y direction value not the current mouse movement -

[SerializeField]
private Transform playerHead;

float inputHorizontal;
float inputVertical; 

float sensitivity = 50;

float yMin = -70;
float yMax = 70;

Vector2 direction; // movement direction
float currYDir = 0,prevYDir = 0;

Transform playerTransform;

void Start()
{
playerTransform = GameObject.FindGameObjectWithTag("Player").transform;
}

private void Update()
{
    inputHorizontal = Input.GetAxisRaw("Mouse X");
    inputVertical = -Input.GetAxisRaw("Mouse Y"); // Inverted Input!

    direction = new Vector2(
            inputHorizontal * sensitivity * Time.deltaTime,
            inputVertical * sensitivity * Time.deltaTime); // The horizontal movement and the clamped vertical movement

    playerTransform.Rotate(0, direction.x, 0);

    currYDir = prevYDir + direction.y;
    currYDir = Mathf.Clamp(currYDir, yMin, yMax);
    playerHead.Rotate(currYDir-prevYDir, 0, 0);

    prevYDir = currYDir;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM