Apply gravity to the move_and_collide

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By TempSchoolAcc#1

I’m working on moving the enemy to the player at the moment and my current code consists of using the move_and_collide() function. The way it works is really simple, however, I am unable to apply gravity correctly. I’ve tried a lot of things and I finally found something that works, but now my enemy jumps with the player. The gravity works fine and pulls the enemy down exactly as I want, but now I’m not sure on how to stop the enemy jumping? Any ideas?


const GRAVITY = Vector2(1, 25.0)

func _physics_process(delta):
if areaExported2: #areaExported2 is the variable I store the players location in
	var velocity = (areaExported2.global_position - global_position).normalized()
	velocity = velocity * GRAVITY
	var collision = move_and_collide(velocity * SPEED * delta) # Speed is already defined and the variable will come in later in the process

Thank you!

I’m not sure I understand your question. Would you share a video showing the issue?

p7f | 2020-11-16 12:03


Is that the enemy code, and does areaExported2.global_position is the player location?

If yes, then this logic says that when the player jumps you will set the enemy vertical velocity to follow the player jump.

var velocity = (areaExported2.global_position - global_position).normalized()

So, if areaExported2.global_position.y increases (when the player jumps) you will also add y velocity for the enemy. I assume that is why the enemy jumps.

If you want your enemy to run on the ground (maybe they can jump too) you probably need logic that handles x and y components separately. For example, If the player is to the left, head left. If the player within a certain distance and above, jump. And you might get into complexity with path finding if you have platforms…

If you can explain what you want the characters to do maybe somebody can help

Also, I don’t understand what you are doing with the GRAVITY variable. I would expect that gravity should just work downwards, but you have both x and y coordinates. You probably only want to add y velocity based on gravity.

AndyCampbell | 2020-11-17 01:12

Yes, this is the enemy code that I attached. The areaExported2 is the player, so I assume that areaExported2.global_position is the player area. My aim is to have the enemy able to follow the player, however, he doesn’t need to jump at any part of the level. Do you have any suggestions on how I would do this differently, I’m new to godot? All I need is for the enemy to follow the player on the floor, without jumping when the player jumps. The GRAVITY variable is there so I can multiple GRAVITY by the other Vector2’s

TempSchoolAcc#1 | 2020-11-17 01:41

@p7r I apologise, I’m on a school laptop as this is my class project and as such a lot of things are blocked and I cannot find a way to upload the video.

TempSchoolAcc#1 | 2020-11-17 01:42

ok, so instead of calculating velocity as a Vector (which will include a y component which you do not need) just look at only the x component.

Maybe something like this (I can’t run this code at the moment so it is not tested and may have errors)

const ENEMY_SPEED = 20

func _physics_process(delta):
  var direction = 0
  if areaExported2:
    if (areaExported2.global_position.x - global_position.x) > 0:
      direction = 1
    if (areaExported2.global_position.x - global_position.x) < 0:
      direction = -1
    velocity = Vector2(direction * ENEMY_SPEED, 0) 
    var collision = move_and_collide(velocity * delta) 

AndyCampbell | 2020-11-17 02:45

Hey, thank you for the code! At the moment my solution which seems to work is adding a piece of code that (honestly I’m not even sure if this is needed) causes the y value to become unaffected and then I can manually adjust where the enemy roams. While this isn’t in play, I have a move_and_slide() function apply gravity so it is aligned probably.
Code to show what I mean:

func _physics_process(delta):
	if areaExported2 == null:
		motion.y += GRAVITY2 # Gravity 2 is just the float of the gravity I wanted
		motion.x = SPEED
		motion = move_and_slide(motion, UP)
		$Sprite.scale.x = 1.02
	# Keep moving towards the player while he is spotted
	if areaExported2:
		var velocity = (areaExported2.global_position - global_position).normalized()
		velocity.y = (velocity.y * 0) * GRAVITY2
		var collision = move_and_collide(velocity * SPEED * delta)

This works for my little school project! I appreciate the help though, thank you!

TempSchoolAcc#1 | 2020-11-17 07:19