bounce not working and instead dragging?

Godot Version

4.7.1

Question

I have a RigidBody2D with a child CollisionShape2D that I’m trying to have bounce off of other objects when it interacts with them. I’ve been having issues getting it to even point towards the player so I decided to just focus on the bouncing. It moves, but when it collides with other objects, it just gets stuck against them and slides with them? it keeps moving forward against the object instead of bouncing.

extends RigidBody2D

var speed = 50

func _ready():
	# set position
	self.global_position = Vector2(500, 200)

func _physics_process(delta):
	var velocity = Vector2(3,2)
	position += velocity * speed * delta
	var collision_info = move_and_collide(velocity * delta)
	if collision_info:
		velocity = velocity.bounce(collision_info.get_normal())

This is the script I’m using to do this. I’m sure there’s something really basic that I’m not understanding, I’m just not sure how to identify it. I also attached the properties of the Ball in question, there’s no gravity because this is meant to be similar to pong and i dont need it falling to the “ground”.

You are defining velocity locally as a [3,2] vector, and you do this every physics update. The ball (RigidBody2D) will never move in a different direction. You have to move the velocity definition outside of _physics_process() (next to your speed variable) so its value persists between physics updates.

You strike me as a beginner so I would strongly recommend you to check out some tutorials. I’m sure there are pong tutorials out there as well. In fact, I found an entire playlist for you that you can follow on YouTube:

Pong Tutorial Playlist

I would like to explain further as to why, specifically, your code is not working as you intended, but any detailed answer I may provide will just produce more questions.


If you have a specific question about something you don’t understand, please don’t hesitate to create another post.

Thank you for answering! Your solution worked, I can see why that was messing things up now. The object does now get bounced by the player, it just slides against the top and bottom walls now instead of bouncing off of those as well. I set them to be StaticBody2D’s with a physics material with friction 0 and bounce 1, but that doesn’t seem to be working. I checked the tutorial you recommended to see their solution to having walls and they seem to have not had the issue I had despite ostensibly having done the same thing. I tried setting the walls to be other nodes as well, such as CharacterBody2D or RigidBody2D to see if attempting to replicate the scene tree of the player or AI paddle or ball itself would work but it did not, so I set it back to a StaticBody2D.

I think it might be an issue with getting bounce to actually trigger and the ball is getting stuck inside the wall? I moved the walls around and it does seem to be an issue where the ball is just colliding with the wall and sliding against it no matter where it’s placed. I attached a gif below recording the game actually running and the code for the object script below that if those help. Sorry if this should have been a new post, I assumed it would be okay here because the ball is still dragging and my current script still seems to be the issue.

BallStuck

extends RigidBody2D

var speed = 50
var velocity = Vector2(3,2)

func _ready():
	# set position
	self.global_position = Vector2(500, 200)

func _physics_process(delta):
	position += velocity * speed * delta
	var collision_info = move_and_collide(velocity * delta)
	if collision_info:
		velocity = velocity.bounce(collision_info.get_normal())

I’m still not sure what the problem exactly was but trying to making the ball face the player when spawned, resulting in it being rotated by about a 45 degree angle seemed to have worked and now it bounces off of everything I want it to and doesn’t sink into the walls at all. Visually it doesn’t look great but everything seems to work now. I would still really like to know what the issue was if possible. The ball also doesnt exactly face the player paddle but thats a separate issue I can figure out.

Bouncywork

Okay. I’m going to explain to you what is going on with your current approach and why it is not working the way you think.

Your code is pretty simple (as it should be), but the nodes you make use of (RigidBody2D, StaticBody2D etc.) function as part of an underlying physics engine that aim to produce realistic-looking physics. Physics engines are based on physics. This means that interacting with rigid-bodies, or any other type of body that is part of the physics engine, requires the use of forces or manipulation of the body’s physics state (see _integrate_forces). It is the state of the physics body which is responsible for moving the body in space over time. That’s what a physics simulation is.

In your current project, you are bypassing the physics system entirely by setting the RigidBody2D’s position directly:

position += velocity * speed * delta

While this will not cause any issues for isolated instances, such as when spawning the object or teleporting it to a different position, it is going to cause problems when a collision occurs and a collision response is computed by the physics system.

Sidenote

You seem to already know a little about integration, given that you integrate the position manually. Generally speaking though, you should only need to do this when the object in question isn’t part of an already established system, such as the physics system. You may be familiar with GameMaker which, when I used it, needed this type of barebones approach.

You don’t need to do this for predefined nodes. It is already done for you. I recommend reading the documentation whenever you work with a node you don’t understand. It’s really useful.


The second point is that you are using a physics class for something that doesn’t need physics-like movement. Pong is a very simple game. You can clearly see how there are no angled obstacles in the game – only vertical and horizontal collisions. This is by design to reduce the complexity of the collisions for Pong that, back then, needed to be programmed. There’s no need for drag, physics materials, gravity, generalized shapes, and so on. You are trying to force a complex physics object to act like a simple, mathematical abstraction of a ball. It doesn’t fit together, and although I’m sure you can make a Pong clone with RigidBody2D, it is much simpler to utilize a Godot node that’s built for custom movement systems: the CharacterBody2D node.

I’m not going to repeat what is already described in the documentation. However, I will provide a brief description of how you should be moving the CharacterBody2D:


I hope that helps you understand the nature of what you’re doing.

Here are some helpful links:

Responses to other comments

The tutorial makes use of a CharacterBody2D, not a RigidBody2D.

In situations where you don’t know what node to use, I urge you to go and read the documentation for the different nodes to see their intended use-cases.

I can’t say for sure why that worked. Perhaps the reduction of colliding edges made your code work. Still, it is a hacky solution at best and you are much better of following the advice I provided above. I’m sure you’ll agree.


  1. ↩︎

Thank you so much!