Search Unity

Rotate agent orientation before meet the target?

Discussion in 'Navigation' started by glenncai, Feb 8, 2019.

  1. glenncai

    glenncai

    Joined:
    Feb 5, 2019
    Posts:
    4
    Hi, I’m new to Unity and starting to learn navigation.
    My moving agent and target are a same size rectangular. Is there any way to make the agent align/overlap with the target?
    The agent and the target are always meeting on the center point, so in this case (shown in the image) the agent will never go to its destination since the target is so close to the wall. How can I tell the agent to rotate its orientation, so it can parallel to the target before they meet? Thank you!
     

    Attached Files:

    • p4.jpg
      p4.jpg
      File size:
      78.8 KB
      Views:
      582
  2. Yandalf

    Yandalf

    Joined:
    Feb 11, 2014
    Posts:
    491
    This is going to require a bit of scripting, but it should be doable.
    First of all you want to make sure your model is a child of an empty gameobject that has your agent component.
    Write a little script for the model gameobject that finds the agent.
    This component will rotate the model, but only when your agent is almost there.

    Code (CSharp):
    1. NavMeshAgent m_agent;
    2. float m_step = 10; //This is how fast you'll rotate, in degrees per second
    3.  
    4. void Start()
    5. {
    6.     m_agent = GetComponentInParent<NavMeshAgent>();
    7. }
    8.  
    9. void Update()
    10. {
    11.     //We check if the agent is moving and close enough to his destination to begin slowing down
    12.     if(m_agent.velocity.sqrMagnitude != 0 && m_agent.remainingDistance <= m_agent.stoppingDistance)
    13.     {
    14.          //Here we rotate
    15.          transform.rotation = Quaternion.RotateTowards(transform.rotation, target.rotation, m_step);
    16.     }
    17. }
    You might have to reset the model's rotation when you begin moving again though, else you'll end up with more and more offset which could cause issues like crab-walking and such.
    Unfortunately there is no easy way to detect when your agent has just started moving, so you'll have to keep track of a few more things. We can keep track of the agent's destination, when this has changed we know we'll begin moving soon.

    Code (CSharp):
    1. Vector3 m_lastDestination;
    2.  
    3. void Update()
    4. {
    5.     if(m_agent.destination != m_lastDestination)
    6.     {
    7.         m_transform.rotation = Quaternion.RotateTowards(m_transfrom.rotation, Quaternion.identity, m_step);
    8.         if(m_transform.rotation == Quaternion.identity)
    9.         {
    10.             m_lastDestination = m_agent.destination;
    11.         }
    12.     }
    13. }
    This is a little messy and might open up issues in specific cases, but it's a simple rough solution you can probably tweak around.
    On another note, the NavMeshAgent expects your character's shape to be capsule-like, meaning objects like your block that are much bigger on one side than the other will possibly get shoved into areas that should be too small for them.