- Home /
Character teleports upwards instead of jumping smoothly Unity2D
I am rather new to Unity, and am attempting to create my first game. Everything has gone as smoothly as expected until now. When attempting to jump, my character instead seemingly teleports to the top of of it's jump before gliding down to the ground. No matter what I have tried and the seemingly endless threads I have searched, I can't find an answer. Any help would be appreciated, thanks. My character script is linked below.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Poro : MonoBehaviour {
public float speed = 10f;
public float force = 300f;
Rigidbody2D rb;
void Start () {
rb = GetComponent<Rigidbody2D>();
}
void FixedUpdate () {
rb.velocity = Vector2.right * speed;
if (Input.GetKeyDown(KeyCode.UpArrow))
{
rb.AddForce(Vector2.up * force);
}
}
}
Answer by Eno-Khaon · Nov 05, 2018 at 01:27 AM
Here's what's happening during FixedUpdate().
First, you're setting your velocity to have no vertical element.
rb.velocity = Vector2.right * speed;
Then, you add an arbitrary vertical force.
if (Input.GetKeyDown(KeyCode.UpArrow))
{
rb.AddForce(Vector2.up * force);
}
First, let's address the velocity itself. If you don't want to drift downward when directly setting a Rigidbody's velocity, you need to keep your vertical speed intact.
rb.velocity = new Vector2(speed, rb.velocity.y);
Furthermore, the distance your character is moving up when jumping right now is only a single physics calculation of movement before "floating" back down.
Second, there's the Input. You DON'T want to use Input.GetKeyDown() during FixedUpdate(). Typically, this results in arbitrary inputs being missed. All Input instructions occur during Update(), whereas FixedUpdate() occurs with different timing. If you get two frames between a FixedUpdate(), you'll miss the frame where the key was pressed. To be certain that the physics will be processed accurately, however, the best practice is to apply physics changes during FixedUpdate().
bool jump = false;
void Update()
{
if(Input.GetKeyDown(KeyCode.UpArrow))
{
jump = true;
}
}
void FixedUpdate()
{
if(jump)
{
jump = false;
rb.AddForce(Vector2.up * rb.mass * force, ForceMode2D.Impulse);
}
}
Finally, the force itself. I tweaked it in my example above already, but here's what should change:
Right now, your jump force scales based on the physics update rate of your game. If you decide to turn it up or down, your character will jump lower or higher respectively. AddForce() (2D), by its default, applies force using ForceMode2D.Force. This results in a steady force that's applied evenly per frame, with a goal of applying the designated force per-second. By this logic, if your physics update rate is the default of 50 FixedUpdate() cycles per second, your force of 300 scales down to 6 units-per-second immediate force applied. If you changed your physics rate to, say, 100 per second, then that 300 force scales down to only 3.
ForceMode2D.Impulse, however, applies its force instantaneously. I multiplied the force by the character's mass to counteract that element of the equation. This results in a consistent force applied to the character when jumping, no matter their mass or physics rate.
Hey, thanks for the super in-depth explanation! Not only does it work, I think I know why it works too. Thanks so much!!!
Answer by Otavio_ · Nov 05, 2018 at 01:18 AM
@XenosTiger, have you tried to slow down the force?
Yes, all that slowing the force does is reduce the height the character "teleports" upwards.
Your answer
![](https://koobas.hobune.stream/wayback/20220612181533im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
2d Circle won't change size 0 Answers
triplex 2d unity game 0 Answers
I have a problem with coins 1 Answer
Multiple Cars not working 1 Answer
Why does my swiping code not work? 1 Answer