Search Unity

NPC AI for sailing game: need Angle dependent path cost

Discussion in 'Navigation' started by FMaroy, Sep 23, 2018.

  1. FMaroy

    FMaroy

    Joined:
    Oct 8, 2015
    Posts:
    5
    Hi All,

    This is my first post on the forum. I'm working on this sailing game, that include obstacles (both static and moving). It includes as well cost areas (some of them are moving as well.
    I have implemented already a logic which is sort of random based and I wanted to have a smarter approach.

    I would like to use the standard Unity navigation module, but it cannot work as is. The problem is that, in sailing, the NPC cannot go against the wind, but it can only go as close as 45deg, and navigate from sides to sides.
    The speed of a sailing object is a function of its angle to the wind, so I would need to include the path angle to the wind as function of cost, and feed this to the path calculator.
    I looked through the web, and I don't find an easy solution, or somebody who had a similar problem.
    I'm starting to think I might have to implement my own aStar calculation, but before diving into such a project, I though than asking for advices might be a good idea.

    Any idea on how I could do this in an easier way?
     
  2. Yandalf

    Yandalf

    Joined:
    Feb 11, 2014
    Posts:
    491
    I did a quick search and it turns out that you can change area costs per agent with NavMeshAgent.SetAreaCost
    It may not be an elegant solution, but you could use this to set the cost per boat on all sailing areas depending on the wind direction compared to the ship's direction. However, this will likely not result in the zigzagging motion you would probably require for your ships to be believable.
    A better solution might be to first figure out your destination with your agent, take the path from that, manually create a zigzag path from it when needed, and then give the agent that calculated path to use instead.
     
  3. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    3,356
    I would start with the path the navmesh returns, then tack along that path.

    First I would take the navmesh path and plot points on it at equal distance from each other. Distance just being arbitrary what works best for how dense your obstacles are.

    THen you just start projecting lines from where you are at 45 degree angles. One left one right. At every X distance along the line raycast to the points on the navmesh path, the ones closest to a 45 deg angle. So maybe the two closest that are <= 45.

    From wherever you are, you should be able to do both left and right and end up with a set of good paths. Pick the one that gets you closest to the goal.

    Your obstacle placement needs to be such that it will allow for tacking at all times, so some minimum distance between them.

    Should go without saying you won't be using agents here.
     
  4. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    3,356
    Should rephrase something here it's important to this approach. The obstacle placement needs to be such that the short path, always has enough room to tack. If there are longer paths that do, but the shortest path has a part where you couldn't tack, then the above approach wouldn't work. The distance between the points on the navmesh path and the projected 45 deg lines will impact how much space you need.
     
  5. FMaroy

    FMaroy

    Joined:
    Oct 8, 2015
    Posts:
    5
    Thank you for Yandalf and Sacktime. That really helpful and conforming me in my current idea, that was very close to your ideas.
    In my idea I would calculate a path at 45 deg in both directions around obstacles and make sure each segment of the path is in a “allowed” angle (let’s say between 40 and 55). If one segment fails, I start from the segment before, and recalculate different path with increasing the angle (45->55). If it doesn’t find good angle, I end the path there.
    And then, it fits your idea, i segment each path and redo the process on the other side.
    I should end up with a tree of possible path and I can integrate the cost along each one to get the best one.
    I’m just a bit concerned by the performance cost associated, when this happens during runtime...
    If it doesn’t work I would fallback to just raycasting on the navmesh.
    Does it sound like a reasonable method?

    I will update you when I have a working demo!
     
  6. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    3,356
    if performance becomes an issue check out the job based raycasting. You can literally do hundreds per frame.
     
  7. FMaroy

    FMaroy

    Joined:
    Oct 8, 2015
    Posts:
    5
    Thanks! I’m still working on the implementation (not my main job!).
    How can I use this feature?