Hi, there! I started learning Unity about a month ago by following a tutorial on YouTube, and the last few days I’ve been trying to make a basic first-person camera + movement object using a Character Controller component. At first I ran into a problem with the Character Controller using absolute directional values instead of relative ones, but now I’ve run into a new problem: when I rotate my view up or down at all (as in, rotating around the X axis), the player’s movement has a few hiccups. If I look up or down when I move forward, the player’s movement starts to slow down, coming to a complete stop when I look exactly 90 degrees up or down. I know that the problem is that the player is attempting to move “forward,” which in this case is either straight up (against gravity) or into the ground, I just don’t know how to fix it. I’ve been trying to think of how to fix this problem using an absolute rotational value or something, but I’m completely stuck trying to work out the math. Any help at all would be appreciated, thank you!
Here is my camera script:
public float sensitivity;
public float minTurnAngle;
public float maxTurnAngle;
private float rotX;
void Update()
{
MouseAiming();
}
void MouseAiming()
{
// get the mouse inputs
float y = Input.GetAxis("Mouse X") * sensitivity;
rotX += Input.GetAxis("Mouse Y") * sensitivity;
// clamp the vertical rotation
rotX = Mathf.Clamp(rotX, minTurnAngle, maxTurnAngle);
// rotate the camera
transform.eulerAngles = new Vector3(-rotX, transform.eulerAngles.y + y, 0);
}
And here is my movement script:
private CharacterController playerController;
private float playerHeight;
private Vector3 playerVelocity;
public float playerSpeed;
private bool playerGrounded;
private bool playerCrouching;
public float playerSpeedCrouchMultiplier;
public float playerJumpHeight;
// Start is called before the first frame update
void Start()
{
playerController = GetComponent<CharacterController>();
playerHeight = playerController.height;
playerCrouching = false;
playerGrounded = true;
}
// Update is called once per frame
void Update()
{
// WASD movement
Vector3 input = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical")); // Get inputs
if (playerCrouching) // check if player is crouching
{
input *= playerSpeedCrouchMultiplier;
}
Vector3 move = transform.TransformDirection(input.normalized) * playerSpeed; // Change direction
// Is player mid-air
playerGrounded = playerController.isGrounded;
if (playerGrounded && playerVelocity.y < 0)
{
playerVelocity.y = 0f;
}
// Jumping
if (Input.GetButtonDown("Jump") && playerGrounded && !playerCrouching)
{
playerVelocity.y += Mathf.Sqrt(playerJumpHeight * -3.0f * References.gravity);
}
playerVelocity.y += References.gravity * Time.deltaTime;
// Crouching
if (Input.GetButton("Crouch"))
{
playerCrouching = true;
playerController.height = playerHeight * 0.5f;
}
else
{
playerCrouching = false;
playerController.height = playerHeight;
}
//Move
playerController.Move(move * Time.deltaTime);
playerController.Move(playerVelocity * Time.deltaTime);
}