MAKE FIRST-PERSON PLAY CONTROLLER.

First-person controllers require the Camera to respond to mouse movements (X Y).

This function sounds easy, but not because I debugged it for hours.

First, I break down this function into 3 parts.

  • Mouse horizontal movement pan the camera.
  • Mouse vertical movemnet control the camera looking up and looking down.
  • Set a limite to camera vertical rotation angle. (Prevents the camera from being able to rotate infinitely vertically)
The Camera responds to mouse movements Demo.
 void Cam_Rotate()//mouse control camera looking around
    {
        float h = Input.GetAxis("Mouse X");
        float v = Input.GetAxis("Mouse Y");
        if (h != 0)
        {
            this.gameObject.transform.Rotate(0, h * Time.fixedDeltaTime * RotateSpeed, 0);//RotateSpeed is a folat variate
        }
        if (v != 0)//Actually it a stuped way to set a limit to the camera rotation anglem, because i used 4 if here.
        {
            if (FirstPersonControllerCamera.transform.rotation.eulerAngles.x< AngleLimit && FirstPersonControllerCamera.transform.rotation.eulerAngles.x<180)
            {
                FirstPersonControllerCamera.transform.Rotate(v * Time.fixedDeltaTime * -RotateSpeed, 0, 0);//set camera rotate
            }
            else if (FirstPersonControllerCamera.transform.rotation.eulerAngles.x > (360- AngleLimit) && FirstPersonControllerCamera.transform.rotation.eulerAngles.x >180)
            {
                FirstPersonControllerCamera.transform.Rotate(v * Time.fixedDeltaTime * -RotateSpeed, 0, 0);
            }
            else if (FirstPersonControllerCamera.transform.rotation.eulerAngles.x <=(360- AngleLimit) && FirstPersonControllerCamera.transform.rotation.eulerAngles.x > 180)
            {
                FirstPersonControllerCamera.transform.Rotate(0.5f, 0, 0);
            }
            else if (FirstPersonControllerCamera.transform.rotation.eulerAngles.x >= AngleLimit && FirstPersonControllerCamera.transform.rotation.eulerAngles.x < 180)
            {
                FirstPersonControllerCamera.transform.Rotate(-0.5f, 0, 0);
            }
        }
    }

The code above works but can not satisfy my demands. Because the solution I achieve setting the angle limit is when the angle achieves the maximum value, the angle will sub 0.1 degrees. So the play will find the view shaking when they try to look up or looking down, just like the video below.

View Shaking

However, Github gave me a suggestion to use the method (Mathf.Clamp) provided by Unity Engine. As we can see in the video below, the view is more shaking.

Debugged Camera
void CameraRotate()//mouse control camera looking around
    {
        YLimited += MouseY * Time.deltaTime * RotateSpeed;
        FirstPersonCamera.transform.localRotation = Quaternion.Euler(Mathf.Clamp(YLimited, 45, 135), 0.0f, 0.0f);
        transform.Rotate(0, MouseX * Time.deltaTime * RotateSpeed, 0);
    }

As we can see in the code above. Mathf.Clamp limit the
variate Withing 45 and 135, And this solution will not cause any view shaking.

Some notes I made during the building of the FPP controller.

1.

There is the controller layers screenshot.

The character is the FirstPersonCamera’s parent. FirstPersonCamera is an empty object used to adjust the angle of the Camera. Because without this empty object, the Camera looks up 10 degrees, the Camera’s rotation is 350 degrees, and the Camera looks down 10 degrees, the rotation of the Camera is -10 degrees. In this way, I can not use Mathf.Clamp.

When the mouse movement is horizontal, the character will rotate around the Y-axis. The empty object FirstPersonCamera will rotate around the X-axis when vertical mouse movement.

Ok, I have achieved the first function.

After the function Camera looks around, here I come to the translation.

First, I break down this function into 2 parts.

  • The player is grounded.
  • The player is not grounded.

The second condition is easy to figure out, just set the character translation on Y-axis negative direction until the player is grounded.

Only if the character is grounded