Search code examples
godotgdscript

I am having issues with the move_and_slide and move_and_colide functions in GODOT


I trying to create a basic evolution simulator, and to do that I require my randomly created creatures to move towards the nearest food. I am confident in the code that gets the direction for the creatures, as I have tested it by modifying the position by the expected amount (Yes I know I should not be directly changing the position). When I then use either move_and_slide or move_and_collide I find that instead of moving as expected, they jump to a line or gathering along the centre of the window and appear to randomly move up and down. I am unsure of what is causing this movement as all my past uses of move_and_slide or move_and_collide have worked perfectly fine.

func move(food_positions, delta):
    if playing:
        direction = choose_direction(food_positions)
        if direction != null:
            move_and_slide(direction*SPEED)

This code is called externally as the creatures are instanced within a 'simulation' scene. The food_positions is an array of Vector2 used to calculate the desired direction. As it is called from another scene I needed to pass the delta value in for when using move_and_collide.

The code for the choose_direction is as follows:

    var closest_food_pos = null
    var closest_food_distance = null
    # iterate through each food
    for food_pos in food_positions:
        # get distance betweeen the two positions
        var gap = food_pos - position
        var distance_food_me = sqrt(pow(gap.x,2) + pow(gap.y,2))
# insert test to within view distance here
        # confiming that we are not comparing to null
        if closest_food_distance != null and closest_food_pos != null:
            # comparing distances
            if closest_food_distance > distance_food_me:
                # setting to closest food
                closest_food_distance = distance_food_me
                closest_food_pos = food_pos
        else:
            #if null need to set to first food to compare
            closest_food_distance = distance_food_me
            closest_food_pos = food_pos

    if closest_food_distance != null and closest_food_pos != null:
        var gap = closest_food_pos - position
        var go_direction = gap.normalized()
        return go_direction.normalized()
    else:
        # add ai go towards function call here
        return null

It's not completely finished yet and there are a few bits that I plan to add in future.

Just as a note, this is part of a creature scene, dynamically instanced in a simulation scene which is pre-instanced/part of the main scene to be used for controls and later usability.

The git hub repository is: https://github.com/benpotter480/Evolution_simulation_that_doesnt_work

Sorry if parts of my repository are not shown as is normal as I am new to using it.

Thanks for any advice.


Solution

  • Okay, I have a solution.

    Preface

    I first added a breakpoint at the move_and_slide() and ran the project from the main scene to step through the code. Nothing looked off. The values were being set and initialized. I added print statements to find out what food_positions, creature_positions, and direction were showing over time, thinking that the first frames weren't to blame. But, nothing looked off.

    I checked the creature scene. There had to be something there. The code looked fine, nothing that should cause move_and_slide() to do what it was doing. I ran the creature scene in isolation. Guess what, it worked. So, at least I know it's not in the creature scene.

    This was troublesome. It was failing in the simulation for no reason as far as I could tell. I tried generating 100 foods, 100 creatures.

    Then 1 creature.

    That creature didn't move. That was something. When there were more creatures it was like they were being forced into each other. After some more fiddling, I was mindlessly twirling the wall_left static body and noticing that little protuberance and then, wait, that's not a RectangleShape2D.

    I deleted all the walls and...

    It worked! The simulation worked!

    TL;DR / Solution

    The LineShape2D collision shapes of the walls had its normals facing the wrong way. Change the LineShape2D's Normal from (0, -1) to (0, 1).

    Conclusion

    That was a head scratcher. Hope this helps and happy coding!