MoveTowards is off target by a small amount

Hello all.

I’m trying to use MoveTowards to get an object from A-to-B.

transform.position = Vector3.MoveTowards(transform.position, End_Pos, speed * Time.deltaTime);

In this example, start is -120,-120, destination is -120,-80. Moving a distance of +40 along Z. Then again a second time, to -120,-40. But notice the slight deviation, to ‘-80.40’/‘-40.78’.

7902832--1006897--upload_2022-2-16_17-41-53.png

The end position is being properly displayed (The -80), but during the movement, it moves just slightly less than the full 40 unit distance.

I’ve tried to do MathF to round the start position and end position, but that just made the descrepency ‘whole rounded increments’, instead of removing the problem.

I’ve also tried IF(distanceFrom < 1.0f), then stop movement routine, but this also has not worked as I expected.

Why isn’t the object stopping at ‘-80’, which is the set End_Pos which it is asked to stop at? What is the best way to work around this / account for this properly, without just rounding the values? The values is even inconsistent, in that it isn’t the same ‘0.4’ difference each time.

Edit: Code

public class ButtonMove : MonoBehaviourPunCallbacks
{

    private CharacterAnimation anim;
    private Quaternion _lookRotation;
    public bool movingToTarget = false;
    public bool canMoveHere = true;

    Vector3 Start_Pos;
    Vector3 End_Pos;

    public float speed = 0.75f;
    public float moveDist = 10f;
    public float rayRange = 7.5f;
    public float ranRoll = 2f;
    public Vector3 targetDirection;

    public float h = 0;
    public float v = 0;

    void Start()
    {
        anim = GetComponent<CharacterAnimation>();
        Start_Pos = transform.position;                                        
        End_Pos = transform.position;
        float h = 0;
        float v = 0;
        StartCoroutine(CoroutineB(h, v));
    }

    // FixedUpdate is used for physics based movement
    void Update()
    {
        if (this.photonView.IsMine)
        {
            if (Input.GetKeyDown("w"))
            {
                Start_Pos = transform.position;
                v += (ranRoll * moveDist);
                h = 0; 
                End_Pos = Start_Pos + new Vector3(h, 0f, v);
                Debug.Log("str: " + Start_Pos + " end " + End_Pos);
////This shows the correct '-120,0,-120' position
                RotatePlayer(End_Pos);

                if (canMoveHere)
                {
                    movingToTarget = true;
                    anim._animRun = true;
                }
            }

            if (movingToTarget)
            {
                StartCoroutine(CoroutineB(h, v));
            }
        }
    }


    private void FixedUpdate()
    {

        Vector3 direction = Vector3.forward;
        Ray theRay = new Ray(transform.position, transform.TransformDirection(direction * rayRange));
        Debug.DrawRay(transform.position, transform.TransformDirection(direction * rayRange)); ;

        canMoveHere = true;

        if (Physics.Raycast(theRay, out RaycastHit hit, rayRange))
        {
            if (hit.collider.tag == "Wall")
            {
                movingToTarget = false;
                anim._animRun = false;
                canMoveHere = false;

            }
        }
    }


    private void RotatePlayer(Vector3 dir)
    {
        if (this.photonView.IsMine)
        {
            transform.LookAt(End_Pos);
        }
    }

    IEnumerator CoroutineB(float hh, float vv)
    {
        if (this.photonView.IsMine)
        {
            while (movingToTarget)
            {
                float distanceFrom = Vector3.Distance(transform.position, End_Pos);

                Vector3 targetDirection = new Vector3(h, 0f, v);
                transform.position = Vector3.MoveTowards(transform.position, End_Pos, speed * Time.deltaTime);
                RotatePlayer(targetDirection);
                yield return null;
                if (distanceFrom < 1.0f)
                {
                    movingToTarget = false;
                    anim._animRun = false;
                    Debug.Log(transform.position);
////This shows the slightly off location of '-120,0,-80.55' for example

                    v = 0;
                    h = 0;
                }
            }
        }
    }
}

Show your actual code. You said you are using transform.position = Vector3.MoveTowards(transform.position, End_Pos, speed * Time.deltaTime); But when and where are you calling this? Under what condition are you stopping calling it?

Added code.

Aside from the ‘accuracy’ question I had - is there a better way to do collision detection, than the ray cast example I’ve used? Looking to stop the linear path if there is an obstacle in front of the object / in the next space in front of the object.

The reason I’m asking is I’m trying to stop at a these set locations, increments of 10 basically, -120, -110, -100, -90, -80… if there is an object at -70, stop. I don’t want to move the player forward from the ‘-80’ to the ‘-70’, I want to detect before movement that something is there, and prevent the option for movement.

Bump