Attention | Topic was automatically imported from the old Question2Answer platform. | |
Asked By | mateushmm14 | |
Old Version | Published before Godot 3 was released. |
Well, this AI is supposed to follow the player if it is on a “reachable area”, which is determined by a “Area2D” node. Else, if there’s nothing to chase, the enemy should “wander” from point A to Point B. Everything works fine, except for the weird “wander” transition from point A to point B that, instead of smoothly translate between those points, it simply jumps to them. So, what I did wrong?
That’s it, let me know if something is not clear and thanks for your attention.
extends KinematicBody2D
var target
var speed = 2
var timer
var canWander
var d = dir.RIGHT
enum dir{RIGHT, LEFT}
func _ready():
set_fixed_process(true)
target = get_parent().get_node("Player")
timer = get_node("Timer")
timer.connect("timeout", self, "_on_timeout")
pass
func _fixed_process(delta):
var body = get_node("Body").get_overlapping_bodies()
var direction = (target.get_global_pos() - self.get_global_pos()).normalized()
if body.size() != 0:
for i in body:
if(i.is_in_group("player")):
canWander = false
move(direction*speed)
elif body.size() == 0:
if canWander == true:
canWander = false
timer.set_wait_time(2)
if d == dir.RIGHT:
move(Vector2(-16,0) * speed)
d = dir.LEFT
elif d == dir.LEFT:
move(Vector2(16,0) * speed)
d = dir.RIGHT
func _on_timeout():
canWander = true
Your move funtion seems to be used in a wrong way.
The distance your AI moves should be calculated by the formula:
distance = velocity * time
(for zero acceleration).
The velocity can be calculated as direction * speed
. So in Godot you should change your:
move(Vector2(-16,0) * speed)
into something like
var direction = Vector2(-1,0)
var speed = 16
var velocity = direction * speed
move(velocity * delta)
While delta
is your delta-time between two frames (given by the _fixed_process
).
rolfpancake | 2017-12-11 17:47
I tried this, but it didn’t work.
extends KinematicBody2D
var target
var timer
var canWander
var d = dir.RIGHT
var speed = 0
var velocity
var direction = Vector2()
enum dir{RIGHT, LEFT}
func _ready():
set_process(true)
target = get_parent().get_node("Player")
timer = get_node("Timer")
timer.connect("timeout", self, "_on_timeout")
pass
func _process(delta):
var body = get_node("Body").get_overlapping_bodies()
velocity = direction * speed
print (velocity)
if body.size() != 0:
direction = (target.get_global_pos() - self.get_global_pos()).normalized()
speed = 2
for i in body:
if(i.is_in_group("player")):
canWander = false
move(direction*speed)
elif body.size() == 0:
speed = 5000
if canWander == true:
canWander = false
timer.set_wait_time(2)
if d == dir.RIGHT:
direction = Vector2(-1,0)
move(velocity * delta)
d = dir.LEFT
elif d == dir.LEFT:
direction = Vector2(1,0)
move(velocity * delta)
d = dir.RIGHT
func _on_timeout():
canWander = true
mateushmm14 | 2017-12-11 21:21
I tried your code and your problem is the immediate change of the direction:
if d == dir.RIGHT:
direction = Vector2(-1,0)
move(velocity * delta)
d = dir.LEFT
In this case the AI can only move 1 frame in the given direction with the given speed. Then it turns into the other direction. Remove the line d = dir.LEFT
and d = dir.RIGHT
and place it into a new control sequence where you specify on what terms the AI should turn in the other direction (like a specified traveled distance).
rolfpancake | 2017-12-11 21:35