- Home /
Rigidbody character controller issues
I'm working on a character controller, everything works fine except two things and I can't find a way to solve this :( This is the code of my controller script :
using UnityEngine;
public class ControlsManager : MonoBehaviour
{
public Transform playerBody;
private Rigidbody _rigidbody;
private Transform _playerCamera;
private Vector2 _mousePosition;
private Vector2 _precMousePosition;
private float _rJoystickX;
private float _rJoystickY;
private float _sprint;
private bool _jump;
private Vector3 _bodyTranslation;
private bool _bodyTranslationChange;
private Vector3 _bodyRotation;
private bool _bodyRotationChange;
private Vector3 _cameraRotation;
private bool _cameraRotationChange;
private void Awake()
{
_rigidbody = playerBody.GetComponent<Rigidbody>();
_playerCamera = Utilities.mainCamera.transform;
_mousePosition = Input.mousePosition;
}
private void Update()
{
_sprint = 1;
// Cursor lock for camera rotation
if (Input.GetKeyDown(Utilities.controls.lockCursorMouse))
{
if (Cursor.lockState == CursorLockMode.None)
{
Cursor.visible = false;
Cursor.lockState = CursorLockMode.Locked;
}
else
{
Cursor.visible = true;
Cursor.lockState = CursorLockMode.None;
}
}
if (!Utilities.isGamePaused)
{
if (Input.GetJoystickNames().Length > 0 && Input.GetJoystickNames()[0] != "")
{
// Camera rotation for controller
_rJoystickX = Input.GetAxis("RJoystickX");
_rJoystickY = Input.GetAxis("RJoystickY");
if (_rJoystickX != 0) {
_bodyRotation.y += Utilities.controls.controllerSens * _rJoystickX * Time.deltaTime;
_bodyRotationChange = true;
}
if (_rJoystickY != 0)
{
_cameraRotation.x += Utilities.controls.controllerSens * _rJoystickY * Time.deltaTime;
_cameraRotationChange = true;
}
// Movements for controller
if(Input.GetKey(Utilities.controls.sprintController))
{
_sprint = 1.6f;
}
if (Input.GetAxis("LJoystickY") > 0)
{
_bodyTranslation += playerBody.forward * _sprint * Time.deltaTime;
_bodyTranslationChange = true;
}
if (Input.GetAxis("LJoystickY") < 0)
{
_bodyTranslation -= playerBody.forward * Time.deltaTime;
_bodyTranslationChange = true;
}
if (Input.GetAxis("LJoystickX") < 0)
{
_bodyTranslation -= playerBody.right * Time.deltaTime;
_bodyTranslationChange = true;
}
if (Input.GetAxis("LJoystickX") > 0)
{
_bodyTranslation += playerBody.right * Time.deltaTime;
_bodyTranslationChange = true;
}
}
if (Cursor.lockState == CursorLockMode.Locked)
{
// Camera rotation for mouse
_precMousePosition = _mousePosition;
_mousePosition.x = Input.GetAxis("Mouse X");
_mousePosition.y = Input.GetAxis("Mouse Y");
if (_mousePosition.x != _precMousePosition.x)
{
_bodyRotation.y += _mousePosition.x * Utilities.controls.mouseSens;
_bodyRotationChange = true;
}
if (_mousePosition.y != _precMousePosition.y)
{
_cameraRotation.x += -_mousePosition.y * Utilities.controls.mouseSens;
_cameraRotationChange = true;
}
// Movements for mouse
_sprint = 1;
if(Input.GetKey(KeyCode.LeftShift))
{
_sprint = 1.6f;
}
if (Input.GetKeyDown(KeyCode.Space))
{
_jump = true;
}
if (Input.GetKey(Utilities.controls.forward))
{
_bodyTranslation += playerBody.forward * (_sprint * Time.deltaTime);
_bodyTranslationChange = true;
}
if (Input.GetKey(Utilities.controls.backward))
{
_bodyTranslation -= playerBody.forward * Time.deltaTime;
_bodyTranslationChange = true;
}
if (Input.GetKey(Utilities.controls.left))
{
_bodyTranslation -= playerBody.right * Time.deltaTime;
_bodyTranslationChange = true;
}
if (Input.GetKey(Utilities.controls.right))
{
_bodyTranslation += playerBody.right * Time.deltaTime;
_bodyTranslationChange = true;
}
///////////////////////////////// Debug
if (Input.GetKey(KeyCode.DownArrow))
{
_bodyTranslation -= playerBody.up * Time.deltaTime;
_bodyTranslationChange = true;
}
if (Input.GetKey(KeyCode.UpArrow))
{
_bodyTranslation += playerBody.up * Time.deltaTime;
_bodyTranslationChange = true;
}
}
}
// Rotations
if (_bodyRotationChange)
{
playerBody.localRotation *= Quaternion.Euler(_bodyRotation);
}
_bodyRotationChange = false;
_bodyRotation = Vector3.zero;
if (_cameraRotationChange)
{
_playerCamera.localRotation *= Quaternion.Euler(_cameraRotation);
}
_cameraRotationChange = false;
_cameraRotation = Vector3.zero;
if (Input.GetKeyDown(KeyCode.Escape))
{
Application.Quit();
}
}
private void FixedUpdate()
{
if (_bodyTranslationChange)
{
_rigidbody.AddForce(_bodyTranslation * Utilities.controls.playerSpeed, ForceMode.VelocityChange);
}
if (_jump)
{
_jump = false;
_rigidbody.AddForce(playerBody.up * 500, ForceMode.Impulse);
}
_rigidbody.drag = playerBody.position.y > -0.6f ? 1 : 8;
_bodyTranslationChange = false;
_bodyTranslation = Vector3.zero;
}
}
The main two problems are :
As I do rotations in Update, and movements in FixedUpdates, there is some annoying jitter when I both move and rotate at the same time. I tried to show this in a gif but everything seems laggy so I can't really show it.
As I use AddForce() to move my character, I had to increase the drag of my rigidbody (up to 8) si it doesn't "slide" when you stop moving. This works great but now I can't jump properly because of that. I found a workaround, by putting the drag back to 1 when I'm in the air, but then if I jump and move, I move 8x faster in the air which is annoying aswell.
Am I doing thinks completely wrong ? I first did not use AddForce but normal vector translations to move the character, but collisions were buggy as hell, I could go through most walls, objects... etc
Thanks if you read all that !
Your answer
Follow this Question
Related Questions
RigidBody Character Controller Bug 0 Answers
Player inversed inputs 0 Answers
Character Controller Rotation 4 Answers
Character falls thru to his waist 11 Answers
How can I make a character controller that changes positions on one click. 1 Answer