• Godot HelpProgramming
  • Help with moving an enemy patrolling back and forth with markers/empty game objects like Unity

Hi,

In Unity for moving enemies that are patrolling left and right, I would normally set two markers for the left-most and right-most transforms, allowing me to reverse them when the enemy has reached those positions.

All the tutorials for Godot that I've seen appear to focus on raycasts when the enemy reaches the end of a platform, or reversing direction when reaching a wall.

My enemies are on a long platform, but never reach the ends (they patrol a short distance), plus there are no walls for them to collide with either.

Can somone help show me how to use some form of markers with transfroms please?

Perhaps I could use the RemoteTransform Node instead of an empty game object like in Unity?

Thanks.

Well i dont know unity but if i was doing it, i would add two static bodys with collision shape as walls to both sides of the platform.

And when enemy collide with walls they will turn back. U can use raycast for collision detect.

And also make the static bodys disable for player so that player can go through inside them. U can search for collision layers and collision masks for it.

im New at gem dev. and this is just an idea.

@hoppala said: Well i dont know unity but if i was doing it, i would add two static bodys with collision shape as walls to both sides of the platform.

And when enemy collide with walls they will turn back. U can use raycast for collision detect.

And also make the static bodys disable for player so that player can go through inside them. U can search for collision layers and collision masks for it.

im New at gem dev. and this is just an idea.

Thanks for your idea, I might consider it if I can't work my method out. I like the idea of avoiding checking for collisions, using targets for the enemy to move towards would possibly avoid slowing the game down - but I could be wrong ;)

I would use one of two methods. One using an Area with something like a sphere or cube shape. The other, is check the distance the moving game piece is from the way point.

if(enemyunit.global_transform.origin.distance_to(waypoint.global_transform.origin)<1.0): #aim for other waypoin

This could be a could chance for you learn how to use the powerful Area. Very good for doing game logic.

@newmodels said: I would use one of two methods. One using an Area with something like a sphere or cube shape. The other, is check the distance the moving game piece is from the way point.

if(enemyunit.global_transform.origin.distance_to(waypoint.global_transform.origin)<1.0): #aim for other waypoin

This could be a could chance for you learn how to use the powerful Area. Very good for doing game logic.

Thanks for that info ;)

@DaveTheCoder said: Another method is to use Path or Path2D.

I've looked at the Path2D option, but I can't seem to find info on reversing the direction when the enemy has reached the end point of the path.

Currently I have this simple scirpt:

extends Path2D

func _physics_process(delta): $PathFollow2D.set_offset($PathFollow2D.get_offset() + 150 * delta)

I created a Path2D line for a sprite horizontally, the sprite moves right.

How do you find out when the sprite has finished?

Additonally, is there a key you can hold down to create a completely staight line, or a way to adjust/move the segments of the path after it's created ?

I haven't done a lot with those classes. I've only used Path2D for spawning enemies randomly along the path.

I know that you can adjust the path's vertices by dragging on them. So you could make a flat curve that's effectively a loop. The path offset would be 0.0 and 1.0 at one end, and 0.5 at the opposite end.

In _physics_process() you could increase the offset from 0.0 until it reaches 0.5, and then decrease the offset until it reaches 0.0.

Or maybe the end point of the path doesn't have to coincide with the origin point. So you could have the offset increase from 0.0 to 1.0, and then decrease back to 0.0.

I reviewed the documentation, and the numbers 0.5 and 1.0 in my previous comment are wrong. The offset is the distance in pixels along the path. I guess you'd have to determine the length of the path to know when to reverse direction.

@DaveTheCoder said: I reviewed the documentation, and the numbers 0.5 and 1.0 in my previous comment are wrong. The offset is the distance in pixels along the path. I guess you'd have to determine the length of the path to know when to reverse direction.

Thanks for the help. Although it sounded like a good idea, I might try another option or two as the paths don't appear to have that many options built in.

PathFollow2D sounds exactly like what you want, you can use the property "unit_offset" to check when it reaches either end (goes from 0.0 to 1.0). I tested this code and it works (the property "Loop" on PathFollow2D needs to be off):

onready var patrol_path = get_node("Path2D/PathFollow2D")
var speed = 200
var direction = 1

func _process(delta):
	
	if patrol_path.unit_offset == 1.0:
		direction = -1
	elif patrol_path.unit_offset == 0.0:
		direction = 1
	
	patrol_path.offset += speed * delta * direction

@Pefistep said: PathFollow2D sounds exactly like what you want, you can use the property "unit_offset" to check when it reaches either end (goes from 0.0 to 1.0). I tested this code and it works (the property "Loop" on PathFollow2D needs to be off):

onready var patrol_path = get_node("Path2D/PathFollow2D")
var speed = 200
var direction = 1

func _process(delta):
	
	if patrol_path.unit_offset == 1.0:
		direction = -1
	elif patrol_path.unit_offset == 0.0:
		direction = 1
	
	patrol_path.offset += speed * delta * direction

I'm getting an error:

get_node: (Node not found: "Path2D/PathFollow2D" (relative to "/root/Node2D/Path2D").)

I'm figuring that the script cant find the path for the Path2D/PathFollow nodes.

Here's my node tree:

Yeah, I had that script in the base Node2D, if you attach it to the Path2D node you have to change that line to "get_node("PathFollow2D")", or you can just attach the script to the PathFollow2D itself, in which case:

extends PathFollow2D

var speed = 200
var direction = 1

func _process(delta):
  
  if unit_offset == 1.0:
	  direction = -1
  elif unit_offset == 0.0:
	  direction = 1
  
  offset += speed * delta * direction

@Pefistep said: Yeah, I had that script in the base Node2D, if you attach it to the Path2D node you have to change that line to "get_node("PathFollow2D")", or you can just attach the script to the PathFollow2D itself, in which case:

extends PathFollow2D

var speed = 200
var direction = 1

func _process(delta):
  
  if unit_offset == 1.0:
	  direction = -1
  elif unit_offset == 0.0:
	  direction = 1
  
  offset += speed * delta * direction

I'm still familiarising with Godot, and I wasn't sure about the path for PathFollow2D. It's fixed now and works good.

I used an animated sprite, with two small additional lines of code, the sprite flips when reaching the ends of the path - just in case anyone else needs to know ;)

extends Path2D


onready var patrol_path = get_node("PathFollow2D")

var speed = 200
var direction = 1


func _process(delta):
	
	if patrol_path.unit_offset == 1.0:
		direction = -1
		$PathFollow2D/AnimatedSprite.flip_h = false ## Flip Animated Sprite Direction
	elif patrol_path.unit_offset == 0.0:
		direction = 1
		$PathFollow2D/AnimatedSprite.flip_h = true ## Flip Animated Sprite Direction
		
	patrol_path.offset += speed * delta * direction

Here's my node tree:

I set the Animated sprite to play from the Inspector, but you could easily play the animation from withint the script.

Here's an example screenshot:

The path method here is really useful as you can make the path go in any direction obviously, not just horizontally.

Although I'm not sure how resuable it is for adding more than one if you have them in different scenes.

    9 months later
    a year later

    JayBanana Hi, this is exactly what I am looking for however I can't see your node tree. I have a Character2D with an AnimatedSprite2D and CollisionShape2D as the children. Where does the path2D and pathfollow2d go? Thanks!