#Raycasts for better movement, am i doing it right? (beginner)

15 messages · Page 1 of 1 (latest)

coral abyss
#

Hi!

Right now i'm trying to make my enemies (there is going to be a bunch of them) able to sense if their intended path is obstructed and have secondary, less desirable paths that they could consider. It wold also allow me to arbitrarily weight on those to change enemy logic

Pretty much like in this video: https://www.youtube.com/watch?v=6BrZryMz-ac&t=167s

I'm experimenting, right now i've added 8 raycast nodes to an enemy for basic directions and i intend to follow the signal up logic, which means they all get a script with a signal for "there is a body" and a signal for "there is no body" so that i can have a variable in the main enemy script for each containing a boolean

After that in the main script there would be 8 variables (1 for each direction) that are true or false.
I need to learn how to convert the direction vector provided by the navigation agent into an angle and compare that angle to the cardinal directions to determine what directions are close to the intended path, then have the enemy select the closest one that is not obstructed

To do that each direction variable that isn't eliminated because obstructed would receive an integer value, the highest wins for this frame

I can then add extra stuff to weight on that decision for more complex behaviors. I guess it makes me wonder how i'm going to make them walk around each other towards the shortest path to their destination though...

Is this a good way to do it, is it good practice, is it going to be bad on performance? That's a lot of variables, signals and raycasts to multiply by the number of enemies and in this case they're going to be numerous

#

Maybe there is a way to make the parent node of all the raycasts (NavigationRedirection, it's a simple 2DNode) to check on the children and have combined signals to limit the amount possible with match?
That's a lot of combinations, probably too many... I'm just spitballing

coral abyss
#

Maybe i can create a loop with one raycast and tell the enemy to only check the direction it was about to go first, have different angles stored in an array and change the position of the ray if the first it checks is obstructed, rince and repeat until it finds a free path

I don't know how to make it determine if it should go right, left, back... Should i have it check every unobstructed direction and add a marker to ask the navigation agent to compare which one is closest to the player following a path?..

Maybe introduce a random component amongst the most preferable so that enemies don't all try to do the same thing exactly?..

keen heart
#

Personally I'd approach this using pathfinding logic that Godot has built-in, which I learned from this video: https://www.youtube.com/watch?v=yT22SXYpoYM&t=1026s. It has a section about pathfinding avoidance where actors can be made to avoid each other or things marked as to be avoided.

But the part about finding alternate paths might be tricky, it probably would involve using some pathfinding algorythm in another step, but probably not every frame (or you'd probably get enemies moving back and forth as paths close/reopen from other enemies' movements). That part I'm really not sure how to tackle.

One idea that flashed in my head but that I don't know how doable it is, would be using the avoidance pathfinding logic, which comes with a separate step to calculate the things it should avoid, and using that as a moment to try a different "layer" of collision/pathfinding possibilities. But again, that's just a very abstract idea.

I'm making a game! Wishlist Fangs & Faith Solitaire Now: https://store.steampowered.com/app/3032430/Fangs__Faith_Solitaire/

This is yet another video on pathfinding. This time we combine the best features in Godot: Pathfinding, Tilemaps and Navigation Layers. This tutorial aims to cover the usage and quirks of them, presenting how basic pathfin...

▶ Play video
coral abyss
# keen heart Personally I'd approach this using pathfinding logic that Godot has built-in, wh...

First thing first, thank you very much i simply didn't know about the avoidance option, it's not mentioned in the book i follow which had me make enemies that just disappear when they hit the player hence why i'm taking a pause from it to learn movement more in depth first

I'm not sure i understand your idea, my thing with the single raycast was meant to look something along the lines of:

if raycast.is_colliding():
  #move raycast to check 45° left and right from velocity, store in variables in boolean

  #move raycast to check 90° left and right from velocity, store in variables in boolean



    if #there are unobstructed paths aka any raycast variable says true:
      #place a Marker2D at unobstructed left, two times if both are clear
      #variable(s) left = ask navigation agent the distance Marker2D to player with pathfinding
      
      #place a Marker2D at unobstructed right, two times if both are clear
      #variable(s) right = ask navigation agent the distance Marker2D to player with pathfinding

      target = #function that returns the global position of the marker that has the shortest path to the player

      if is_instance_valid(target):
        _navigation_agent_2d.target_position = target

      next_position = _navigation_agent_2d.get_next_path_position()
      direction_to_shorter_path = global_position.direction_to(next_position)

      velocity = velocity.move_toward(direction_to_shorter_path * max_speed, acceleration * delta)

  elif #there is no unobstructed path
     velocity = Vector2.ZERO
     move_and_slide()
     return```
#

In short, do you mean introducing some if like this that changes it? It seems complicated to interfere in the middle of godot's inner process, but the result can be influenced like this afterwards if i want to introduce a different behavior, like running from something if it gets too close or something like that, is that close to what you suggested?

Sorry if i'm unclear, i'm doing my best

keen heart
#

Nah we all are doing our best! And sorry my suggestion wasn't more concrete, but to answer your question: sort of. I was thinking of replacing the Raycasts by the pathfinding, because (at least in my mind) the raycasts offer only a snapshot of the most immediate surroundings, so it's hard to use their output to "plan" a path.

For example, eA and eB are after the player.
eA determines there's a path, goes straight ahead.
eB does the same, but soon eA is blocking that path, so finds another path.
Next frame/update, the path that was blocked by eA is free again because it moved, so eB jerks back the way it came.

I guess this is a problem with any pathfinding though, not just raycast-based ones. Maybe there needs to be a common "team planning" at some level for the enemies, but that's a can of worms too.

coral abyss
#

i suppose if i force them to take a left or a right, this should be avoided to a degree especially if i later introduce some randomness in their target position to encircle the player slightly (i guess?)

(ok, note to future users: avoidance has its own max speed setting: i was wondering why my enemies were suddenly so slow for half an hour, check the inspector's avoidance section on NavigationAgent2D)

coral abyss
# keen heart Nah we all are doing our best! And sorry my suggestion wasn't more concrete, but...

I've managed to set it up (and also it's super funny to set the avoidance radius super high and see them act like angry atoms in an arena... <- bold concept inbound /j)

Sadly they still derp quite a bit around corners and the like, although maybe i could probably resolve the issue by making round edges everywhere (babyproof the walls!)

I think i want to still pursue making a version of that maybe-gizmo thing, it seems great to personalize enemy behavior down the road

To avoid pinging you exceedingly if i have notes i may just write them without the "answer to" discord function thing

Thank you very much for your help, i appreciate it a lot

#

**If you just joined the topic: **

I'm still trying to find a way to do the thing, the post is still open and unsolved

Also hi and welcome =)

frail kelp
#

This is very similar to something I'm working on at the moment, using the Path3D demo from the "Godot 4 Node Essentials" course as a base.

While the demo uses an AStar3D class to handle the navigation, all its points are laid out in a 3D grid topology, which results in the ship having very aggressive stepwise motion. I'm trying out an AStar3D-based navigation system for connecting waypoints for general high-level guidance, but introducing RayCast3D-based fine navigation for obstacle avoidance.

I've previously tried an obstacle avoidance-only approach using RayCast3Ds, however there were moments where the agent became stuck behind an obstacle and didn't simply go around it. There would be some serious jitter as it starts to take one path around the obstacle, but in the next frame would reverse direction as it suddenly had a closer position to the target than continuing on the original path around the obstacle.

#

Also, I looked into NavigationServer3D / the 3D navigation agent system in Godot, but found it only plausible for ground-based agents that can travel up & down stairs/ramps and follow paths that cross over each other if appropriate, but cannot navigate through 3D space like an aircraft would.

A big indication of this is the existence of a NavigationMesh object (where the agent navigates across its surface), but there isn't the existence of a NavigationVolume (or similar) object that describes a volume that the agent can travel through. Something to note is that the documentation indicates this class is experimental, so could be removed later.

coral abyss
coral abyss
#

I've been trying all day/evening/part of the night to get to a result but right now i have a bunch of haywire raycasts

Since it's technically a more specific issue that would have use outside of this specific topic, i've posted on reddit about it. You can find the full code of my enemy there.
It's a lot more than i had 48 hours ago, but i'm pretty sure it's jank, i'm basing assumptions on assumptions not finding how i'm supposed to do this better

Should someone be curious about a detail, it's all there. It's bulky, but i don't really know what i'm supposed to do to do better:
https://www.reddit.com/r/godot/comments/1m6vi1y/somehow_my_raycasts_keep_getting_a_wrong/