- Home /
Jumping isn't smooth while going up
So i am trying to implement my custom physics on 2d sprite. the upward translation isn't smooth , however coming down is smooth in my player controller.cs.
Project link : https://github.com/DemonJAZ/WalkInForest2DGame
using System.Collections; using System.Collections.Generic; using UnityEngine;
public class PlayerController : MonoBehaviour { private bool grounded = false; public float gravitymodifier = 1f; public float jumpforce; public float movementSpeed; private Rigidbody2D Pico; private float inputX,inputY;
// Start is called before the first frame update
void Start()
{
Pico = gameObject.GetComponent<Rigidbody2D>();
}
private void Update()
{
if (Input.GetKeyDown(KeyCode.Space) && grounded)
{
transform.Translate(Vector2.up * jumpforce * Time.deltaTime);
grounded = false;
}
}
// Update is called once per frame
private void FixedUpdate()
{
if (Input.GetKey(KeyCode.D))
{
transform.Translate(Vector2.right * movementSpeed * Time.deltaTime);
}
if (Input.GetKey(KeyCode.A))
{
transform.Translate(Vector2.left * movementSpeed * Time.deltaTime);
}
if (!grounded)
{
transform.Translate(Physics2D.gravity * gravitymodifier * Time.deltaTime);
}
if (Physics2D.Raycast((Vector2)transform.position + (Vector2.down * 0.7f) , Vector2.down,0.1f) && !grounded)
{
grounded = true;
}
}
}
Answer by highpockets · Jun 09, 2019 at 10:54 AM
Well, when you press space and you are grounded, you apply the jumpforce in the world up direction using translate, but on the same frame isGrounded becomes false and in the next fixed update you are passing the gravity vector to the translate method which is overriding your jump. You need to account for your jump while you are jumping in the FixedUpdate() while isGrounded is false, but a rigidbody does this for you if you use it correctly
I see you have a Rigidbody2D component, but you are not using it in your movement logic which seems a bit odd since you assign it to a variable named Pico, yet you never do anything with Pico. Is it a kinematic rigidbody??
If you want to use the rigidbody in a way that calculates the physics for you, it needs to be dynamic and you need to AddForce() for movement or directly change the velocity vector (changing the velocity vector directly could lead to unexpected behavior unless you know what you are doing) and AddTorque() for rotations or directly change the angular velocity vector (once again, directly changing the angular velocity is not recommended for the same reasons as above). While directly modifying the velocity vector is not recommended, by looking at your code, it seems that you are setting exact values for movement (kind of arcade style) and if that is what you want instead of gradually speeding up for example, modifying the velocity vector of the rigidbody might be exactly what you are looking for.
bool startingToJump = false;;
private void Update()
{
if (Input.GetKeyDown(KeyCode.Space) && grounded)
{
startingToJump = true;
}
}
// Update is called once per frame
private void FixedUpdate()
{
float xVel = 0.0f;
float yVel = 0.0f;
if (Input.GetKey(KeyCode.D))
{
xVel = (1 * movementSpeed * Time.deltaTime);
}
else if (Input.GetKey(KeyCode.A))
{
xVel = (-1 * movementSpeed * Time.deltaTime);
}
if( startingToJump)
{
yVel = (1 * jumpforce);
startingToJump = false;
}
if (Physics2D.Raycast((Vector2)transform.position + (Vector2.down * 0.7f) , Vector2.down,0.1f) && !grounded)
{
grounded = true;
}
else
{
grounded = false;
}
Pico.velocity = new Vector2(xVel, Pico.velocity.y + yVel);
}
That is a bit of untested code, but I think it might be what you are looking for. If you really wanted to calculate the physics without the help of the rigidbody that will be more code. I took out the gravity code because the rigidbody does that for you. Hope that helps, cheers
Thanks for the you solution , but i am trying to implement in kinematic scenario, my Rigidbody is kinematic.
In that case you need to save your manual jump velocity for example and add gravity every frame to change it over time. Below is some untested code
Vector2 vel;
// Start is called before the first frame update
void Start()
{
Pico = gameObject.GetComponent<Rigidbody2D>();
}
private void Update()
{
if (Input.Get$$anonymous$$eyDown($$anonymous$$eyCode.Space) && grounded)
{
vel.y = jumpforce * Time.deltaTime;
transform.Translate(vel);
grounded = false;
}
}
// Update is called once per frame
private void FixedUpdate()
{
if (Input.Get$$anonymous$$ey($$anonymous$$eyCode.D))
{
vel.x = movementSpeed * Time.deltaTime;
}
if else (Input.Get$$anonymous$$ey($$anonymous$$eyCode.A))
{
vel.x = -movementSpeed * Time.deltaTime;
}
else
{
vel.x = 0.0f;
}
if (!grounded)
{
vel.y = vel.y + (Physics2D.gravity.y * gravitymodifier * Time.deltaTime);
}
if (Physics2D.Raycast((Vector2)transform.position + (Vector2.down * 0.7f) , Vector2.down,0.1f) && !grounded && vel.y <= 0.0f)
{
grounded = true;
vel.y = 0.0f;
}
transform.Translate(vel);
}
}
Thank you so much, i think i was focusing more on overco$$anonymous$$g the gravity rather than stopping it and focus more on implementing velocity upwards to Y axis.