Search Unity

When does isOnOffMeshLink become true?

Discussion in 'Navigation' started by MaloFleur, Jul 5, 2022.

  1. MaloFleur

    MaloFleur

    Joined:
    Apr 1, 2020
    Posts:
    3
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.AI;
    3.  
    4. // Use physics raycast hit from mouse click to set agent destination
    5. [RequireComponent(typeof(NavMeshAgent))]
    6. public class ClickToMove : MonoBehaviour
    7. {
    8.     NavMeshAgent m_Agent;
    9.     RaycastHit m_HitInfo = new RaycastHit();
    10.  
    11.     void Start()
    12.     {
    13.         m_Agent = GetComponent<NavMeshAgent>();
    14.     }
    15.  
    16.     void Update()
    17.     {
    18.         if (Input.GetMouseButtonDown(0) && !Input.GetKey(KeyCode.LeftShift))
    19.         {
    20.             var ray = Camera.main.ScreenPointToRay(Input.mousePosition);
    21.             if (Physics.Raycast(ray.origin, ray.direction, out m_HitInfo))
    22.                 m_Agent.destination = m_HitInfo.point;
    23.         }
    24.     }
    25. }
    26.  
    I use the code above to get the mouse event and set the agent's destination, and the agent will move to my clicked point in an area with some manual generated navmeshlinks.

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.AI;
    3. using System.Collections;
    4.  
    5. [RequireComponent(typeof(NavMeshAgent))]
    6. public class AgentLinkMover : MonoBehaviour
    7. {
    8.     public AnimationCurve m_Curve = new AnimationCurve();
    9.     NavMeshAgent agent;
    10.     public float speed = 1f;
    11.  
    12.     IEnumerator Start()
    13.     {
    14.         NavMeshAgent agent = GetComponent<NavMeshAgent>();
    15.         agent.autoTraverseOffMeshLink = false;
    16.         while (true)
    17.         {
    18.             if (agent.isOnOffMeshLink)
    19.             {
    20.                 yield return StartCoroutine(Parabola(agent, 2.0f, 0.5f));
    21.                 agent.CompleteOffMeshLink();
    22.             }
    23.             yield return null;
    24.         }
    25.     }
    26.  
    27.     private void Awake()
    28.     {
    29.         agent = GetComponent<NavMeshAgent>();
    30.         agent.autoTraverseOffMeshLink = false;
    31.     }
    32.  
    33.     private void Update()
    34.     {
    35.         agent.speed = speed;
    36.  
    37.     }
    38.  
    39.     IEnumerator Parabola(NavMeshAgent agent, float height, float duration)
    40.     {
    41.         OffMeshLinkData data = agent.currentOffMeshLinkData;
    42.         Vector3 startPos = agent.transform.position;
    43.         Vector3 endPos = data.endPos + Vector3.up * agent.baseOffset;
    44.         float normalizedTime = 0.0f;
    45.         while (normalizedTime < 1.0f)
    46.         {
    47.             float yOffset = height * 4.0f * (normalizedTime - normalizedTime * normalizedTime);
    48.             agent.transform.position = Vector3.Lerp(startPos, endPos, normalizedTime) + yOffset * Vector3.up;
    49.             normalizedTime += Time.deltaTime / duration;
    50.             yield return null;
    51.         }
    52.     }
    53. }
    54.  
    I expect that the isOnOffMeshLink becomes true exactly in the red area and agent moves as what I coded. However, the fact is that, when the agent reach the green area, it starts jumping.
    Is there any way to reconize the red area?
    upload_2022-7-5_15-40-30.png
    upload_2022-7-5_15-43-52.png
     

    Attached Files:

  2. SIgmar_Storm

    SIgmar_Storm

    Joined:
    Jul 3, 2020
    Posts:
    5
  3. roflcopetr

    roflcopetr

    Joined:
    Jan 7, 2016
    Posts:
    10
    I noticed the agent NavLink is dependent on agent radius, so here I let the agent approach the start location before a jump is actually initiated

    Code (CSharp):
    1.  
    2. // delay in the jump coroutine
    3. float maxJumpDelay = 0.5f; // Last chance jump delay for edge cases
    4. Vector3 jumpStart = agent.currentOffMeshLinkData.startPos;
    5. Vector3 jumpEnd = agent.currentOffMeshLinkData.endPos + Vector3.up * agent.baseOffset;
    6. while (Vector3.SqrMagnitude(transform.position - jumpStart)
    7.    > _jumpStartMinDistance * _jumpStartMinDistance)
    8. {
    9.    if (Vector3.SqrMagnitude(transform.position - jumpEnd)
    10.        < Vector3.SqrMagnitude(jumpStart - jumpEnd)
    11.        || maxJumpDelay <= 0.0f)
    12.    {
    13.        break;
    14.    }
    15.  
    16.    maxJumpDelay -= Time.deltaTime;
    17.    yield return null;
    18. }
    19.  
    20. // do the jump...
    21.