Support Forum

Problem getting the starting position of a route

Hello I am having problems receiving the initial position of the new route to be calculated, I need the initial position to be able to make a rotation towards that new destination, here is a video where you can see that sometimes it turns and sometimes not due to this position:

I’m running this code:

public void MoveToPosition()
{
GraphNode vGraphNode = NextNode();
if (ToTurn)
{
this.enableRotation = false;
this.updateRotation = false;
Vector3 direction;
GraphNode vGrapghNode = NextNode();
if (vGrapghNode != null)
direction = (Vector3)vGrapghNode.position;
else if (!interpolator.valid)
direction = simulatedPosition;
else
direction = interpolator.tangent;

            if (RotateBackward(direction))
                ToTurn = false;
            else
                FinalizeMovement(tr.position, tr.rotation);
        }
        if (!ToTurn)
        {
            this.enableRotation = true;
            this.updateRotation = true;
            Vector3 nextPosition;
            Quaternion nextRotation;
            MovementUpdate(Time.deltaTime, out nextPosition, out nextRotation);
            FinalizeMovement(nextPosition, nextRotation);
        }
    }

public GraphNode NextNode()
{
if (this.path != null && this.path.path != null && this.path.path.Count > interpolator.segmentIndex + 1)
return this.path.path[interpolator.segmentIndex + 1];
else
return null;
}

public bool RotateBackward(Vector3 destination)
{
Vector3 direction = (destination - transform.position);
float vAngleResult = Vector2.Angle(new Vector2(transform.forward.x, transform.forward.z), new Vector2(direction.x, direction.z));
if (vAngleResult <= 11.5f)
return true;

        Vector3 vDireccion = destination - transform.position;
        Quaternion vRotation = Quaternion.LookRotation(vDireccion);

        vRotation = Quaternion.RotateTowards(transform.rotation, vRotation, 20 * Time.deltaTime);
        vRotation.x = transform.rotation.x;
        vRotation.z = transform.rotation.z;
        transform.rotation = vRotation;

        direction = (destination - transform.position);
        vAngleResult = Vector2.Angle(new Vector2(transform.forward.x, transform.forward.z), new Vector2(direction.x, direction.z));
        bool vResult = vAngleResult <= 11.5f;            
        return vResult;
    }

public void MovementUpdate(float deltaTime, out Vector3 nextPosition, out Quaternion nextRotation)
{
if (updatePosition) simulatedPosition = tr.position;
if (updateRotation) simulatedRotation = tr.rotation;

        Vector3 direction;

        nextPosition = CalculateNextPosition(out direction, isStopped ? 0f : deltaTime);

        if (enableRotation)
        {
            nextRotation = SimulateRotationTowards(direction, deltaTime);
            nextRotation.x = this.gameObject.transform.rotation.x;
            nextRotation.z = this.gameObject.transform.rotation.z;
        } 
        else nextRotation = simulatedRotation;
    }

public void FinalizeMovement(Vector3 nextPosition, Quaternion nextRotation)
{
previousPosition2 = previousPosition1;
previousPosition1 = simulatedPosition = nextPosition;
simulatedRotation = nextRotation;
if (updatePosition) tr.position = nextPosition;
if (updateRotation) tr.rotation = nextRotation;
}

Hi

Using the first position like that is very unstable as it might be super close to the agent itself.

I’d recommend something like this:

// Save the previous state of the interpolator
var prevDistance = interpolator.distance;
// Move the interpolator to the start of the path
interpolator.distance = 0;
var lookaheadRadius = 1.0;
// Move the interpolator to a point `lookaheadRadius` away from the agent, along the current path
interpolator.MoveToCircleIntersection2D(this.position, lookaheadRadius, this.movementPlane);
var lookDirection = interpolator.position - this.position;

// Restore the previous state of the interpolator
interpolator.distance = prevDistance;

Also: You can format big blocks of code using code fences (```) at both ends.

Hello, I am using AiLerp which does not have the movementPlane variable, I have created this variable as follows:
SimpleMovementPlane movementPlane = new SimpleMovementPlane (Quaternion.identity);
and then when turning I have tried to use interpolator.position and interpolator.tangent in RotateBackward () and neither of them solves the problem, what am I doing wrong?

AIPath does have the movement plane field (it’s in the base class AIBase). Your workaround should work equally well though.

In which way does it not solve the problem? Can you debug it and see what points it produces, and where things go wrong? (e.g. using Debug.DrawLine)

sorry I wanted to say AiLerp, Debug this it will cost me a while to adapt the code in a new scene since I work between client and server, anyway it seems to me that the problem is that sometimes it has not had time to calculate the new route and returns the position start of the above path, could this be the problem?

Can you confirm if i doing it right are using AiLerp, I have tested it and tr.position is always the same as interpolator.position

That could definitely be the problem. You will need to either calculate the path synchronously (path.BlockUntilCalculated) or wait until you receive the OnPathComplete callback.