Search Unity

Resolved Jumping on PC is different than it is on mobile device

Discussion in 'Scripting' started by scythwolf, Nov 22, 2022.

  1. scythwolf

    scythwolf

    Joined:
    Dec 30, 2018
    Posts:
    49
    Hello!
    I am curious why my character (a ball) is jumping differently on my PC compared with my mobile device. With the same jumpforce they reach a different height.
    I use the new input system. Maybe it is the strength of the touch?
    Also when I keep the jump button pressed the height of every consecutive jump stays not the same... as if the jumpforce added or the balls force when adding the jumpforce is different.

    I tried to play with the numbers but that didn't help either. Screenshot of the balls components are included.

    Here is the code:

    Code (CSharp):
    1.  
    2.  
    3. public class PlayerMovement : MonoBehaviour
    4. {
    5.     public float movementSpeed = 1;     //movement Speed of Player
    6.     public float jumpForce = 100;       //Force for jumping by AddForce
    7.     public float groundCheckDistance;
    8.  
    9.     private Rigidbody2D _rigidbody;
    10.  
    11.     [SerializeField] bool isGrounded = false;   //isGrounded Checkbox
    12.     [SerializeField] Transform groundCheckCollider;    //Empty to check if isGrounded
    13.     [SerializeField] LayerMask groundLayer;     //Wich layer to check if isGrounded
    14.     public PlayerInputActions playerControls;
    15.     private InputAction move;
    16.     private InputAction jump;
    17.     private InputAction touch;
    18.  
    19.     //Variable for Tutorials
    20.     public GameObject canvasUI;
    21.     UIStartTimer uiStartTimer;
    22.  
    23.     void Start()
    24.     {
    25.         uiStartTimer = canvasUI.GetComponent<UIStartTimer>();
    26.     }
    27.  
    28.     public void Awake()
    29.     {
    30.         _rigidbody = GetComponent<Rigidbody2D>();
    31.         playerControls = new PlayerInputActions();
    32.     }
    33.  
    34.     public void OnEnable()
    35.     {
    36.         move = playerControls.Player.Move;
    37.         move.Enable();
    38.  
    39.         jump = playerControls.Player.Jump;
    40.         jump.Enable();
    41.  
    42.     }
    43.  
    44.     public void OnDisable()
    45.     {
    46.         move.Disable();
    47.         jump.Disable();
    48.     }
    49.  
    50.     void Update()
    51.     {
    52.        
    53.         if (uiStartTimer.timerPaused == false)                                                                      
    54.         {
    55.             var movementDirection = move.ReadValue<Vector2>();
    56.             _rigidbody.AddForce(movementDirection * Time.deltaTime * movementSpeed, ForceMode2D.Impulse);
    57.  
    58.             GroundCheck(); //check if grounded for jump
    59.             bool jumping = jump.IsPressed();
    60.  
    61.             //GroundCheck();
    62.  
    63.             Debug.Log("Jumping is " + jumping);
    64.             Debug.Log("isGroundeds is " + isGrounded);
    65.  
    66.             if (isGrounded == true && jumping == true)
    67.             {
    68.                 _rigidbody.AddForce(new Vector2(0, jumpForce), ForceMode2D.Impulse);
    69.             }
    70.         }
    71.     }
    72.  
    73.     void GroundCheck()
    74.     {
    75.         isGrounded = false;
    76.         Collider2D[] colliders = Physics2D.OverlapCircleAll(groundCheckCollider.position, groundCheckDistance, groundLayer);
    77.         if (colliders.Length > 0)
    78.         {
    79.             isGrounded = true;
    80.         }
    81.     }
    82. }
    83.  
    84.  
    upload_2022-11-22_18-45-28.png

    upload_2022-11-22_18-46-6.png

    Thanks for any hints
     
  2. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,775
    Different framerates, is the answer.

    When you use .AddForce, it adds that amount of force for a certain duration, and that duration is based on whatever update phase you're in. If you're in Update(), it's the duration of the game frame. If you're in FixedUpdate, it's a constant duration every time the code is called. It's a bit of an annoying quirk.

    Instead of calling AddForce on line 68, instead set some "doPhysicsJump" variable. Add a FixedUpdate method where you check for that variable, AddForce, then set that variable to false. That will give AddForce a consistent duration to apply the force.

    You should also do the same for the AddForce on line 58, but since that one does have you continuously adding force, it's less of a major issue and more just, minor consistency issues. And for that one, I'd say store the input value rather than a boolean, and don't set it false/zero after use.
     
    scythwolf likes this.
  3. Adrian

    Adrian

    Joined:
    Apr 5, 2008
    Posts:
    1,065
    That's what ForceMode2D is for. It defaults to ForceMode2D.Force, which is intended for forces added over a certain time (i.e. multiplied by delta time). If the force is added all at once, you need to use ForceMode2D.Impulse instead, which is unaffected by delta time. You always need to be careful to choose the right one, using either incorrectly will result in physics inconsistencies based on the frame rate.

    Are you sure about using
    ForceMode2D.Force
    in
    Update
    ? I had assumed it would just use the fixed time step and also result in (albeit smaller) frame rate inconsistencies. At least the 3D physics got Rigidbody.GetAccumulatedForce in 2022.2 and that defaults to the fixed time step as argument, indicating that non-impulse forces will always use the fixed delta time. This would mean that difference between
    Update
    and
    FixedUpdate
    frequency would affect the actual force applied.

    In general, I'd say do everything physics-related in
    FixedUpdate
    . Only when you know what you're doing is not time-dependent, you can do it outside of it.
     
    scythwolf likes this.
  4. scythwolf

    scythwolf

    Joined:
    Dec 30, 2018
    Posts:
    49
    That really helped a lot. It still was a bit off: The first jump was the highest. The follow up jumps were mostly consistent but lower than the first one. I thought it might have something to do with the groundCheck() and when it was handled. To synchronize it with the jump I put it there as well. Now it is pretty consistent... Thank you!