Navmesh Clamp Component does not clamp manually Moved agent to sloped Recast Graph

  • A* version: 5.4.4
  • Unity version: 6000.2.6f2 (4a4dcaec6541)

I have a recast graph with a simple slope set up and an RVOController with a simple character controller script based on the “Manual Player Movement” “Keyboard movement without pathfinding**”** documentation. Like the documentation says, I attached the Navmesh Clamp component to it, and while this does clamp to the nav in terms of the XZ plane, it doesn’t on the Y axis.

Relevant Player movement code:

void Update()
{
    m_moveAmount = m_moveAction.ReadValue<Vector2>();
    m_lookAmount = m_lookAction.ReadValue<Vector2>();

    Vector3 v = PlayerMovementDirectionRelativeToCamera(m_moveAmount) * Time.deltaTime * agentSpeed;
    Debug.Log(v);

    rvo.velocity = v;
    transform.position += v;
}
protected Vector3 PlayerMovementDirectionRelativeToCamera(Vector2 rawInput)
{
    float playerHorizantalInput = rawInput.x;
    float playerVerticalInput = rawInput.y;

    Vector3 forward = Camera.main.transform.forward;
    Vector3 right = Camera.main.transform.right;
    forward.y = 0;
    right.y = 0;
    forward = forward.normalized;
    right = right.normalized;

    Vector3 rightRelativeHorizontalInput = playerHorizantalInput * right;
    Vector3 forwardRelativeVerticalInput = playerVerticalInput * forward;

    Vector3 cameraRelativeMovement = forwardRelativeVerticalInput + rightRelativeHorizontalInput;

    cameraRelativeMovement = cameraRelativeMovement * 2f;

    return cameraRelativeMovement;
}

Now, my player movement code only moves the character on the XZ plane, I expect the order of operations to work like this:

  1. Player movement script moves player into slope in Update
  2. NavmeshClamp detects closest point on the graph and snaps the player to that position in LateUpdate

However, it seems clamp is ignoring the height of the navmesh.

Hi

This is by design. The NavmeshClamp component is only intended to clamp the agent on the XZ axes.

Typically, the navmesh is not accurate enough on the Y axis to use for ground collision. You’re usually better off using Physics.Raycast or something similar.

If you really want to, you can use:

var nn = NearestNodeConstraint.Walkable;
nn.distanceMetric = DistanceMetric.ClosestAsSeenFromAboveSoft();
var nearest = AstarPath.active.GetNearest(transform.position, nn);
if (nearest.node != null) {
    transform.position = nearest.position;
}
1 Like