Interpolation to exact position

Hello,

I’m trying to make my characters to stop moving so “edgy”, they are going from node to node, and I would like for them to just go straight to building corners. Also the local avoidance is needed to avoid other characters. Here’s the screenshot to display what I want it to do.

The black line is what I want him to go, and the green one is the one he’s actually going. I’ve tried several seeker’s start and end points, but with found no correct way.

Here’s the script which is holds all the moving in my game.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
using Pathfinding;

using Pathfinding.RVO;
using Pathfinding.Util;
namespace Cult
{
    public class MovementCommander : NetworkBehaviour
    {
        private DirectionChange clientDirection = new DirectionChange(), serverDirection = new DirectionChange();
     //   private UnityEngine.AI.NavMeshAgent agent;
        private Coroutine resumingAfterAction;
        public NetworkCubeFollower networkCube;
        PersonObject pObj;
        public Vector3 targetPos;
        public Vector3 talkingTargetPosition;

        [SyncVar]
        private Vector3 firstNodePositionOnServer;

        private Vector3 lastDirection;
        public Vector3 lastDirectionTest
        {
            get
            {
                return lastDirection;
            }
        }
        private Vector3 lastPointerPoisition, lerpstart;
        public float MinMovementDistance = 1f;
        public float spedFolowingMod = 4;
        private float t;
        private float epsilon;
        private float sprintDistance;

        [SyncVar]
        public bool canIMove = true;

        private bool stoped;
        private bool stopped;
        internal Vector3 direction;

        public float networkCubeSendInterval;

        /// <summary>
        /// this should be equal to 1 when ping and interval is aroun 0.02 and around 4 at high ping
        /// </summary>
        private float networkSpeedModificator
        {
            get
            {
                if (networkCubeSendInterval < CGC.i.NetworkCondition.PingTime / 1000)
                {
                    return Mathf.Clamp(CGC.i.NetworkCondition.PingTime * 12, 1, 4);
                }
                else
                {
                    return Mathf.Clamp(networkCubeSendInterval * 12, 1, 4);
                }
            }
        }

        public class DirectionChange
        {
            public Vector3 direction;
            public float time;
        }

        public override void OnStartLocalPlayer()
        {
            direction = transform.position;
        }
        internal void stopForMakeingAction(bool doStop, float time = 0)
        {
            if (resumingAfterAction != null)
                StopCoroutine(resumingAfterAction);
            resumingAfterAction = null;
            if (doStop)
            {
                pathSpeed = 0;
                
                //agent.speed = 0;
                //agent.Stop();
                stoped = true;
            }
            else
            {
                resumingAfterAction = StartCoroutine(resumeAfterAction(time));
            }
        }

        private IEnumerator resumeAfterAction(float time)
        {
            yield return new WaitForSeconds(time);
            stoped = false;
            pathSpeed = speed();
            if (seeker.isActiveAndEnabled)
                pathSpeed = speed();
            else if(!pObj.person.dead)
            {
                seeker.enabled = true;
                pathSpeed = speed();
            }
        }

        private float speed()
        {
            if (stoped)
                return 0;
            if (pObj.personStats.maxSpeed == 0)
                return 0;
            if (!isServer)
                return pObj.personStats.maxSpeed * (1 + speedNetworkAddjustment);
            sprintDistance = pObj.personStats.maxSpeed * (1 + speedNetworkAddjustment);
            float v;
            if (seeker.isActiveAndEnabled)
            {
                    v = pObj.personStats.maxSpeed;
            }
            else
            {
                v = pObj.personStats.maxSpeed;
            }
            if (float.IsNaN(v))
            {
                Debug.Log("err");
            }
            return v;
        }
        Seeker seeker;
        CharacterController controller;
        internal void restartAgent()
        {
            pathSpeed = speed();
        }

        private IEnumerator reTarget()
        {
            while (true)
            {
                yield return new WaitForSeconds(0.1f + Random.value);
                if (!pObj.person.dead)

                    if (pathSpeed > 0)
                    {
                        pathSpeed = speed();
                    }
            }
        }

        internal void disableMovement(bool dis = true)
        {
            this.enabled = !dis;
            if (seeker == null)
                seeker = GetComponent<Seeker>();
            seeker.enabled = !dis;
            if (dis == false)
            {
                pathSpeed = speed();
            }
        }

        internal bool hasPath
        {
            get
            {
                return path != null;
            }
        }
        private const float sqrErrorMargin = 25f;
        private const float sqrErrorMarginMax = 25f;
        private const float refreshmentRate = 0.3f;
        private const float speedNetworkAddjustmentRange = 3f;
        private const float maxSpeedModifier = 2;
        private const float teleportationNeedTimeLimit = 0.5f;
        private const float sqrteleportationDistance = 900f;
        private float speedNetworkAddjustment;
        private Vector3 lastDestination;
        private float lastTimeUpdated;
        public bool dirty;
        private float teleportationNeedDetectionTime;
        float lastUpdate;
        public float UpdateTime
        {
            get
            {
                if (pObj.prophetOf != -1)
                    return 0;
                if (pObj.cult != Cult.getNoCult())
                    return 0.1f;
                if (!pObj.isPeacefull())
                    return 0.2f;
                return 0.5f;
            }
        }
        float oldUpdateTime;
        float u;
        internal bool isMoving
        {
            get
            {
                return (transform.position - lastPosition).sqrMagnitude > 1;
            }
        }
        public Vector3 lastPosition;
        Vector3 directionToNetworkCube;

        Vector3 directionToServerNode;
        Vector3 directionToClientNode;
        public Path path;

        protected PathInterpolator interpolator = new PathInterpolator();
        public Transform target;
        public bool canSearch = true;
        public bool canMove = true;
        protected RVOController rvoController;
        protected Transform tr;
        protected bool canSearchAgain = true;
        public float pathSpeed = 7;
        public float nextWaypointDistance = 3;
        private int currentWaypoint = 0;
        public float repathRate = 0.5f;
        private float lastRepath = -9999;
        public Transform targetPosition;
        public bool TargetReached { get; protected set; }
        private bool startHasRun = false;
        protected Vector2 velocity2D;
        public float slowdownDistance = 0.6F;
        public float endReachedDistance = 0.2F;
        public float rotationSpeed = 360;
        protected float verticalVelocity;
        protected Vector3 targetPoint;
        protected Vector3 velocity;
        public float pickNextWaypointDist = 2;

        protected IMovementPlane movementPlane = GraphTransform.identityTransform;

        public virtual void SearchPath()
        {
            if (target == null) throw new System.InvalidOperationException("Target is null");
            lastRepath = Time.time;
            Vector3 targetPosition = target.position;
            canSearchAgain = false;
            seeker.StartPath(GetFeetPosition(), targetPosition);
        }
        public virtual Vector3 GetFeetPosition()
        {
            if (rvoController != null && rvoController.enabled && rvoController.movementPlane == MovementPlane.XZ)
            {
                return tr.position + tr.up * (rvoController.center - rvoController.height * 0.5f);
            }
            if (controller != null && controller.enabled)
            {
                return tr.TransformPoint(controller.center) - Vector3.up * controller.height * 0.5F;
            }

            return tr.position;
        }

        public void OnPathComplete(Path _p)
        {
            ABPath p = _p as ABPath;

            if (p == null) throw new System.Exception("This function only handles ABPaths, do not use special path types");
            canSearchAgain = true;
            p.Claim(this);
            if (p.error)
            {
                p.Release(this);
                currentWaypoint = 0;
                return;
            }
            if (path != null) path.Release(this);
            path = p;
            if (path.vectorPath.Count == 1) path.vectorPath.Add(path.vectorPath[0]);
            interpolator.SetPath(path.vectorPath);

            var graph = AstarData.GetGraph(path.path[0]) as ITransformedGraph;
            movementPlane = graph != null ? graph.transform : GraphTransform.identityTransform;

            // Reset some variables
            TargetReached = false;

            // Simulate movement from the point where the path was requested
            // to where we are right now. This reduces the risk that the agent
            // gets confused because the first point in the path is far away
            // from the current position (possibly behind it which could cause
            // the agent to turn around, and that looks pretty bad).
            interpolator.MoveToLocallyClosestPoint((GetFeetPosition() + p.originalStartPoint) * 0.5f);
            interpolator.MoveToLocallyClosestPoint(GetFeetPosition());
        }
        Vector3 dir = Vector3.zero;
        void UpdateMoveing()
        {
            
                if (Time.time - lastRepath > repathRate && seeker.IsDone())
                {
                    lastRepath = Time.time + Random.value * repathRate * 0.5f;
                }
                if (path == null)
                {
                return;
            }
                if (currentWaypoint > path.vectorPath.Count) return;
            if (currentWaypoint == path.vectorPath.Count)
                {
                    currentWaypoint++;
                return;
            }
                 dir = (path.vectorPath[currentWaypoint] - transform.position);
                float dirMag = dir.sqrMagnitude;
                
                dir = dir.normalized;
                
                dir *= pathSpeed ;
 
            dir *= Time.deltaTime;
            velocity2D = speed() * dir;
            bool alreadyCounted = false;
            Vector2 delta2D = new Vector2(0,0);

            if (rvoController != null && rvoController.enabled)
            {
                     var rvoTarget = transform.position + movementPlane.ToWorld(Vector2.ClampMagnitude(velocity2D, (path.vectorPath[currentWaypoint ] - transform.position).magnitude), 0f);
                    rvoController.SetTarget(rvoTarget, velocity2D.magnitude, velocity2D.magnitude);
            }
            //if(!alreadyCounted)
            delta2D = CalculateDeltaToMoveThisFrame(movementPlane.ToPlane(transform.position), (path.vectorPath[currentWaypoint] - transform.position).magnitude, Time.deltaTime);
            Move(transform.position, movementPlane.ToWorld(delta2D, verticalVelocity * Time.deltaTime));
            velocity = movementPlane.ToWorld(velocity2D, verticalVelocity);

            if (dirMag < dir.sqrMagnitude)
                dir = (path.vectorPath[currentWaypoint] - transform.position);
            else
            {
                if(pObj.target == null || (pObj.target !=null && (Vector3.Distance(pObj.target.transform.position, pObj.transform.position) > pObj.person.activeInteraction.activationDistance)))
                    transform.LookAt(transform.position + dir);
            }
            transform.position = Vector3.MoveTowards(transform.position, transform.position + dir, 1f);
            if ((transform.position - path.vectorPath[currentWaypoint]).sqrMagnitude < nextWaypointDistance * nextWaypointDistance)
            {
                //if (speed() > 10)
                    //currentWaypoint += 2;
                //else
                currentWaypoint++;
            }
            
        }

        public virtual void OnTargetReached()
        {
            // The end of the path has been reached.
            // If you want custom logic for when the AI has reached it's destination
            // add it here.
            // You can also create a new script which inherits from this one
            // and override the function in that script
        }
       

        //protected void MovementUpdate(float deltaTime)
        //{
        //    if (!canMove) return;

        //    if (!interpolator.valid )
        //    {
        //        velocity2D = Vector3.zero;
        //    }
        //    else
        //    {
        //        if(/*GetComponent<EffectInvoker>().posibleTargets.Count >= 2 &&*/ path.vectorPath.Count>1)
        //        {
        //            interpolator.SetPath(path.vectorPath);
        //            var currentPosition = tr.position;

        //            interpolator.MoveToLocallyClosestPoint(currentPosition, true, false);
        //            interpolator.MoveToCircleIntersection2D(currentPosition, pickNextWaypointDist, movementPlane);
        //            targetPoint = interpolator.position;
        //            var dir = movementPlane.ToPlane(targetPoint - currentPosition);

        //            var distanceToEnd = dir.magnitude + interpolator.remainingDistance;
        //            // How fast to move depending on the distance to the target.
        //            // Move slower as the character gets closer to the target.
        //            float slowdown = slowdownDistance > 0 ? (speed() / 10f) / slowdownDistance : 1;

        //            // a = v/t, should probably expose as a variable
        //            float acceleration = speed() / 1f;
        //            //velocity2D += MovementUtilities.CalculateAccelerationToReachPoint(dir, dir.normalized * speed(), velocity2D, acceleration, speed()) * deltaTime;
        //            //velocity2D = MovementUtilities.ClampVelocity(velocity2D, speed(), slowdown, true, movementPlane.ToPlane(tr.forward));

        //            velocity2D = speed() * dir;
        //            //ApplyGravity(deltaTime);

        //            if (distanceToEnd <= endReachedDistance && !TargetReached)
        //            {
        //                TargetReached = true;
        //                OnTargetReached();
        //            }

        //            // Rotate towards the direction we are moving in
        //            var currentRotationSpeed = rotationSpeed * Mathf.Clamp01((Mathf.Sqrt(slowdown) - 0.3f) / 0.7f);
        //            RotateTowards(velocity2D, currentRotationSpeed * deltaTime);

        //            if (rvoController != null && rvoController.enabled)
        //            {
        //                // Send a message to the RVOController that we want to move
        //                // with this velocity. In the next simulation step, this
        //                // velocity will be processed and it will be fed back to the
        //                // rvo controller and finally it will be used by this script
        //                // when calling the CalculateMovementDelta method below

        //                // Make sure that we don't move further than to the end point
        //                // of the path. If the RVO simulation FPS is low and we did
        //                // not do this, the agent might overshoot the target a lot.
        //                var rvoTarget = currentPosition + movementPlane.ToWorld(Vector2.ClampMagnitude(velocity2D, distanceToEnd), 0f);
        //                rvoController.SetTarget(rvoTarget, velocity2D.magnitude, speed());
        //            }
        //            if(distanceToEnd > speed()/10f)
        //            {
        //                var delta2D = CalculateDeltaToMoveThisFrame(movementPlane.ToPlane(currentPosition), distanceToEnd, deltaTime);
        //                Move(currentPosition, movementPlane.ToWorld(delta2D, verticalVelocity * deltaTime));
        //                velocity = movementPlane.ToWorld(velocity2D, verticalVelocity);
        //            }
        //            else
        //            {
        //                velocity = Vector3.zero;
        //            }

        //        }
        //        //else
        //        //{
        //        //    UpdateMoveing();
        //        //}

        //    }
        //}

        protected void Move(Vector3 position3D, Vector3 deltaPosition)
        {
            bool positionDirty = false;

            if (controller != null && controller.enabled)
            {
                // Use CharacterController
                tr.position = position3D;
                controller.Move(deltaPosition);
                // Grab the position after the movement to be able to take physics into account
                // TODO: Add this into the clampedPosition calculation below to make RVO better respond to physics
                position3D = tr.position;
                if (controller.isGrounded) verticalVelocity = 0;
            }
            else
            {
                // Use Transform, Rigidbody or Rigidbody2D
                float lastElevation;
                movementPlane.ToPlane(position3D, out lastElevation);
                position3D += deltaPosition;

                // Position the character on the ground
                //if (usingGravity) position3D = RaycastPosition(position3D, lastElevation);
                positionDirty = true;
            }

            // Clamp the position to the navmesh after movement is done
            var clampedPosition = /*ClampToNavmesh(*/position3D/*);*/;

            // We cannot simply check for equality because some precision may be lost
            // if any coordinate transformations are used.
            if ((clampedPosition - position3D).sqrMagnitude > 0.001f * 0.001f)
            {
                // The agent was outside the navmesh. Remove that component of the velocity
                // so that the velocity only goes along the direction of the wall, not into it
                var difference = movementPlane.ToPlane(clampedPosition - position3D);
                velocity2D -= difference * Vector2.Dot(difference, velocity2D) / difference.sqrMagnitude;

                // Make sure the RVO system knows that there was a collision here
                // Otherwise other agents may think this agent continued
                // to move forwards and avoidance quality may suffer
                if (rvoController != null && rvoController.enabled)
                {
                    rvoController.SetCollisionNormal(difference);
                }
                position3D = clampedPosition;
                positionDirty = true;
            }

            // Assign the final position to the character if we haven't already set it
            if (positionDirty)
            {
                // Note that rigid.MovePosition may or may not move the character immediately.
                // Check the Unity documentation for the special cases.
                //if (rigid != null) rigid.MovePosition(position3D);
                //else if (rigid2D != null) rigid2D.MovePosition(position3D);
                //else
                    tr.position = position3D;
            }
        }

        protected Vector2 CalculateDeltaToMoveThisFrame(Vector2 position, float distanceToEndOfPath, float deltaTime)
        {
            if (rvoController != null && rvoController.enabled)
            {
                // Use RVOController to get a processed delta position
                // such that collisions will be avoided if possible
                return movementPlane.ToPlane(rvoController.CalculateMovementDelta(movementPlane.ToWorld(position, 0), deltaTime));
            }
            // Direction and distance to move during this frame
            return Vector2.ClampMagnitude(velocity2D * deltaTime, distanceToEndOfPath);
        }
        protected virtual void RotateTowards(Vector2 direction, float maxDegrees)
        {
            if (direction != Vector2.zero)
            {
                Quaternion targetRotation = Quaternion.LookRotation(movementPlane.ToWorld(direction, 0), movementPlane.ToWorld(Vector2.zero, 1));
                tr.rotation = Quaternion.RotateTowards(tr.rotation, targetRotation, maxDegrees);
            }
        }

        public void OnDisable()
        {
            seeker.CancelCurrentPathRequest();

            // Release current path so that it can be pooled
            if (path != null) path.Release(this);
            path = null;

            // Make sure we no longer receive callbacks when paths complete
            seeker.pathCallback -= OnPathComplete;
        }
        protected IEnumerator RepeatTrySearchPath()
        {
            while (true) yield return new WaitForSeconds(TrySearchPath());
        }
        public float TrySearchPath()
        {
            if (Time.time - lastRepath >= repathRate && canSearchAgain && canSearch && target != null)
            {
                SearchPath();
                return repathRate;
            }
            else
            {
                float v = repathRate - (Time.time - lastRepath);
                return v < 0 ? 0 : v;
            }
        }
        private void Update()
        {
            //MovementUpdate(Time.deltaTime);
            UpdateMoveing();
            if (Time.time - lastUpdate < u)
                return;
            
            lastPosition = transform.position;
            lastUpdate = Time.time;
            u = UpdateTime;
            if (oldUpdateTime!=u&&networkCube!=null)
            {
                oldUpdateTime = u;
                networkCube.GetComponent<NetworkTransform>().sendInterval = 0.02f + u;
            }
            if (isServer)
            {
                setDestination(serverDirection.direction);
                
                if (path !=null && path.vectorPath.Count > 1)
                {
                    int id = currentWaypoint + 3;
                    if(id>=path.vectorPath.Count)
                    {
                        id = path.vectorPath.Count - 1;
                    }
                    if (firstNodePositionOnServer != path.vectorPath[id])
                        firstNodePositionOnServer = path.vectorPath[id];
                }
                else
                {
                    if (firstNodePositionOnServer != new Vector3(0, 0, 0))
                        firstNodePositionOnServer = new Vector3(0, 0, 0);
                }
                
            }
            else
            {
                if (!dirty)
                    return;
                if (networkCube == null)
                {
                    return;
                }
                directionToNetworkCube = networkCube.transform.position - transform.position;
                if (directionToNetworkCube.sqrMagnitude > sqrteleportationDistance)
                {
                    if (teleportationNeedDetectionTime == 0)
                    {
                        teleportationNeedDetectionTime = Time.time;
                    }
                    if (Time.time - teleportationNeedDetectionTime > teleportationNeedTimeLimit)
                    {
                        transform.position = networkCube.transform.position;
                    }
                }
                else
                {
                    teleportationNeedDetectionTime = 0;
                }

                if (Time.time - clientDirection.time < 1 * networkSpeedModificator)
                {
                    if(GetComponent<PersonObject>().personType==PersonTypeDescriptor.typesOfPerson.Prophet)
                        visualizationModel = CGC.i.PrefabsManager.onMapObjectDescriptors.personDescriptors.ManFighter.model;
                    setDestination(clientDirection.direction);
                }
                else
                {
                    float directionAndCubeAdjustment;

                    directionToServerNode = firstNodePositionOnServer - transform.position;
                    directionToClientNode = new Vector3(float.NaN, float.NaN, float.NaN);

                    if(path!=null && path.vectorPath.Count>1)
                        directionToClientNode = path.vectorPath[1] - transform.position;
                    else
                        directionToClientNode = new Vector3(0, 0, 0);
                    directionAndCubeAdjustment = Vector3.Dot(directionToServerNode.normalized, directionToNetworkCube.normalized);

                    speedNetworkAddjustment = Mathf.Clamp(directionAndCubeAdjustment * directionToNetworkCube.sqrMagnitude / sqrErrorMarginMax / networkSpeedModificator, -speedNetworkAddjustmentRange, speedNetworkAddjustmentRange);
                    if (directionToNetworkCube.sqrMagnitude < sqrErrorMargin * Mathf.Abs(networkSpeedModificator) || directionAndCubeAdjustment < 0 && directionToNetworkCube.sqrMagnitude <Mathf.Abs( sqrErrorMargin * networkSpeedModificator) * 25)
                    {
                        if (GetComponent<PersonObject>().personType == PersonTypeDescriptor.typesOfPerson.Prophet)
                                   visualizationModel = CGC.i.PrefabsManager.onMapObjectDescriptors.personDescriptors.ManPrayer.model;
                        setDestination(serverDirection.direction);
                        
                    }
                    else
                    {
                        if (GetComponent<PersonObject>().personType == PersonTypeDescriptor.typesOfPerson.Prophet)
                                    visualizationModel = CGC.i.PrefabsManager.onMapObjectDescriptors.personDescriptors.ManBlank.model;
                        setDestination(networkCube.transform.position);

                    }
                }
                dirty = false;
            }
            if (!stoped)
            {
                pathSpeed = speed();
            }
        }

        private void Awake()
        {
            visualizationModel = CGC.i.PrefabsManager.onMapObjectDescriptors.personDescriptors.ManBlank.model;
            pObj = GetComponent<PersonObject>();
            seeker = GetComponent<Seeker>();
            controller = GetComponent<CharacterController>();
            rvoController = GetComponent<RVOController>();
            interpolator = new PathInterpolator();
            tr = transform;
            serverDirection.direction = transform.position;
            clientDirection.direction = transform.position;

            RaycastHit hit;
            this.transform.rotation = GetComponent<PersonObject>().startingRotation;
        }
        private void Start()
        {
            seeker = GetComponent<Seeker>();
            setDestination(transform.position);

            //List<Vector3> pathList = new List<Vector3>();
            //pathList.Add(transform.position);
            //pathList.Add(transform.position);
            //interpolator.SetPath(pathList);

            controller = GetComponent<CharacterController>();
            pathSpeed = GetComponent<PersonObject>().personStats.maxSpeed;
            if (isServer)
            {
                StartCoroutine(reTarget());
            }
            else
            {
                //       StartCoroutine(reTargetClient());
            }
        }

        private void OnEnable()
        {
            seeker.pathCallback += OnPathComplete;
            Init();
        }
        void Init()
        {
            if (startHasRun)
            {
                lastRepath = float.NegativeInfinity;
                StartCoroutine(RepeatTrySearchPath());
            }
        }
        public float agentSpeed
        {
            get
            {
                return pathSpeed;
            }
        }

        public void stopTarget()
        {
            //   Debug.Log("Stop target");
            //   agent.Stop();
        }

        internal Vector3 agentVelocity
        {
            get
            {
                return new Vector3(1, 1, 0);
            }
        }

        public void newDirection(Vector3 direction, bool overrideClient = false)
        {
            if ((direction - lastDirection).sqrMagnitude < 1f)
                return;

            dirty = true;
            lastDirection = direction;
            targetPos = direction;
            direction.y = transform.position.y; // everybody do the flop no more!
            if (direction.magnitude < 1f)
            {
                return;
            }
            this.direction = direction;
            if (isClient && overrideClient)
            {
                clientDirection.direction = direction;
                clientDirection.time = Time.time;
            }
            if (isServer)
            {
                serverDirection.direction = direction;
                serverDirection.time = Time.time;
                RpcsetServerDirection(direction, Time.time);
            }
        }

        [ClientRpc]
        private void RpcsetServerDirection(Vector3 direction, float time)
        {
            dirty = true;
            serverDirection.direction = direction;
            serverDirection.time = time;
        }
        GameObject visualizationModel;
        private void setDestination(Vector3 destination)
        {
            if (destination.x == float.NaN || float.IsInfinity(destination.x) ||
                destination.y == float.NaN || float.IsInfinity(destination.y) ||
                destination.z == float.NaN || float.IsInfinity(destination.z) )
                return;
            if ((destination - lastDestination).sqrMagnitude < 4)
            {
                return;
            }
            lastDestination = destination;
            //if (GetComponent<PersonObject>().personType == PersonTypeDescriptor.typesOfPerson.Prophet)
            //          Instantiate(visualizationModel,destination,Quaternion.identity);
                if (!pObj.isDead())
            {

                if (seeker.isActiveAndEnabled)
                {
                    currentWaypoint = 1;
                    path = seeker.StartPath(this.transform.position, destination);
                    Debug.DrawRay(transform.position, destination);
                    if (path.vectorPath.Count == 1)
                        path.vectorPath.Add(path.vectorPath[0]);
                }
            }
        }

        public Vector3[] getPointsOfPath ()
        {
            if (currentWaypoint < path.vectorPath.Count - 1)
                return path.vectorPath.GetRange(currentWaypoint, path.vectorPath.Count - currentWaypoint).ToArray();
            else
                return null;
        }
    }
}

I will appreciate any help!

Hi

Try attaching the FunnelModifier component to the same GameObject that has the Seeker component.
See also: https://arongranberg.com/astar/docs/class_pathfinding_1_1_funnel_modifier.php

1 Like

Thanks a lot! The movement is smooth and not choppy like before! Thanks!