0 votes

Hello everyone! I've been playing aroud with Godot a lot for the past few month and I am liking it a lot. However, I am having some difficulties with my current project and I feel it is time for me to seek advice from people with more experience, so here I am :)

First of all, a simplified version of my project:
https://github.com/WannabeGamedev/map_navigation

It's a tilemap, the player spawns on a random tile and you can move within a mesh provided by tiles, nothing special. If you press T, a multiple instances of AI handled parties are added, all they do is roam the map randomly (you can use mouse wheel to zoom in and out for convenience). I am sure many of you will find the code below familiar, this is what I am currenlty using:

func move_along_path(distance : float):
var start_point : = position
#if _target != null:
#   goto(_target.position)
for _i in range(_path.size()):
    var distance_to_next : = start_point.distance_to(_path[0])
    if distance <= distance_to_next and distance >= 0.0 and distance_to_next != 0:
        position = start_point.linear_interpolate(_path[0], distance / distance_to_next)
        break
    if _path.size() == 1 and distance >= distance_to_next:
        position = _path[0]
        _path.remove(0)
        set_process(false)
        path_complete()
        break
    distance -= distance_to_next
    start_point = _path[0]
    _path.remove(0)

There are few issues however:

  • The more parties I have on the map, the slower it gets, the perfomance is pretty bad. If it was an RTS game or an action, I'd want to be able to handle much bigger numbers of instances at the same time. Is this approch bad for such projects? Is there a better way to handle pathfinding and movement on a map if I don't want unit's path snap to tiles?

  • I need to add a follow function and I am not sure what would be the best way to do it. You can see 2 commented lines in the code that I was using for this (goto function communicates with nav2d node, gives it new destination and recieves new path) but I think asking for new path every frame is bad for performance. Would it be good enough if I added a 1-2sec cooldown?

  • The most frustrating for me and basically the reason I am posting all of this since I've spent much time trying to figure it out. If you run the game, press T and spend some time watching the map, all parties will just stop simultaneously for no apparrent reason :( Have I messed something up, am I missing something? Since paths/movement is handled by _process function of each instance separately, I don't really understand why all paths get resetted at the same time, but it looks like they do..

Any useful advice is greatly appreciated!

in Engine by (12 points)

My own workarounds and observations in case they are useful for anybody:

1) and 3) Using kinematicbody2d for parties and physicsprocess instead of process helped a lot. The freeze issue disappeared altogether, animations seem a bit smoother too. Instead of recalculating positions every frame manually I rely on moveand_slide and my map navigation currently looks like this:

func _physics_process(delta):
# If party is not active, don't move
if is_active:
    # If there is a target to follow, compare final destination to target position every few seconds
    # and adjust path if needed
    if target != null:
        follow_cd += delta
        if follow_cd >= 1.0:
            goto(target.position)
            follow_cd = 0
    # Movement along path
    if path.size() > 0:
        var current_speed = speed * speed_modifier
        velocity = (path[0] - position).normalized() * current_speed
        if (path[0] - position).length() > 4:
            move_and_slide(velocity)
        else:
            position = path[0]
            path.remove(0)
            if path.size() == 0:
                path_complete()

2) As for the follow function, I've decided to give a one second cooldown idea a try, it's in the code above as well. I am not very happy with the delay and still thinking if there is a better way to go about it but it works overall and does not seem to impact game perfomance too much.

Please log in or register to answer this question.

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.