0
\$\begingroup\$

I have three laptops in my scene and I am trying to bring them to front when I click on them. I am able to recognize which laptop is clicked by using the code below, but it doesn't move to the focus position in a single click: it moves only one frame so I have to keep clicking it.

void Update () {
        if (Input.GetMouseButtonDown (0)) {
            RaycastHit hit;
            Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);

            if (Physics.Raycast (ray, out hit)) {
                if (hit.transform.name == "Laptop 1") {

                    Debug.Log("Laptop 1 is clicked");
                    Laptop1Trans.position = Vector3.MoveTowards (Laptop1Trans.position, FocusPointTrans.position, moveSpeed);

                } else if (hit.transform.name == "Laptop 2") {
                    Debug.Log("Laptop 2 is clicked");
                } else if (hit.transform.name == "Laptop 3") {
                    Debug.Log("Laptop 3 is clicked");
                } else {
                }
            }
        }
    }

I tried moving the move part to a method but still same behaviour.

Are there any workaround?

\$\endgroup\$
1
\$\begingroup\$

It looks like you're trying to use MoveTowards in a fire-and-forget manner, like a tweening library: "Hey you, move over there gradually over the next several frames, without further supervision"

MoveTowards doesn't do that (It couldn't if it wanted to — it doesn't even know what object to move, all it has is some vectors). It's just a way to calculate one position: the place the object should be this frame after taking one step toward the destination.

To keep updating its position, you need a method that runs every frame until it reaches its destination, not just the frame you clicked. A Coroutine can do this quite well:

IEnumerator MoveTo(Transform mover, Vector3 destination, float speed) {
    // This looks unsafe, but Unity uses
    // en epsilon when comparing vectors.
    while(mover.position != destination) {
         mover.position = Vector3.MoveTowards(
             mover.position,
             destination,
             speed * Time.deltaTime);
         // Wait a frame and move again.
         yield return null;
    }
}

You can start this motion with:

StartCoroutine(MoveTo(clickedLaptop, FocusPointTrans.position, moveSpeed); 
\$\endgroup\$
1
  • \$\begingroup\$ thanks i didn't know that about MoveTowards. \$\endgroup\$ Apr 12 '18 at 9:29
0
\$\begingroup\$

Use Input.GetMouseButton instead. GetMouseButtonDown only returns true on one frame when the button was pressed down, while GetMouseButton returns true while the button is held down.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.