0 votes

I'd like to create a 2D game where an enemy continues to walk or jump once the players stand on it.
This is the behaviour of the enemies in the sample Godot project (2d platformer - kinetic). In my game, however, the enemy stops completely once the player is on top.

I've compared the code between the sample game and mine, and I can't figure out what is different (except that I use move_and_slide and not move_and_slide_with_snap inside player.gd, because for me, move_and_slide_with_snap caused the player to stop responding to input.

This is my very first Godot project, so I'm still learning the ropes. (I've been coding for years, so I am familiar with a number of concepts.)

Here is the enemy.tscn file

[gd_scene load_steps=5 format=2]
[ext_resource path="res://sprites/baddies/enemy.png" type="Texture" id=1]
[ext_resource path="res://src/Enemy.gd" type="Script" id=2]

[sub_resource type="RectangleShape2D" id=1]
extents = Vector2( 24, 31.75 )

[sub_resource type="RectangleShape2D" id=2]
extents = Vector2( 32, 10 )

[node name="Baddie" type="KinematicBody2D"]
collision_layer = 8
collision_mask = 36
script = ExtResource( 2 )

[node name="Baddie" type="Sprite" parent="."]
position = Vector2( -9.09495e-13, -40 )
scale = Vector2( 0.740741, 0.811828 )
texture = ExtResource( 1 )

[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
position = Vector2( 0, -32.25 )
shape = SubResource( 1 )

[node name="VisibilityEnabler2D" type="VisibilityEnabler2D" parent="."]
visible = false
position = Vector2( -0.5, -28.5 )
scale = Vector2( 4.45, 2.85 )
process_parent = true
physics_process_parent = true

[node name="PickupDetector" type="Area2D" parent="."]
collision_layer = 8
collision_mask = 4

[node name="CollisionShape2D" type="CollisionShape2D" parent="PickupDetector"]
position = Vector2( 0, -72 )
shape = SubResource( 2 )

[node name="FloorDetectorLeft" type="RayCast2D" parent="."]
position = Vector2( -40, -42 )
enabled = true
collision_mask = 32

[node name="FloorDetectorRight" type="RayCast2D" parent="."]
position = Vector2( 40, -42 )
enabled = true
collision_mask = 32

[node name="WallDetectorLeft" type="RayCast2D" parent="."]
position = Vector2( 8, -40 )
rotation = 1.5708
enabled = true
collision_mask = 32

[node name="WallDetectorRight" type="RayCast2D" parent="."]
position = Vector2( -16, -40 )
rotation = -1.57079
enabled = true
collision_mask = 32

[connection signal="body_entered" from="PickupDetector" to="." method="_on_PickupDetector_body_entered"]

And my Enemy.gd

class_name Baddie
extends Character

enum State {
    NORMAL,
    DEAD
}

onready var floor_detector_left = $FloorDetectorLeft
onready var floor_detector_right = $FloorDetectorRight
onready var wall_detector_left = $WallDetectorLeft
onready var wall_detector_right = $WallDetectorRight

var affected_by_gravity = true # set to false for flying enemies

func _ready() -> void:
    motion.x = -50.0
    var _State = State.NORMAL

func _on_PickupDetector_body_entered(body):
    ### nothing here yet....

func _physics_process(delta):
    if not floor_detector_left.is_colliding() or not floor_detector_right.is_colliding():
        motion.x *= -1

    if wall_detector_left.is_colliding() or wall_detector_right.is_colliding(): 
        motion.x *= -1

    if affected_by_gravity: 
        motion.y += GRAVITY * delta

#   commented this if-statement out to see if this 
#  was somehow causing the enemy to stop moving
# when the player was on top #######
#   if is_on_wall():
#       motion.x *= -1.0

motion.y = move_and_slide(motion, FLOOR_NORMAL).y
Godot version 3.4.4
in Engine by (12 points)

1 Answer

0 votes

I cannot see your specific problem in the code but at least in reference to the fact that move and slide with snap didnt work there is a known issue on slopes with this function. There is a good video https://www.youtube.com/watch?v=9l-tf97z2bg which deals with this, might be worth watching and seeing if fixing that part solves your problem?

by (2,001 points)

Thanks for your answer.
The video you sent dealt mainly with slopes, and I don't have slopes in my game. (Yet -- so I'll keep your video, just in case.)

I'm not sure if this is the "right" way to fix my problem, but I found that using Self.position.x = etc. etc. did the trick -- the enemy continues to move, even when the player is standing on top.

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read Frequently asked questions and How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to [email protected] with your username.