Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Issue with Agentmesh

Discussion in 'Navigation' started by LionFische, Feb 9, 2016.

  1. LionFische

    LionFische

    Joined:
    Oct 16, 2015
    Posts:
    107
    Hi, I have a simple sandbox created with a player and a few cubs patrolling through a set of waypoints that I have stored in a list. It is working fine using the following code to give patrols their target destination...

    Code (CSharp):
    1. transform.position = Vector3.MoveTowards (transform.position, currentWaypoint.position, speed * Time.deltaTime);
    I have then decided to add a nav mesh so as to include some obstacles for the patrols. To do this, I added a nav agent to the patrol cubes and then use the following code to set their target destination...

    Code (CSharp):
    1. navAgent.SetDestination(currentWaypoint.position);
    I find when I use this navAgent.SetDestination that the cube reaches the first waypoint and then tips over and gets stuck. I have tried to freeze rotation in the inspector but that seems to make no difference.

    Here is the code for the function I have created.

    Code (CSharp):
    1.     public void moveEnemy()
    2.     {
    3.  
    4.         if (GameObject.Find ("Player") != null && PT.isDetected == true) {
    5.  
    6.             Debug.Log ("The Player is in detected!");
    7.  
    8.             currentPatrolTarget = GameObject.Find ("Player").transform;
    9.             navAgent.SetDestination(currentPatrolTarget.position);
    10.             //transform.position = Vector3.MoveTowards (transform.position, currentPatrolTarget.transform.position, speed * Time.deltaTime);
    11.         } else
    12.         {
    13.             float distanceToCurrent = Vector2.Distance (transform.position, currentWaypoint.position);
    14.  
    15.             if (distanceToCurrent == 0) {
    16.                 if (wayPointNumber != wayPointsList.Count - 1) {
    17.                     wayPointNumber++;
    18.                     currentWaypoint = wayPointsList [wayPointNumber];
    19.                 } else {
    20.                     wayPointNumber = 0;
    21.                     currentWaypoint = wayPointsList [wayPointNumber];
    22.                 }
    23.             }
    24.             navAgent.SetDestination(currentWaypoint.position);
    25.             //transform.position = Vector3.MoveTowards (transform.position, currentWaypoint.position, speed * Time.deltaTime);
    26.  
    27.             //Establish the transform to give the raycast a target to rotate too
    28.             Vector3 relativePos = currentWaypoint.position - transform.position;
    29.             transform.rotation = Quaternion.LookRotation (relativePos);
    30.  
    31.             // targetRotation would be the result of your Quat.LookRotation call
    32. //        transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, speed * Time.deltaTime);
    33.         }
    34.     }
    Any thoughts or advice appreciated.

    2h
     
  2. pixxelbob

    pixxelbob

    Joined:
    Aug 26, 2014
    Posts:
    111
    What is moveEnemy called? Is it called as part of an Update loop?


    The method you're using to check the distance to the current way point is not good enough.
    Replace your distanceToCurrent with the following:
    Code (CSharp):
    1. if(navAgent.remainingDistance <= navAgent.stoppingDistance)
    2. {
    3.     if (wayPointNumber != wayPointsList.Count - 1) {
    4.         wayPointNumber++;
    5.         navAgent.SetDestination(wayPointsList [wayPointNumber].position);
    6.     } else {
    7.         wayPointNumber = 0;
    8.         navAgent.SetDestination(wayPointsList [wayPointNumber].position);
    9.     }
    10.  
    11. }
    You will find a good example of this in the Stealth project.
    Specifically the EnemyAI component which i think you could probably just use verbatim for what you need.
     
    Last edited: Feb 9, 2016
    LionFische likes this.
  3. LionFische

    LionFische

    Joined:
    Oct 16, 2015
    Posts:
    107

    Hi Bob, thanks for the reply.

    Yes, I have moveEnemy called in the update method.

    Code (CSharp):
    1.     void Update () {
    2.         moveEnemy ();
    3.     }
    2h
     
  4. pixxelbob

    pixxelbob

    Joined:
    Aug 26, 2014
    Posts:
    111
    No probs.
    That being the case there are a number of issues with your moveEnemy method if I'm honest.
    Using GameObject.Find in an Update loop is bad. You should create a reference to the player in Awake() and use that.

    Also you're setting the NavAgent's destination each frame which is also not great. You should only set the destination when the target needs to change.

    I've updated my post with a link to the EnemyAI script from the Stealth tutorial. I recommend you use that and adapt for what you need. It's very robust and follows some good practices.
     
    LionFische likes this.
  5. LionFische

    LionFische

    Joined:
    Oct 16, 2015
    Posts:
    107
    Thanks pBob.

    The reason I used the GameObject.find was that I had an issue when the player died as I was destroying the object. It's lack of existence at that stage had implications for other scripts, so I then altered things so that they only ran as long as the player was known to exist.

    I will look into the issues you have mentioned, ref in Awake().

    I have the patrol setup so that if the player is detected, it will reassign it's destination to the players position as long as the player is visible to the patrol. To do this I'm guessing that I have to keep updating the NavAgent destination to follow the player?

    I will have a look at the script you have linked.

    Thank you very much for the help, I really appreciate it.

    2h