I am making code for a first person physics-based character controller in Unity. The movement is mostly smooth, but when I go up a slope, instead of sliding back down, the character floats in the air slightly while slowly moving downward until it gets back to the ground. This behavior is very strange and unexpected, and I don't really know why this is happening.
The character is an empty object with a capsule and a sphere childed to it. The script is on the empty object, and the rigidbody is on the capsule which is a child to the empty. Here is the script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
float mouseSensitivity;
private float cameraXRotation;
private float cameraYRotation;
private float movementX;
private float movementY;
private Transform playerHeadTransform;
private Transform playerBodyTransform;
private Rigidbody playerRigidBody;
private bool IsJumping;
// Start is called before the first frame update
void Start()
{
Cursor.lockState = CursorLockMode.Locked;
playerBodyTransform = transform.GetChild(0).gameObject.GetComponent<Transform>();
playerHeadTransform = transform.GetChild(0).transform.GetChild(0).gameObject.GetComponent<Transform>();
playerRigidBody = transform.GetChild(0).gameObject.GetComponent<Rigidbody>();
playerHeadTransform.transform.rotation = Quaternion.Euler(0f, 0f, 0f);
mouseSensitivity = 750;
IsJumping = false;
}
// Update is called once per frame
void Update()
{
#region CameraStuff
float cameraMouseX = Input.GetAxis("Mouse X") * mouseSensitivity * Time.deltaTime;
float cameraMouseY = Input.GetAxis("Mouse Y") * mouseSensitivity * Time.deltaTime;
cameraXRotation -= cameraMouseY;
cameraYRotation = cameraMouseX;
cameraXRotation = Mathf.Clamp(cameraXRotation, -90f, 60);
playerHeadTransform.localRotation = Quaternion.Euler(cameraXRotation, 0f, 0f);
playerBodyTransform.localRotation = Quaternion.Euler(0f, cameraYRotation, 0f);
#endregion
//Movement input variables
movementX = Input.GetAxis("Horizontal") * mouseSensitivity * Time.deltaTime;
movementY = Input.GetAxis("Vertical") * mouseSensitivity * Time.deltaTime;
}
void FixedUpdate()
{
playerRigidBody.velocity = playerBodyTransform.TransformDirection(movementX*2, 0, movementY*2);
}
}
CodePudding user response:
Your player not falling down is most probably related to you setting
void FixedUpdate()
{
playerRigidBody.velocity = playerBodyTransform.TransformDirection(movementX*2, 0, movementY*2);
}
if there is gravity involved you rather want to make sure to not overwrite the Y
axis and do e.g.
var currentVelocity = playerRigidbody.velocity;
var newVelocity = playerBodyTransform.TransformDirection(movementX * 2, 0, movementY * 2);
// keep the velocity on Y but only if it is currently downwards
// so you can still move up on a slope but fall down with gravity
if(currentVelocity.y < 0) newVelocity.y = currentVelocity.y;
playerRigidBody.velocity = newVelocity;