Search Unity

setting NavMeshAgent.velocity manually not really working all the time

Discussion in 'Scripting' started by Bluvarth, Jul 29, 2019.

  1. Bluvarth

    Bluvarth

    Joined:
    Jul 11, 2017
    Posts:
    11

    Gif reference: Blue lines dictate the velocity that the agent is being set to, green lines are the current velocity of an agent. Faint red lines are the current path of an agent.


    I have my scene set up so that the red and green circles are navigating towards me on the navmesh, and when I hit them I knock them back. I'm using three NavMeshSurface scripts from navmesh components, so there are three different meshes for the three sizes (large, medium, small). For some reason however, when I set the velocity of the large size agents, if I am too close to them, there is no knock back but instead they are pushed into me. The scripts are kind of long and convoluted so I'll just include the relevant code below.

    gameHandler class (The monobehaviour)
    Code (CSharp):
    1.  
    2. private void FixedUpdate()
    3.     {
    4.         playerClass.calculateInputs();
    5.  
    6.         foreach (enemy e in enemies)
    7.         {
    8.             if (Vector3.Distance(e.transform.position, playerClass.transform.position) < e.targetRange)
    9.             {
    10.                 e.setTarget(playerClass.transform);
    11.             }
    12.             e.move();
    13.         }
    14.     }
    15.  
    16.  
    17. public static void damage(player p, enemy e, int damage, float knockback)
    18.     {
    19.         // e is the enemy being damaged by the player p
    20.         e.stun(0.5f);
    21.         e.agent.velocity = (e.transform.position - p.transform.position).normalized * knockback;
    22.         Debug.DrawRay(e.transform.position, (e.transform.position - p.transform.position).normalized * knockback, Color.blue, 1f);
    23.     }

    Enemy class where move() is called every fixedUpdate() by gameHandler
    Code (CSharp):
    1. public class enemy
    2.     {
    3.         public Transform transform;
    4.         public GameObject obj;
    5.         public NavMeshAgent agent;
    6.         bool attackingPlayer = false;
    7.         Transform target;
    8.  
    9.         public float targetRange;
    10.  
    11.         float stunTimer = 0;
    12.  
    13.         public void move()
    14.         {
    15.  
    16.             if (stunTimer > 0)
    17.             {
    18.                 stunTimer = Mathf.Max(0, stunTimer - Time.fixedDeltaTime);
    19.                 if (stunTimer == 0)
    20.                 {
    21.                     agent.isStopped = false;
    22.                 }
    23.             }
    24.             else
    25.             {
    26.                 if (attackingPlayer)
    27.                 {
    28.                     agent.SetDestination(target.position);
    29.                 }
    30.             }
    31.  
    32.         }
    33.  
    34.         public void stun(float duration)
    35.         {
    36.             stunTimer = duration;
    37.             agent.isStopped = true;
    38.         }
    39.    
    40.         public void setTarget(Transform target)
    41.         {
    42.             this.target = target;
    43.             attackingPlayer = true;
    44.         }
    45.     }
    player class where calculateInputs() is called by gameHandler every fixedUpdate()
    Code (CSharp):
    1. public class player
    2.     {
    3.  
    4.         public GameObject obj;
    5.         public Transform transform;
    6.         public NavMeshAgent agent;
    7.  
    8.         public int damage = 3; // manually set for debugging
    9.         public float knockback = 6; // manually set for debugging
    10.  
    11.         void attack(float direction) // currently only left or right, expand to all directions later
    12.         {
    13.             if (direction == 1)
    14.             {
    15.                 List<enemy> hitEnemies = new List<enemy>();
    16.                 foreach (enemy e in gameHandler.enemies)
    17.                 {
    18.                     if (Vector3.Distance(e.transform.position, transform.position + new Vector3(1, 0, 0)) < 1)
    19.                     {
    20.                         hitEnemies.Add(e);
    21.                     }
    22.                 }
    23.                 for (int i = 0; i < hitEnemies.Count; i++)
    24.                 {
    25.                     gameHandler.damage(this, hitEnemies[i], damage, knockback);
    26.                 }
    27.             }
    28.             else
    29.             {
    30.                 List<enemy> hitEnemies = new List<enemy>();
    31.                 foreach (enemy e in gameHandler.enemies)
    32.                 {
    33.                     if (Vector3.Distance(e.transform.position, transform.position + new Vector3(-1, 0, 0)) < 1)
    34.                     {
    35.                         hitEnemies.Add(e);
    36.                     }
    37.                 }
    38.                 for (int i = 0; i < hitEnemies.Count; i++)
    39.                 {
    40.                     gameHandler.damage(this, hitEnemies[i], damage, knockback);
    41.                 }
    42.             }
    43.         }
    44.  
    45.         public void calculateInputs()
    46.         {
    47.            
    48.             if (Input.GetMouseButtonDown(0))
    49.             {
    50.                 if (Input.mousePosition.x > Camera.main.pixelWidth / 2)
    51.                 {
    52.                     attack(1); // Attack to the right
    53.                 }
    54.                 else
    55.                 {
    56.                     attack(-1); // Attack to the left
    57.                 }
    58.             }
    59.         }
    60.  
    61.     }
    62.  
    63. }
     
  2. palex-nx

    palex-nx

    Joined:
    Jul 23, 2018
    Posts:
    1,748
    You're setting agent.isStopped one line prior to setting it's velocity. May be this is the reason?
     
  3. Bluvarth

    Bluvarth

    Joined:
    Jul 11, 2017
    Posts:
    11
    That was one of my futile attempts at fixing it, actually. Stopping just means that the navigation is halted and they coast to a halt. Doesn't work either way.
     
  4. palex-nx

    palex-nx

    Joined:
    Jul 23, 2018
    Posts:
    1,748
    NavMesh agents contains a lot of weird logic. I've made 2 games using navmesh but didn't completely understood it. I know there are some limitations on what properties may be changed in what agent state. What I do to debug things like this (it happens quite often with unity agents) is to debug.log whole agent state prior changing subject property and isolate changes what breaks each other. I bet velocity change will work if you'r agent will be alone in the scene moving from A to B and distance(A, B) is large enough. After get it working this way, try adding iteractions one by one and see what of them breaks velocity change.
     
  5. HYEONWOO

    HYEONWOO

    Joined:
    Jan 26, 2017
    Posts:
    1
    Use ResetPath() before control velocity if you are using velocity and SetDestination()
    I had a same problem and It worked.
     
    superDMT and CodesCove like this.
  6. ChiuanWei

    ChiuanWei

    Joined:
    Jan 29, 2012
    Posts:
    131
    it's not work for me. i don't know why the character need to SetDestination first. if not doing this once... setting the velocity is not working.
     
    iquos likes this.
  7. sas67uss

    sas67uss

    Joined:
    Feb 8, 2020
    Posts:
    81
    Agent.velocity is the current speed of the agent . that means it must be in moving to have velocity.the movement of agent in unity is the constant acceleration motion.
    You can change the acceleration to slow down the agent to reach the maximum speed. and then in during path changing velocity of agent .
     
  8. Atto2O

    Atto2O

    Joined:
    Aug 19, 2018
    Posts:
    6
    Just if someone is facing the same problem as me.

    Whe i did change the agent velocity from hight value to low one, it take same time to reach the slow velocity,i fixed it by set a higher value to acceleration.
     
  9. ArachnidAnimal

    ArachnidAnimal

    Joined:
    Mar 3, 2015
    Posts:
    1,832
    I remember having issues with setting the velocity. Setting the .speed instead worked:
    Code (csharp):
    1.  
    2. private void SetAgentSpeedAndAcceleration ()
    3.     {
    4.         agent.acceleration = ...
    5.         agent.speed =...
    6.         agent.angularSpeed =...
    7.     }
    8.