Collision detection problem

Godot 4.3_stable_official on MacOs 15.1

I’m trying to recreate the Amiga Bounce Ball demo.
Now I’ve run into a collision detection issue that I can’t solve. Been searching the web and trying for hours and just can’t find a proper solution.
The problem is that when the ball hits the right wall I can’t get it to return. No matter what I try it moves in some direction that I don’t want it to.

the GDScript currently looks like this:

extends CharacterBody3D

# Constants for movement
const INITIAL_X_VELOCITY = 3.0  # Initial horizontal speed
const DRAG = 0.5               # Drag slows movement over time
const JUMP_VELOCITY = 5.0     # Vertical jump strength
const ROTATION_SPEED = 1.0     # Rotation speed of the ball

# Variables to track motion
var gravity = ProjectSettings.get_setting("physics/3d/default_gravity")
var x_direction = 0.5  # 1 for right, -1 for left

func _ready():
	# Initialize the ball's horizontal velocity
	velocity.x = INITIAL_X_VELOCITY * x_direction

func _physics_process(delta):
	# Apply gravity if not on the floor
	if not is_on_floor():
		velocity.y -= gravity * delta

	# Bounce on the floor
	if is_on_floor():
		velocity.y = JUMP_VELOCITY

	# Detect wall collisions and reverse X velocity
	if is_on_wall():
		for i in range(get_slide_collision_count()):
			var collision = get_slide_collision(i)
			var collider = collision.get_collider()
			
			if collider.is_in_group("walls"):
				print("Bounced off a wall!")
				# Reverse horizontal direction
				velocity.x = -velocity.x
				x_direction = -0.5
				break  # Handle only one collision per frame

	# Apply drag to Z velocity (optional)
	#velocity.z = move_toward(velocity.z, 0, DRAG * delta)

	# Rotate the ball for visual effect
	rotate_y(deg_to_rad(ROTATION_SPEED * x_direction))
	velocity.x = INITIAL_X_VELOCITY * x_direction
	# Move the ball
	move_and_slide()

The Plane_00x-col are on layer 2 and the collision mask of the ball is set to 1 and 2.

[Edit:] It bounces correctly off the left wall. Strange…

Last year, I found that I had a bunch of unexplained behavior by changing velocity during my game’s runtime. This is most likely why:

Note the velocity is modified, invisibly to you, by move_and_slide(). So the velocity value you set is not necessarily the same after calling move_and_slide().

I solved all of my game’s velocity inconsistencies by building my objects’ movement vectors myself, and setting velocity with the sum of those vectors immediately before calling move_and_slide().

1 Like

Using move_and_slide() may not be best for your demo, as you want to control velocity. move_and_collide will provide instant collision data too.

Eitherway I think your issue is flipping velocity.x when it is overriden by x_direction anyways. Should be flipping x_direction instead.

if collider.is_in_group("walls"):
	print("Bounced off a wall!")
	# Reverse horizontal direction
	x_direction *= -1
1 Like

Thank you both for your input. It works now. But I realize that I have to look more into physics and read again the Physics Introduction and CharacterBody2D/3D documentation.