Impulse rigidbody forces different in build

Hello everyone,

I’m making a fps multiplayer game and I’m working on the jumping. I came across that problem: forces added in build mode are way weaker than in edit mode.

  • Jumping in editor:

stzw3c

  • Jumping in build:

eg1xbb

I made my searches on the subject and all i found was about Time.deltaTime and not about Impulse forces. Here is the codes involved in jumping :

  • Movement script (OnCollision functions aren’t important to read, they detect ground):
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Mirror;

[RequireComponent(typeof(PlayerControllerCh4riot))]
public class PlayerMove : MonoBehaviour {

    [SerializeField]
    private Vector3 velocity;
    [SerializeField]
    private Vector3 rotation;
    [SerializeField]
    private float cameraRotationX;
    [SerializeField]
    private Rigidbody body;
    [SerializeField]
    private Camera playerCamera;
    [SerializeField]
    private float cameraRotationXMax = 85f;
    private float currentCameraRotationX;
    [SerializeField]
    private float jumpForce = 2f;
    [SerializeField]
    public GroundChecker groundChecker;
    public bool isGrounded;

    private void Start() {
        //Cursor.lockState = CursorLockMode.Locked;
    }

    public void SetVelocity(Vector3 _velocity) {
        velocity = _velocity;
    }

    public void SetRotation(Vector3 _rotation) {
        rotation = _rotation;
    }
    public void SetCameraRotationX(float _cameraRotationX) {
        cameraRotationX = _cameraRotationX;
    }


    private bool isJumping;
    private void FixedUpdate() {
        Move();
    }

    private void LateUpdate() {
        Rotate();
    }


    public void Jump() {
        if (isGrounded) body.AddForce(Vector3.up * jumpForce , ForceMode.Impulse);
    }


    private void Move() {
        if (velocity != Vector3.zero) {
            body.MovePosition(body.position + velocity * Time.fixedDeltaTime);
        }
    }

    private void Rotate() {
        body.MoveRotation(body.rotation * Quaternion.Euler(rotation));

        currentCameraRotationX = Mathf.Clamp(currentCameraRotationX + cameraRotationX, -cameraRotationXMax, cameraRotationXMax);
        playerCamera.transform.localEulerAngles = new Vector3(-currentCameraRotationX, 0, 0);
    }



    private void OnCollisionEnter(Collision collision) {
        Vector3 localCollisionPoint = transform.InverseTransformPoint(collision.GetContact(0).point);
        /*Debug.Log("ENTER [" + (IsGroundCollision(localCollisionPoint, collision.gameObject.layer) ? "X" : " ") + "]"
            + "(" + groundChecker.colliders.Count.ToString() + ")"
            + "[" + collision.gameObject.name + ":" + LayerMask.LayerToName(collision.gameObject.layer) + "]"
            + ": " + localCollisionPoint.ToString("F4"));*/
        if (IsGroundCollision(localCollisionPoint, collision.gameObject.layer)) {
            AddGroundCollider(collision.collider);
        }
    }

    private void AddGroundCollider(Collider collider) {
        isGrounded = true;
        groundChecker.colliders.Add(collider);

    }
    private void OnCollisionExit(Collision collision) {
        /*Debug.Log("Exit (" + groundChecker.colliders.Count.ToString() + ")"
                  + "[" + collision.gameObject.name + ":" + LayerMask.LayerToName(collision.gameObject.layer) + "]"
                  + "[" + (groundChecker.colliders.Contains(collision.collider) ?"x":" ") + "]");*/
        groundChecker.colliders.Remove(collision.collider);
        if (groundChecker.colliders.Count == 0) isGrounded = false;
    }

    private void OnCollisionStay(Collision collision) {
        if (!isGrounded) {
            Vector3 localCollisionPoint = transform.InverseTransformPoint(collision.GetContact(0).point);
            if (IsGroundCollision(localCollisionPoint, collision.gameObject.layer)) {
                AddGroundCollider(collision.collider);
            }
        }
    }

    private bool IsGroundCollision(Vector3 point, int layer) {
        return Math.Abs(point.y) < .5f && Math.Round(point.x, 4) == 0 && Math.Round(point.z, 4) == 0
               && ((groundChecker.groundCheckLayers.value & (1 << layer)) > 0);
    }
}
  • Commands controller script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[RequireComponent(typeof(PlayerMove))]
public class PlayerControllerCh4riot : MonoBehaviour {

    [SerializeField]
    private float speed;
    [SerializeField]
    private PlayerMove playerMove;
    [SerializeField]
    private float mouseSensitivity;

    private void Update() {
        // Calculates player's velocity
        {
            Vector3 moveHorizontal = transform.right * Input.GetAxisRaw("Horizontal");
            Vector3 moveVertical = transform.forward * Input.GetAxisRaw("Vertical");
            Vector3 velocity = (moveHorizontal + moveVertical).normalized * speed;
            playerMove.SetVelocity(velocity);
        }
        // Calculates player's rotation
        {
            Vector3 bodyRotation = new Vector3(0, Input.GetAxisRaw("Mouse X"), 0) * mouseSensitivity;
            playerMove.SetRotation(bodyRotation);
            Vector3 cameraRotation = new Vector3(Input.GetAxisRaw("Mouse Y"), 0, 0) * mouseSensitivity;
            playerMove.SetCameraRotationX(cameraRotation.x);
        }
        // Handles jump
        if (Input.GetButton("Jump")) {
            playerMove.Jump();
        }
    }
}

If anyone has a solution, I’ll take it!

Change the method from Update to FixedUpdate

The player’s movements must be in a fixed update because the frequency of the call is always constant, unlike Update, which is updated as the frame is drawn

I tried something similar before and didn’t work but now it does ! Thank you so much !