Characterbounce movement causes a slide while standing still and sometimes it does so aswell randomly [SOLVED]

Godot 4.4.1 steam

Question


pqQOhSm

sprite2D2 is an arrow that follows the collision location and rotate towards it
everytime i press spacebar the character will kind of slide around instead of doing an actuall bounce

basically what the code is meant to do is its meant to on space bounce the player like if its a jump but it works on any surface and uses a rigidbody so that the physics on it are realistic

why use a rigidbody instead of characterbody2d? i want to with this game create a more physics based enviorement that allows the player(s) to really mess around (i dont want to fully say why cause its a private project rn)

So my question is how could I make this code work better and make bounce even while standing still

You might want to check the vector you’re feeding into apply_impulse() in the bounce input check in run(). You’re manipulating it a lot; it may not be quite what you think it ought to be by the time it gets out of the equation.

i tried removing the .normalized()
and making the x velocity 0 but now the player cant bounce/jump while not moving

so yeah idk what i could be doing wrong sadly

Maybe try drawing the impulse vector as a debug line and see what you get.

One glaring issue that I notice is that you are invoking run() in both _integrate_forces() and _physics_process(). The code in run() is, for this reason, essentially being ran twice in every physics update. I don’t think this is your intention nor the best approach.

As @hexgrid also points out, the impulse you’re using to produce the jump/bounce is not simple. I’m assuming you are trying to produce a vector that points in the opposite direction of your contact_point (i.e. your hitmarker2). However, I don’t see how your current approach achieves this.

Impulse vector breakdown

In this section I will break down what your current impulse vector represents, and illustrate a better approach to computing an impulse vector for your desired “bounce” system.

As shown in your code, your impulse vector is made up of 3 values:

  • V1: A constant vector with the value [2, 500]
  • s_rot: The local rotation of the physics object’s 2D sprite ($Sprite2D2)
  • V2: Another constant vector with the value [2, 20]

V1 is being rotated by -s_rot radians, then normalized. This is then component-wise multiplied by V2. First of all, having two unnamed vector values in an equation makes it very hard to understand what each value is meant to represent (usually referred to as “magic numbers”). Does V1 define the default “bounce” strength? Does V2 represent a difference in bounce strength between the two axes? It’s near impossible to know these things unless this is explained with a variable name or accompanying comment.

Code conventions aside, I don’t think you understand what $Sprite2D2.rotation actually represents. For all nodes, 2D or 3D, rotation represents the local rotation of the object in radians (See docs). Since the RigidBody2D is the object that is moving, that is the object whose transform changes over time. The Sprite2D2 does not perform any local movement. For this reason, you should not be using Sprite2D2’s local rotation to modulate the direction of the impulse you’re using for your bounce system. Use the data from the physics object, not the visuals attached to it.

IMPORTANT: I am by no means implying that you should then use the rotation of the physics object. I am simply prompting you to think more deeply about why you are using these specific values.

Computing a useful impulse vector

First, compute a directional vector. Since you are using a ball, this can easily be done by subtracting the center of the ball from the contact point.

    var contact_point = state.get_contact_local_position(0)
    var bounce_dir = (state.transform.origin - contact_point).normalized()

Then multiply the bounce_dir by a desired bounce strength.

    var bounce_strength = 100.0
    var bounce_imp = bounce_dir * bounce_strength

That’s it. You should now be able to use this bounce_imp to apply impulse to your ball when needed.


I see other issues as well. You are not performing proper input detection, and you are using this mysterious extracheck() function which, again, needs more clarification as to why it exists. Line 15 seems irrelevant, and just to make sure you don’t forget - run() is being invoked twice!

I hope I made you think a little more about what you are doing and that I helped you solve your problem. Let me know if you need further clarification on anything.