Search Unity

Flying A.I. That Navigates Around Objects

Discussion in 'Navigation' started by dann96, Feb 20, 2015.

  1. dann96

    dann96

    Joined:
    Dec 6, 2014
    Posts:
    113
    I currently need help figuring out how to make an A.I. that can fly around like a bird (x, y, and z positions) and will be able to avoid objects with collision meshes, AKA a sort of 3-dimensionial navmesh.

    Here is what I currently have (the flyto variable is just a test to see if it will fly to a specified object):

    using UnityEngine;
    using System.Collections;

    public class bird_ai : MonoBehaviour {

    public float speed = 10;

    public Transform flyto;

    void Update ()
    {
    float step = speed * Time.deltaTime;
    transform.LookAt(flyto);
    transform.position = Vector3.MoveTowards(transform.position, flyto.position, step);
    }
    }


    If anyone has suggestions in code, I am making this in C#.
     
  2. jpthek9

    jpthek9

    Joined:
    Nov 28, 2013
    Posts:
    944
    If you only need obstacle avoidance on the XZ plane, you can generate a bunch of layers of navmeshes and simply assign the bird's layer based on its height.
     
    radiantboy likes this.
  3. dann96

    dann96

    Joined:
    Dec 6, 2014
    Posts:
    113
    If it helps any, I am basically looking for a way to make the bird's height change depending upon its distance between the two locations that it is flying two. For example: If it is flying a total of 3 yards, its height slowly will ascend to about 1 yard high between the two points and will descend back to its normal height when it started once it reaches its location.

    Is it also possible to adjust these variables in the editor if this whole script can be programmed?
     
  4. dann96

    dann96

    Joined:
    Dec 6, 2014
    Posts:
    113
    Here is a bit more of a visual concept of what I am trying to do.

    Forgive the crudely made images, I made them a bit quickly.

    the idea is to make it fly at a varying height while avoiding static objects in the world.
     

    Attached Files:

  5. MakeCodeNow

    MakeCodeNow

    Joined:
    Feb 14, 2014
    Posts:
    1,246
    Do a google search of BOIDS. It describes a flocking algorithm, but you can use similar avoidance techniques for a single bird.
     
  6. jpthek9

    jpthek9

    Joined:
    Nov 28, 2013
    Posts:
    944
    Birds often fly in 2D formations so Unity's standard navigation should work fine to keep the formations. For gradual height, just do transform.position.height += Increase * Time.deltaTime if the destination.y > transform.position.y and decrease the height if it's less.
     
  7. dann96

    dann96

    Joined:
    Dec 6, 2014
    Posts:
    113
    How exactly would I go about coding that precisely?
     
  8. jpthek9

    jpthek9

    Joined:
    Nov 28, 2013
    Posts:
    944
    I'm not sure. So far all you've given me is what you want; not how you're implementing this. For starters, what are the controls?
     
  9. dann96

    dann96

    Joined:
    Dec 6, 2014
    Posts:
    113
    Well, I'm using a raycast system that gives the player the ability to click anywhere on the ground or an object and the bird will fly to it using the nav mesh. I now just need to figure out how to get it to elevate.


    Ray mouseClick = Camera.main.ScreenPointToRay (Input.mousePosition);

    if (Physics.Raycast (mouseClick, out hit, 1000))
    {
    cursorPosition = hit.point;
    }

    if (Input.GetMouseButton (0))
    {
    agent.SetDestination (hit.point);
    }
     
  10. shadow-river

    shadow-river

    Joined:
    May 29, 2013
    Posts:
    63
    dann96 the way I have gotten around this problem is doing these 2 things. first I use an invisible cube with the nav agent attached, this agent can move through obstacles etc. (this has no avoidance). this sticks to your ground plain and moves straight to wherever you click your mouse. the next step is to parent your bird to the cube and use mecinam and raycasting to make the bird elevate. so before your bird starts moving you can play an animation (by moving the transform) of the bird flying up then the bird flys down and lands when he reaches his destination. with raycasting you shoot a ray forwerds so that if it comes in to contact with obstacles you can make him fly up or down, this gives your bird life. your bird will move with the cube since its a child of the cube.

    this may be a crude way of doing it but it works.
    hope this helps or gives you an idea at least.
     
  11. dann96

    dann96

    Joined:
    Dec 6, 2014
    Posts:
    113
    Thanks for the reply. I understand what you mean in the explanation, but could you possibly show a bit of the concept in code C# perhaps?

    nothing too complicated, just enough to get the point across.
     
  12. shadow-river

    shadow-river

    Joined:
    May 29, 2013
    Posts:
    63
    ok this is what you should do to get him to rise and fall. have your cube set at ground level attach a navmesh agent. get your bird and attach it to the cube as a child and set it exactly at the cubes position. attach this script to the cube ( I haven't tested it so may need some altering) also make shore that you make an animation of your birds transform rising to the point you want, and make another one of your bird descending (make them using unity's animation tool) you'll want another animation for idle and flying as well (but my script I quickly wrote doesn't include these). in mecinam you'll want to set all the animations up as Boolean triggers for this ill call them rise and fall.
    ( also when you make the animations for rise and fall you will need to make sure they don't loop)

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class bird : MonoBehaviour {
    5.  
    6.     Animator anim;
    7.     NavMeshAgent agent;
    8.  
    9.     void Start ()
    10.     {
    11.         agent = GetComponent<NavMeshAgent>();
    12.         anim = GetComponentInChildren<Animator>(); // this gets the animator in the bird object
    13.     }
    14.  
    15.  
    16.     void Update ()
    17.     {
    18.  
    19.  
    20.         if (Input.GetMouseButton(0))
    21.         {
    22.  
    23.             Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);
    24.             RaycastHit hit;
    25.          
    26.             if(Physics.Raycast(ray, out hit, 1000))
    27.             {
    28.                 agent.SetDestination (hit.point);
    29.                  anim.SetBool("fall",false);
    30.                 anim.SetBool("rise",true); // this plays the animation of the birds transform flying up
    31.             }
    32.         }
    33.  
    34.         if(agent.remainingDistance <= float.Epsilon)// this here makes the bird land when your cubes reached its destination.
    35.         {
    36.  
    37.             anim.SetBool("rise",false);
    38.             anim.SetBool("fall",true); // this plays the animation of the bird landing
    39.         }
    40. }
    41. }
    this is a start hope it helps
     
  13. hoesterey

    hoesterey

    Joined:
    Mar 19, 2010
    Posts:
    659
    Heya,
    Lots of ways to skin the cat. I've used the concept of "Avoidence Colliders" think whiskers on a cat. Basically I have avoidance collider going up down, left, right, etc...

    When a collider has a Obstacle in it it sends a message to the AI brain. The brain chooses "the best way to turn" based on where it wants to go and what avoidance colliders are clear. So if it wants to get to point X but a rock is in the way it will fly straight toward point x until the rock enters an avoidance collider. It will then turn until the rock is out of the front avoidance collider but in one of the side colliders. whenever the rock leaves a side collider the ship turns toward its goal. Gives it the impression of skirting around the rock. (you can sort of see the AI ship in the distance avoid the rock, the player ship is running into it to test physics ;))


    I don't really have the need of a "nav mesh" as my levels are really open, so I use dynamic avoidance for everything.

    If you want a 3d nav mesh its really just a grid of "points" that are open or not. Look up A* pathfinding.
     
  14. dann96

    dann96

    Joined:
    Dec 6, 2014
    Posts:
    113
    I never thought about adding detection colliders, thanks.