AddForce with Impulse adds less force 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 editor 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!

You have a frame rate dependency: Every frame (void Update) you check if the jump button is down and, if true, apply an impulse. So, currently, if you halve your frame rate, you halve the number of times you apply that impulse - for the same duration of button down.

Oh I see! (Sorry for the delay) Thanks! Putting it in FixedUpdate fixed it!