Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 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 DanSuper · Jan 18, 2013 at 01:58 AM · navmeshagentnavigation

NavMeshAgent teleports to destination when OffmeshLink is Activated

I have a very particular behavior with my NavMeshAgent. If it stops at a manual OffmeshLink which is not activated, when the link becomes activated it will instantly teleport to the destination rather than navigating the Offmeshlink. Everything works fine if the Offmeshlink is activated when the NavMeshAgent reaches it.

I'm totally baffled, I don't see anything in my code that would allow a NavMeshAgent to teleport. I'm wondering if there's a bug in the NavMeshAgent involving offmeshlink activation.

I'm posting my code below, it's pretty much based on the agentLocomotion.js that came with the Unity3.5Beta preview projects, but translated into C#, and with the animation blending removed since I'm just working with a Cube right now.

 using UnityEngine;
 using System.Collections;
 
 public class SimpleNavScript : MonoBehaviour {
     
     
     private string locoState_ = "Locomotion_Stand";
     
     private NavMeshAgent navAgent;
     
     private Vector3 navAgentCurrentPosition;
     
     public Transform navigationTarget;
     
     private Vector3 navigatorTargetPosition;
     
     private Vector3 linkStart;
     
     private Vector3 linkEnd;
     
     private Quaternion linkRotation;
     
     public float jumpTimeDefault;
     private float jumpTime;
     
     private float jumpYOffset;
     
     private float jumpHeightModifier;
     
     private float jumpUpHeightModifier;
     
     private float jumpDownHeightModifier;
     
     public float jumpDownHeightModifierDefault;
     public float jumpUpHeightModifierDefault;
     
     private OffMeshLinkData link;
     private OffMeshLinkAdditionalData offlinkdata;
     
     private Hashtable additionalData;
     
     
     
     // Use this for initialization
     void Start () {
         
         
         jumpYOffset = (collider as BoxCollider).size.y;
         jumpTime = jumpTimeDefault;
         jumpUpHeightModifier = jumpUpHeightModifierDefault;
         jumpDownHeightModifier = jumpDownHeightModifierDefault;
         
         navAgent = GetComponent<NavMeshAgent>();    
         //navAgent.updatePosition = false;
         //navAgent.updateRotation = false;
         
         
         navigatorTargetPosition = navigationTarget.position;
         
         navAgent.SetDestination(navigatorTargetPosition);
         
         StartCoroutine(maintainAnimation());
     
         
         
     }
     
     IEnumerator maintainAnimation()
     {
         while(Application.isPlaying)
         {
             
             yield return StartCoroutine(locoState_);    
             
         }
         
     }
     
     
     // Update is called once per frame
     void FixedUpdate () {
         
         if(navigatorTargetPosition != navigationTarget.position)
         {
             navigatorTargetPosition = navigationTarget.position;
             navAgent.SetDestination(navigatorTargetPosition);
             
         }
         
 
     }
     
     
     IEnumerator Locomotion_Stand()
     {
         do
         {
             // Blend Animations here    
             yield return null;    
         }while(navAgent.remainingDistance == 0 );
         
         
         locoState_ = "Locomotion_Move";
         yield break;
     }
     
     IEnumerator Locomotion_Move()
     {
         do
         {
             // Blend Animations here;
             yield return null;
             
             if(navAgent.isOnOffMeshLink )
             {
                 if(navAgent.currentOffMeshLinkData.activated)
                 {
                     locoState_ = SelectLinkAnimation();
                     yield break;
                 }
             
             }
             
             
         }while(navAgent.remainingDistance != 0);
         
         locoState_ = "Locomotion_Stand";
         yield break;
 
         
     }
     
     string SelectLinkAnimation()
     {
         
         
         
          link = navAgent.currentOffMeshLinkData;
         
         if(link.offMeshLink)
         {
             offlinkdata = link.offMeshLink.gameObject.GetComponent<OffMeshLinkAdditionalData>();
             
             if(offlinkdata)
             {
                 
                 
                 additionalData = offlinkdata.GetAdditionalData();
                 
                 string offMeshLinkType = additionalData["offMeshLinkType"] as string;
                 
                 
                 if(offMeshLinkType.CompareTo("Jump") == 0)
                 {
                     
                     
         
                     return "Locomotion_JumpAnimation";
                 }
                 else if(offMeshLinkType.CompareTo("SlidePole") == 0)
                 {
                     
                     return "Locomotion_SlidePole";
                     
                 }
                 else
                 {
                     
                     return "Error";    
                 }
                 
                 
                 
                 
             }
             else
             {    
                 return "Error";
             }
             
             
             
         
         }else ///  Default Offmesh Link... just jump with default paramaters
             {
                 
                 jumpTime = jumpTimeDefault;
                 jumpUpHeightModifier = jumpUpHeightModifierDefault;    
                 jumpDownHeightModifier = jumpDownHeightModifierDefault;
                 return "Locomotion_JumpAnimation";    
                 
             
             }
         
         
         
     }
     
     
     IEnumerator Locomotion_SlidePole()
     {
         Transform slidePoleStartPosition = additionalData["slidePoleStartPosition"] as Transform;
         Transform slidePoleEndPosition = additionalData["slidePoleEndPosition"] as Transform;
     
         float jumpOnHeightModifier = (float) additionalData["jumpOnHeightModifier"];
         float jumpOnTime = (float) additionalData["jumpOnTime"];
     
         float slideTime = (float) additionalData["slideTime"];
     
         float jumpOffHeightModifier = (float) additionalData["jumpOffHeightModifier"];
         float jumpOffTime = (float) additionalData["jumpOffTime"];    
         
         additionalData = null;
         
         linkStart = link.startPos;    
         linkEnd = link.endPos;
         
         Vector3 alignDir = slidePoleStartPosition.position - linkStart;
         alignDir.y = 0.0f;
         
         linkRotation = Quaternion.LookRotation(alignDir);
         
         navAgent.Stop(true);
         
         float jumpOnStartTime = Time.time;
         
         transform.rotation = linkRotation;
         Vector3 posStartAnim = transform.position;
         
         //Debug.Log("Starting JumpAnimation... jumpHeightModifier : " + jumpHeightModifier.ToString());
         float tLerp = 0.0f;
         
         do
         {
             tLerp = (Time.time - jumpOnStartTime) / jumpOnTime;    
             Vector3 newPos = Vector3.Lerp(posStartAnim, slidePoleStartPosition.position, tLerp);
             newPos.y += jumpOnHeightModifier * Mathf.Sin(Mathf.PI * tLerp) + jumpYOffset;
             transform.position = newPos;
             
             yield return null;
             
         } while(tLerp < 1.0f);
         
         
         tLerp = 0.0f;
         float slideStartTime = Time.time;
         
         
         do
         {
             tLerp = (Time.time - slideStartTime) / slideTime;    
             Vector3 newPos = Vector3.Lerp(slidePoleStartPosition.position, slidePoleEndPosition.position, tLerp);
             transform.position = newPos;
             yield return null;
             
         } while(tLerp < 1.0f);
         
         
         
         alignDir = linkEnd - slidePoleEndPosition.position;
         alignDir.y = 0.0f;
         linkRotation = Quaternion.LookRotation(alignDir);
         transform.rotation = linkRotation;
         
         float jumpOffStartTime = Time.time;
         
         tLerp = 0.0f;
         
         do
         {
             tLerp = (Time.time - jumpOffStartTime) / jumpOffTime;    
             Vector3 newPos = Vector3.Lerp(slidePoleEndPosition.position, linkEnd, tLerp);
             newPos.y += jumpOffHeightModifier * Mathf.Sin(Mathf.PI * tLerp) + jumpYOffset;
             transform.position = newPos;
             
             yield return null;
             
         } while(tLerp < 1.0f);
         
         
         
         navAgent.CompleteOffMeshLink();
         
         //link = null;
         offlinkdata = null;
         
         navAgent.Resume();
         //transform.position = linkEnd;
         locoState_ = "Locomotion_Stand";
         yield break;
         
     }
     
         
         
     IEnumerator Locomotion_JumpAnimation()
     {
         
         if(additionalData != null)
         {
             
             if((additionalData["offMeshLinkType"] as string).CompareTo("Jump") == 0)
             {
                     jumpUpHeightModifier = (float) additionalData["jumpUpHeightModifier"];
                     jumpDownHeightModifier = (float) additionalData["jumpDownHeightModifier"];
                     jumpTime = (float)additionalData["jumpTime"];
                 
                     additionalData = null;
             }
             
             
         }
                     
         float distS = (transform.position - link.startPos).magnitude;
         float distE = (transform.position - link.endPos).magnitude;
         
         
         if(link.startPos.y < link.endPos.y)
         {
             jumpHeightModifier = jumpUpHeightModifier;    
             
         }
         else
         {
             
             jumpHeightModifier = jumpDownHeightModifier;
             
         }
         
                 
         
         if(distS < distE)
         {
             linkStart = link.startPos;    
             linkEnd = link.endPos;
             
         }
         else
         {
             linkStart = link.endPos;
             linkEnd = link.startPos;
         }
         
         Vector3 alignDir = linkEnd - linkStart;
         alignDir.y = 0.0f;
         
         linkRotation = Quaternion.LookRotation(alignDir);
         
         navAgent.Stop(true);
         
         //blend animations here
         float jumpStartTime = Time.time;
         //float jumpEndTime = Time.time + jumpTime;
         
         transform.rotation = linkRotation;
         
         Vector3 posStartAnim = transform.position;
         
         float tLerp = 0.0f;
         
         Debug.Log("Starting JumpAnimation... jumpHeightModifier : " + jumpHeightModifier.ToString());
         
         
         do
         {
             tLerp = (Time.time - jumpStartTime) / jumpTime;    
             Vector3 newPos = Vector3.Lerp(posStartAnim, linkEnd, tLerp);
             newPos.y += jumpHeightModifier * Mathf.Sin(Mathf.PI * tLerp) + jumpYOffset;
             transform.position = newPos;
             
             yield return null;
             
         } while(tLerp < 1.0f);
         
         // play idle animation
         
         navAgent.CompleteOffMeshLink();
         
         //link = null;
         offlinkdata = null;
         
         navAgent.Resume();
         //transform.position = linkEnd;
         locoState_ = "Locomotion_Stand";
         yield break;
         
     }
     
     
 }
 

 
Comment
Add comment
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

2 Replies

· Add your reply
  • Sort: 
avatar image
0

Answer by DanSuper · Jan 18, 2013 at 07:06 PM

So, I think I worked it out this morning. I added code for checking for a partial path to the Locomotion_Move method. If the path is partial, I check to see if the NavAgent is close to it's current steering target. If it is, I stop the Navmesh agent then check on subsequent frames to see if the path is stale. When the path becomes stale I reset it's target and resume the agent, which will then navigate the offmeshlink correctly. I'm putting the code changes down below so others who encounter this problem can see my solution (and hopefully comment if they see improvements)

 IEnumerator Locomotion_Move()
     {
         do
         {
             // Blend Animations here;
             yield return null;
             
             if(navAgent.pathStatus == NavMeshPathStatus.PathPartial)
             {
                 
                 if((navAgent.steeringTarget - transform.position).magnitude < 1.0f)
                 {
                     
                     isPathPartial = true;
                     navAgent.Stop();
                     Debug.Log("Stopping NavAgent");
                     
                     
                 }
                 
             }
            
             if( isPathPartial )
             {
                 if(navAgent.isPathStale)
                 {
                     navAgent.SetDestination(navigatorTargetPosition);
                     isPathPartial = false;
                     navAgent.Resume();
                     Debug.Log ("Resuming NavAgent");
                 }
             }
             
             
             
             if(navAgent.isOnOffMeshLink )
             {
                 if(navAgent.currentOffMeshLinkData.activated)
                 {
 
                     
                     locoState_ = SelectLinkAnimation();
                     yield break;
                 }
             }
                 
              
         }while(navAgent.remainingDistance != 0);
         
         locoState_ = "Locomotion_Stand";
         yield break;
 
         
     }
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 DanSuper · Jan 18, 2013 at 10:28 PM 0
Share

I'm un-marking my answer as the answer... because I get the proper behavior if a short amount of time has passed (less than a $$anonymous$$ute) but if I wait more than a $$anonymous$$ute... I still get the teleporting....

Frustrating.....

avatar image
0

Answer by nasoukikos · May 23, 2014 at 06:28 AM

I don't know if you have solved this problem but how i worked around it is by deactivating the AutoTraverseOffMeshLink from the nav mesh agent and when needed i activate it again, and reducing the navspeed to get a much more desirable effect, once he is on navmesh again, i reset my speed. how my code looks like

`if(nav.isOnOffMeshLink) { if(nav.currentOffMeshLinkData.offMeshLink.tag == "Stairs") {

                 nav.autoTraverseOffMeshLink = true;
                 nav.speed = 0.05f;
                 
         }

Comment
Add comment · 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

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

10 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

Related Questions

Can't make the manual offmeshlink work 1 Answer

Manual OffMeshLink Max Distance? 1 Answer

Enemies using navmesh are bumping each other through solid objects 1 Answer

How to reduce the rotation radius in NavMeshAgent ? 2 Answers

Why is my NavMeshAgent jerking over to the Off Mesh Link traversal point? 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