- Home /
Player's jump is random and inconsistent...
The title is very self-explanatory. The issue is that, whenever I jump, the player's jump height is very strange and random. I am basically making a platformer for a game jam and this issue is not very nice for platforming lol.
Here is the script:
using System.Collections; using System.Collections.Generic; using UnityEngine;
public class PlayerMovement : MonoBehaviour { public float speed = 10f; private Rigidbody2D rb; public float jumpForce = 800f;
private bool allowJump;
public Transform point;
public LayerMask whatIsGround;
public float radius = 0.5f;
private void Start()
{
rb = GetComponent<Rigidbody2D>();
}
private void Update()
{
float x = Input.GetAxisRaw("Horizontal");
rb.velocity = new Vector2(x * speed * Time.deltaTime, rb.velocity.y);
allowJump = Physics2D.OverlapCircle(point.position, radius, whatIsGround);
if (Input.GetButtonDown("Jump") && allowJump == true)
{
rb.AddForce(Vector2.up * jumpForce * Time.deltaTime, ForceMode2D.Impulse);
}
else
{
allowJump = false;
}
}
}
so basically, I have some simple horizontal movement and some basic jumping. I have a bool that detects the ground. If it is overlapping, it will allow the player to jump, if there is nothing overlapping, player cannot jump so as to stop the player from jumping in mid-air.
Pls help :)
Answer by FeedMyKids1 · Jan 08, 2021 at 04:24 PM
Hey, I think the issue is that your setting values to the Player's rigidbody directly with your side to side movement.
Try to do the side to side movement in a different way, like by using Rigidbody.MovePosition (x speed Time.deltaTime).
I think that alone might make it more consistent.
What might also be an issue is that .AddForce is compounding the force that is already on the rigidbody, so you could (in your jump portion) set the rigidbody.velocity to Vector3.zero.
https://docs.unity3d.com/ScriptReference/Rigidbody.MovePosition.html
private void Update()
{
float x = Input.GetAxisRaw("Horizontal");
rb.MovePosition (transform.position + (x * speed * Time.deltaTime);
allowJump = Physics2D.OverlapCircle(point.position, radius, whatIsGround);
if (Input.GetButtonDown("Jump") && allowJump == true)
{
rb.velocity = Vector3.zero;
rb.AddForce(Vector2.up * jumpForce, ForceMode2D.Impulse);
}
else
{
allowJump = false;
}
}
Answer by Llama_w_2Ls · Jan 08, 2021 at 04:21 PM
I had the same issue. This question has been posted many times, but to save you some hassle, don't addForce. Instead, modify the velocity.y of the rigidbody. This will create a consistent and predictable jump height. @Pixelated_Studioz
Hi,
The problem that immediately comes to $$anonymous$$d when directly modifying the velocity of the rigidbody is that you take away all acceleration and smoothing.
The answer I posted also modifies velocity and is kind of a hack but would work like what you're talking about.
Another approach would be to use NEGATIVE force equal to the rigidbody's up velocity:
Vector3 negVelocity = rb.velocity * -1f;
rb.AddForce (negvelocity * Time.deltaTime, Force$$anonymous$$ode.Impulse);
Answer by wfin · Jan 09, 2021 at 04:19 PM
It didn't fix the bug still :( but thanks anyways. I have noticed something, when I don't multiply my jump power with Time.deltaTime, my player seems to jump fine (It doesn't sky rocket or jump inconsistently)... Why is that so? I have looked around and found nothing related to this..
Time.deltaTime varies depending on your frames per second. It fluctuates, which would cause inconsistent jumping motions, i'm guessing.
Oh man, that's a huge overlapse on my part:
For the impulse type Force$$anonymous$$ode on AddForce, you don't want to use Time.deltaTime because like Llama2 says, it fluctuates based on the difference in the amount of time it took to render the last two frames.
AddForce (Force$$anonymous$$ode.Impulse) will add a one time force to the rigidbody which, with gravity, will dissipate over time and that's all controlled from within the Rigidbody class itself.
https://docs.unity3d.com/ScriptReference/Rigidbody.AddForce.html
Answer by VeryAnnoyingCat · Jan 29, 2021 at 04:47 PM
SO,
Time.deltaTime is the time elapsed in seconds since the last frame, which depends on framerate, and is therefore, inconsistent as pointed out previously. ForceMode.Impulse adds the entire force in a single frame. So deltaTime causes spikes in the jump force.
Why da frig is there an else statement setting allowJump to false? In my sense the code would not mess up, but my sense is flawed so it is better to trust Debug.Log and remove the else statement. It is not needed for the code to function. So, the final code is:-
private Rigidbody2D rb; public float jumpForce; public float speed; public bool allowJump; public Transform point; public LayerMask whatIsGround; public float radius = 0.5f; private void Start() { rb = GetComponent<Rigidbody2D>(); } private void Update() { float x = Input.GetAxisRaw("Horizontal"); rb.velocity = new Vector2(x * speed, rb.velocity.y); allowJump = Physics2D.OverlapCircle(transform.position, radius, whatIsGround); if (Input.GetKeyDown(KeyCode.UpArrow) && allowJump == true) // set this to your desired input method { Debug.Log("bum"); rb.AddForce(Vector2.up * jumpForce, ForceMode2D.Impulse); allowJump = false; } }
Also, consider using Physics2d.OverlapArea instead of OverlapCircle.
Your answer
Follow this Question
Related Questions
Input Axis Vertical is not set up? 1 Answer
Sprites are being cut in half. HELP! 4 Answers
Character Instantly hits Ground after Falling off Object 1 Answer
Smooth Crouch Movement Issue 0 Answers
2D jumping raycast question 0 Answers