Home > Blockchain >  Object.Position always goes to origin
Object.Position always goes to origin

Time:03-17

new to Unity here! I'm trying to move using vector3.MoveTowards(), but my object position always goes towards origin even if I placed it elsewhere. Before Play Position Before Play, after Play Position After Play.

Here's my code

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Vector : MonoBehaviour
{
    public Transform obj;
    [SerializeField] Vector3 a;
    [SerializeField] Vector3 b;
    [SerializeField] Vector3 c;
    public float speed;
    private RaycastHit hit;
    Vector3 previousPosition;
    Vector3 targetPosition;
    float lerpMoving;

    // Start is called before the first frame update
    void Start()
    {
        // speed = 100.0f;
        // hit = new RaycastHit(); 
    }

    // Update is called once per frame
    void Update()
    {
        previousPosition = transform.position;
        // transform.position = obj.position;

        if (Input.GetKeyDown(KeyCode.Mouse0)) 
        {
            if (Input.GetMouseButtonDown(0)) 
            {
                Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);          
                if (Physics.Raycast(ray, out hit)) 
                {
                    LayerMask layerHit = hit.transform.gameObject.layer;

                    switch (layerHit.value)
                    {
                        case 8:
                            break;
                        case 9:
                            break;
                        default:
                            targetPosition = hit.point;
                            lerpMoving = 0;  
                            break;
                    }   
                }
            }
        }
        if(lerpMoving < 1)
        {
        movePlayer();   
        }

        void movePlayer()
        {
            lerpMoving  = Time.deltaTime; 
            transform.position = Vector3.MoveTowards(previousPosition, targetPosition, 
            speed * lerpMoving);
        }

        // if (Input.GetMouseButtonDown (0))
        // {
        //     Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);

        //     if (Physics.Raycast(ray, out hit))
        //     {
        //         transform.position = Vector3.MoveTowards(hit.point, b, speed);
        //     }

        // }


    }

}

This code is to make the object to move based on where your mouse clicks where beside layer 8 and 9 it can go anywhere

CodePudding user response:

Well you are permanently moving towards targetPosition.

But if you never clicked and your ray has never hit anything so far then targetPosition will have its default value (0,0,0).

And since the lerpMoving by default is 0 you instantly start moving.

Note: In general your MoveTowards using the increasing lerpMoving (except the effect of increasing velocity is explicitly desired) makes not much sense. See bottom of the answer.


There are multiple points and ways how to solve this.

  • I would suggest to either make it e.g.

    private float lerpMoving = 1f;
    

    so that movePlayer isn't called until explicitly set to 0.

  • or you initially set

    void Start()
    {
        ...
    
        targetPosition = transform.position;
    }
    

    so it simply "moves" to where it already is now anyway.

  • Or rather make sure you only move at all when the position is set. You could do this using a Nullable

    private Vector3? targetPosition;
    

    and later check e.g.

    void movePlayer()
    {
        if(targetPosition == null) return;
    
        // NOTE: See below
    
        if(lerpMoving >= 1f)
        {
            targetPosition = null;
        }
    }
    

    so you only move while there is a valid position.


Now I explicitly omitted the line(s) where you actually move because using an increasing lerpMoving as parameter for MoveTowards makes not much sense.

  • You either want to use Lerp instead

    transform.position = Vector3.Lerp(previousPosition, targetPosition, lerpMoving);
    

    but in that case you do NOT want to update the previousPosition all the time but rather together with setting the targetPosition in

    ...
    targetPosition = hit.point;
    previousPosition = transform.position;
    lerpMoving = 0;
    ...
    

    in order to move to the target within 1 second after the click, regardless how far or close it is

  • Or you want to move with a linear speed using simply

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

    and get entirely rid of lerpMoving and previousPosition.

  • Related