My rigidBody2D loses gravity if I move it with a script

Godot Version

4.3

Question

Hi. I am new with Godot and game developing.
I am trying to make an enemy that moves left and right (goes back if it hits a wall), and I want it to be able to fall off platforms.
I used a RigidBody2D. If I just place the scene with no script for movement it will fall, but when I add code for it to move, then it will stay on place in the Y axis, it wont fall.
How can I make it so it falls?
Here is my script.
I got it mostly from this video

extends Node2D

var direction = 1
@onready var ray_castleft = $RayCastleft
@onready var ray_cast_r_ight = $RayCastRIght
@onready var animated_sprite = $AnimatedSprite2D

# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
	if ray_cast_r_ight.is_colliding():
		direction = -1
		animated_sprite.flip_h = true
	if ray_castleft.is_colliding():
		direction = 1
		animated_sprite.flip_h = false
	position.x += direction * 60 * delta

The problem right now is, that you always move the body, even when the raycasts don’t collide with anything.
Try something like this:

func _process(delta):
	if ray_cast_r_ight.is_colliding():
		position.x += - 60 * delta
		animated_sprite.flip_h = true
	if ray_castleft.is_colliding():
		animated_sprite.flip_h = false
		position.x += 60 * delta

Thanks for your reply.
I want the enemy to always be moving left or right (change direction if they hit a wall) but be able to fall if they walk off a cliff. Basically, they would be the same behavior as green turtles in Mario 2D games.
With my code gravity stops affecting the enemy and they “float” on the Y axis forever (and keep on floating off-screen).
Sorry if I didnt explain myself properly earlier.

Try adding a third raycast to check, if the body is on a ground:

extends RigidBody2D

var direction = -1
@onready var ray_cast_left = $RayCast2DLeft
@onready var ray_cast_right = $RayCast2DRight
@onready var ray_cast_down: RayCast2D = $RayCastDown

@onready var animated_sprite = $AnimatedSprite2D

# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
	if ray_cast_right.is_colliding():
		direction = -1
		animated_sprite.flip_h = true
	if ray_cast_left.is_colliding():
		direction = 1
		animated_sprite.flip_h = false
	if ray_cast_down.is_colliding():
		linear_velocity = Vector2(0, 0)
		position.x += direction * 60 * delta

It might also be better to not directly move the object but only apply a force and let the engine do the rest.
It’s pretty late where I am so excuse my grammar (or my code)

1 Like

Rigid bodies deal in forces to change position, I think you would be better off using a CharacterBody2D and calculating gravity in the script.

3 Likes

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.