Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by kitfox-com · Feb 03, 2017 at 09:02 PM · scripting problemnavmeshnavmeshagent

How to have a script temporarily take control of a NavMeshAgent?

I'm trying to implement a custom animation for when my character follows an OffMeshLink on a NavMesh. I found some code from the Unity manual that is supposed to give you direct control over following an OffMeshLink - unfortunately, it is not working.

https://docs.unity3d.com/ScriptReference/AI.NavMeshAgent.CompleteOffMeshLink.html

I copied and pasted the code into a C# script and added the script as a component to my object with a NavMeshAgent. When my agent walks over an OffMeshLink, the agent freezes and will not move further. After some debugging the problem seems to be that the script becomes stuck on the line

 agent.transform.position = Vector3.MoveTowards (agent.transform.position, endPos, agent.speed*Time.deltaTime);

This is because agent.transform.position is not updating. Even though agent.transform.position is being assigned a new value each time through the while loop, something is overriding this and each time the line is evaluated again, agent.transform.position has reverted to its original value. I can get around this by setting agent.enabled = false before evaluating this loop; however, this creates a jerky animation and I'm not sure it's the right way to go about it.

What's the right way to have the script take control of my NavMesh agent while it's supposed to be following the OffMeshLink?

 using UnityEngine;
 using System.Collections;public enum OffMeshLinkMoveMethod {
     Teleport,
     NormalSpeed,
     Parabola
 }[RequireComponent (typeof (NavMeshAgent))]
 public class AgentLinkMover : MonoBehaviour {
     public OffMeshLinkMoveMethod method = OffMeshLinkMoveMethod.Parabola;
     IEnumerator Start () {
         NavMeshAgent agent = GetComponent<NavMeshAgent> ();
         agent.autoTraverseOffMeshLink = false;
         while (true) {
             if (agent.isOnOffMeshLink) {
                 if (method == OffMeshLinkMoveMethod.NormalSpeed)
                     yield return StartCoroutine (NormalSpeed (agent));
                 else if (method == OffMeshLinkMoveMethod.Parabola)
                     yield return StartCoroutine (Parabola (agent, 2.0f, 0.5f));
                 agent.CompleteOffMeshLink ();
             }
             yield return null;
         }
     }
     IEnumerator NormalSpeed (NavMeshAgent agent) {
         OffMeshLinkData data = agent.currentOffMeshLinkData;
         Vector3 endPos = data.endPos + Vector3.up*agent.baseOffset;
         while (agent.transform.position != endPos) {
             agent.transform.position = Vector3.MoveTowards (agent.transform.position, endPos, agent.speed*Time.deltaTime);
             yield return null;
         }
     }
     IEnumerator Parabola (NavMeshAgent agent, float height, float duration) {
         OffMeshLinkData data = agent.currentOffMeshLinkData;
         Vector3 startPos = agent.transform.position;
         Vector3 endPos = data.endPos + Vector3.up*agent.baseOffset;
         float normalizedTime = 0.0f;
         while (normalizedTime < 1.0f) {
             float yOffset = height * 4.0f*(normalizedTime - normalizedTime*normalizedTime);
             agent.transform.position = Vector3.Lerp (startPos, endPos, normalizedTime) + yOffset * Vector3.up;
             normalizedTime += Time.deltaTime / duration;
             yield return null;
         }
     }
 }

Comment
Add comment · Show 1
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Jellezilla · Nov 11, 2019 at 08:22 PM 0
Share

For avoiding the agent getting stuck, a workaround is to set the method to curve with a value of 0.

1 Reply

· Add your reply
  • Sort: 
avatar image
-1

Answer by wizardos · Sep 18, 2017 at 02:41 PM

The example works very well. You need to add a few lines of code somewhere.

Here is an example:

  1. Start the coroutine (line 19).

  2. Set a destination (line 26).

    using UnityEngine; using System.Collections; using UnityEngine.AI;

    public enum OffMeshLinkMoveMethod { Teleport, NormalSpeed, Parabola }

    [RequireComponent(typeof(NavMeshAgent))] public class AgentLinkMover : MonoBehaviour { public OffMeshLinkMoveMethod method = OffMeshLinkMoveMethod.Parabola;

      private void Start()
         {
             StartCoroutine(StartMoving()); // <--
         }
     
         IEnumerator StartMoving()
         {
             NavMeshAgent agent = GetComponent<NavMeshAgent>();
             agent.autoTraverseOffMeshLink = false;
             agent.SetDestination(Vector3.zero); // <--
             while (true)
             {
                 if (agent.isOnOffMeshLink)
                 {
                     if (method == OffMeshLinkMoveMethod.NormalSpeed)
                         yield return StartCoroutine(NormalSpeed(agent));
                     else if (method == OffMeshLinkMoveMethod.Parabola)
                         yield return StartCoroutine(Parabola(agent, 2.0f, 0.5f));
                     agent.CompleteOffMeshLink();
                 }
                 yield return null;
             }
         }
     
         IEnumerator NormalSpeed(NavMeshAgent agent)
         {
             OffMeshLinkData data = agent.currentOffMeshLinkData;
             Vector3 endPos = data.endPos + Vector3.up * agent.baseOffset;
             while (agent.transform.position != endPos)
             {
                 agent.transform.position = Vector3.MoveTowards(agent.transform.position, endPos, agent.speed * Time.deltaTime);
                 yield return null;
             }
         }
     
         IEnumerator Parabola(NavMeshAgent agent, float height, float duration)
         {
             OffMeshLinkData data = agent.currentOffMeshLinkData;
             Vector3 startPos = agent.transform.position;
             Vector3 endPos = data.endPos + Vector3.up * agent.baseOffset;
             float normalizedTime = 0.0f;
             while (normalizedTime < 1.0f)
             {
                 float yOffset = height * 4.0f * (normalizedTime - normalizedTime * normalizedTime);
                 agent.transform.position = Vector3.Lerp(startPos, endPos, normalizedTime) + yOffset * Vector3.up;
                 normalizedTime += Time.deltaTime / duration;
                 yield return null;
             }
         }
     }
    
Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Jellezilla · Nov 11, 2019 at 08:17 PM 0
Share

I just encountered exact same issue, and this proposed and poorly formatted solution is not a solution. The IEnumerator Start is already being run, so no need to call it again. And setting the agents destination to 0, 0, 0 doesn't really make any sense to me

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

86 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

i cant acces the navmesh surface 0 Answers

Making a queue for NavMeshAgents 0 Answers

How to Calculate NavMeshAgent Paths Quicker 1 Answer

Make NavMesh move to random positions 1 Answer

Mesh as Navmesh? 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges