Search Unity

Need help with navmeshlink and navagent.velocity movment.

Discussion in 'Scripting' started by Chance-Touchstone, Feb 10, 2020.

  1. Chance-Touchstone

    Chance-Touchstone

    Joined:
    Dec 26, 2013
    Posts:
    43
    I could use some help with a bug. I'm using a game kit asset that originally moved AI characters with .AddForce(). But I've modified it to use navagent, a navmeshlink and two navemesh surfaces for a wall and a floor. This is to get the characters to walk on the wall and the floor. If they spawn on the floor they get stuck at the wall. If they spawn on the wall the get stuck at the floor. They walk around the wall just fine but they stop by the navmeshlink and won't move to the other surface. I've added a gizmo to mark their target destination which shows they're stuck trying to get to the other surface.
    I think this has to do with the way I'm moving them with myNavAgent.Velocity. Perhaps I need to change this velocity's direction? But I'm not sure how to get it to move from the wall onto the floor.

    (Thanks in advance for your time and assistance)

    //I've tried to strip this down to the bare code here:
    Code (CSharp):
    1.     private Transform tempTransform;
    2.     public Transform TempTransform
    3.     {
    4.         get
    5.         {
    6.             if (tempTransform == null)
    7.                 tempTransform = GetComponent<Transform>();
    8.             return tempTransform;
    9.         }
    10.     }
    11.  
    12.    protected override void SetDestination()
    13.     {
    14.       //Sets the target position using a waypoint.
    15.       targetPosition = TranslatePositionToNavMesh(waypoints.Dequeue());
    16.     }
    17.  
    18.  
    19.  
    20.     protected override void UpdateMovements()
    21.     {
    22.     //...
    23.  
    24.     var heading = targetPosition - TempTransform.position;
    25.     var distance = heading.magnitude;
    26.     var direction = heading / distance;
    27.       Move(direction);
    28.  
    29.     //...
    30.     }
    31.  
    32.  
    33.     protected virtual void Move(Vector3 direction)
    34.     {
    35.         if (direction.magnitude != 0)
    36.         {
    37.             if (direction.magnitude > 1)
    38.                 direction = direction.normalized;
    39.  
    40.             var targetSpeed = GetMoveSpeed();
    41.             var targetVelocity = direction * targetSpeed;
    42.  
    43.             // Apply a force that attempts to reach our target velocity
    44.             Vector3 velocity = TempRigidbody.velocity;
    45.             Vector3 velocityChange = (targetVelocity - velocity);
    46.             velocityChange.x = Mathf.Clamp(velocityChange.x, -targetSpeed, targetSpeed);
    47.             velocityChange.y = Mathf.Clamp(velocityChange.y, -targetSpeed, targetSpeed);
    48.             velocityChange.z = Mathf.Clamp(velocityChange.z, -targetSpeed, targetSpeed);
    49.  
    50.             //Replaced this line  !!!IMPORTANT
    51.             //TempRigidbody.AddForce(velocityChange, ForceMode.VelocityChange);
    52.             //With this line for navagent velocity  !!!IMPORTANT I think my problem is related to this.
    53.             agent.velocity = velocityChange;
    54.             var rotateHeading = (TempTransform.position + direction) - TempTransform.position;
    55.             var targetRotation = Quaternion.LookRotation(rotateHeading);
    56.  
    57.             TempTransform.rotation = Quaternion.Lerp(TempTransform.rotation, targetRotation, Time.deltaTime * 15f);
    58.         }
    59.     }
    60.  
    61.  
    62.  
    63.     //Translates the waypoint position to a position on the navMesh.
    64.     private Vector3 TranslatePositionToNavMesh(Vector3 pos)
    65.     {
    66.         NavMeshHit myNavHit;
    67.         if(NavMesh.SamplePosition(pos, out myNavHit, 100, -1))
    68.         {
    69.             pos = myNavHit.position;
    70.         }
    71.         return pos;
    72.     }
     
    Last edited: Feb 11, 2020
  2. adi7b9

    adi7b9

    Joined:
    Feb 22, 2015
    Posts:
    181
    You have only a navmesh, but the wall area and ground area separated, with no connection between.

    I think by deactivating the navmesh, move your AI char to a ground pos (here you can do some jumping-fall animations) and then just reactivate navmesh.
     
  3. Chance-Touchstone

    Chance-Touchstone

    Joined:
    Dec 26, 2013
    Posts:
    43
    I have 2 nav mesh surfaces which generate 2 navmehses that are connected with a navmeshlink.

    I tested it with a simple click to move script and a block object. The block moves across the 2 surfaces perfectly. But my characters get stuck by the navmesh link.
     
    Last edited: Feb 11, 2020
  4. Chance-Touchstone

    Chance-Touchstone

    Joined:
    Dec 26, 2013
    Posts:
    43
    I got it! :D
    It still needs some tweaking but they're traversing both surfaces now. Just had to simplify it and use SetDestination instead of adding velocity.

    Code (CSharp):
    1. protected virtual void Move(Vector3 direction)
    2.     {
    3.         agent.SetDestination(direction);
    4.     }
    5.  
    6. protected override void UpdateMovements()
    7.     {
    8.     //...
    9.       //Move(direction);
    10.         Move(targetPosition);
    11.     //...
    12.     }