Agent not reconnecting with Navmesh?

Hi so I have a climbing mechanic in my game that basically turns off AIPath and all that when an agent hits a wall. The climb up, then find a spot to climb up to based on the navmesh, tween to that position, then turn back on AIPath. This works for higher up walls perfectly, but when it’s a low wall like in this gif, it seems to go back to the position where it first started climbing. I’ve confirmed the position it’s moving to is correct, but when turning on the AIPath, it goes back down.

When i disable the AIPath toggle, it doesn’t do this reverse, so It’s definitely turning it back on is what’s causing this. Any idea on how I can fix this?

https://media.giphy.com/media/v1.Y2lkPTc5MGI3NjExM2tseG4yZDJjeTJnZGZrM2hwNXJlNjJnem44YWdlenlnYXBkMXpsbyZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/hm2zIbe6OUDyeGmJuw/source.gif

Here is some of the code I’m using

_climbToWalkPos = transform.position + (Vector3.up * 2) + (transform.forward * 2);

if (Physics.Raycast(_climbToWalkPos, -Vector3.up, out hit, Mathf.Infinity, _groundLayerMask))
{
    _climbToWalkPos = AstarPath.active.GetNearest(hit.point).position;
    
    _climbTween = transform.DOMove(_climbToWalkPos, .75f).SetEase(Ease.Linear);
}

Hi

How exactly do you disable the agent?
Do you disable the component using ai.enabled = false;?

Also, which version are you using?

yep exactly that

4.2.18 i believe

Hmm. Not quite sure.
But one thing you could do is to upgrade to a more recent version. Either 4.2.19, or 5.0.

ok. so there is nothing with the fact that it’s close to the ground as well? Like it’s finding a point that isn’t where it’s landed.

When you enable the component, it should try to find the closest point on the navmesh to anchor itself to.

does anything look wrong with the navmesh?

The navmesh looks perfectly fine to me.

should anything break if I update?

I’ve worked hard to keep things as compatible as possible. But there are some changes.
Take a look at the migration guide: Upgrade Guide - A* Pathfinding Project

1 Like

ok so as per my other thread, I did upgrade. This specific problem is still occurring though.

Would it be possible for you to post the full code that you are using?

removed all the extra stuff like animation. CheckForClimb is called in Update and the first section of code is run by a state machine.

void Climb_Enter()
{
    StopMove();
    ToggleAIPath(false);

    Destroy(rb);
}
void Climb_Update()
{
    if(_shouldClimb)
    {
        transform.Translate(Vector3.up * Time.deltaTime * _climbSpeed);
    }
    else if (!_shouldClimb && _climbTween == null) // no more climbing infront of bobo
    {
        _climbToWalkPos = transform.position + (Vector3.up * 2) + (transform.forward * 2);

        RaycastHit hit;
        if (Physics.Raycast(_climbToWalkPos, -Vector3.up, out hit, Mathf.Infinity, _groundLayerMask))
        {
            _climbToWalkPos = hit.point;

            Vector3[] path = new Vector3[2];
            path[0] = _climbToWalkPos + (-transform.forward * 2);
            path[1] = _climbToWalkPos;
            _climbTween = transform.DOPath(path, .75f).SetEase(Ease.InSine);
        } else
        {
            Debug.LogWarning("No  ground underneath target for " + this.gameObject);
        }
    }
    else if(!_shouldClimb && _climbTween != null) // climb to walk tween has started
    {
        if (transform.position == _climbToWalkPos)
            _msm.ChangeState(MoveStates.Walk);
    }
}
void Climb_Exit()
{
    _climbTween = null;

    StartMove();
    ToggleAIPath(true);
}
public void StartMove() 
{
    _aiPath.isStopped = false;
    _aiPath.canMove = true; 
}
public void StopMove()
{
    _aiPath.isStopped = true;
    _aiPath.canMove = false;
}

void CheckForClimb()
{
    RaycastHit climbHit;
    if (Physics.Raycast(transform.position + Vector3.up * .2f, transform.forward, out climbHit, .65f, _groundLayerMask))
    {
        if (_msm.State != MoveStates.Climb) // start climb
        {
            float angle = Vector3.Angle(Vector3.up, climbHit.normal);
            float maxSlope = AstarPath.active.data.recastGraph.maxSlope; // get max slope of graph. 45 currently.
            if (angle > maxSlope && angle < 120) // 120 is just too steep
            {
                _climbNormal = climbHit.normal;
                _shouldClimb = true;
                _msm.ChangeState(MoveStates.Climb);
            }
        } else
        {
            _climbNormal = climbHit.normal;
        }
    } else
    {
        _shouldClimb = false;
    }
}

I assume this function just sets ai.enabled ?

Well. It looks perfectly reasonable to me. However, are you sure the DOPath method doesn’t move the character back to its original position after the tween?

This only happens on short walls. So no it doesn’t because it works fine on tall walls!

Anything else I can show to help you figure out what’s going on with this? Any other scripts or something?

Would it be possible for you to share your project with me? Or a test project that shows the same issue?