Search Unity

[SOLVED] Moving object to point -- Object moves slower when point is close than farther away

Discussion in 'Scripting' started by Deleted User, Sep 22, 2014.

  1. Deleted User

    Deleted User

    Guest

    I want to move an object to a point at a constant speed but when the point is close to the object, it will move much slower than when it is far awar. As well, it seems to slow down a bit when it comes closer to the point.
    This is my script: (Only line 36-56 are of importance).

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4.  
    5. public class Fly : MonoBehaviour
    6. {
    7.         public float speed;
    8.         public float touchMaxDeviation;
    9.         public float touchMaxDuration;
    10.    
    11.         private Vector3[] startPosition = new Vector3[10];
    12.         private Vector3 v3;
    13.         private bool[] hasDeviated = new bool[10];
    14.         private float[] touchDuration = new float[10];
    15.         private Vector3 start;
    16.         private bool move;
    17.         private Vector3 end;
    18.         void Update ()
    19.         {
    20.                 //        transform.position += speed * Vector3.right * Time.deltaTime;
    21.                 if (Input.touchCount > 0) {
    22.                         for (int i = 0; i < Input.touchCount; i++) {
    23.                                 Touch touch = Input.GetTouch (i);
    24.                                 touchDuration [touch.fingerId] += touch.deltaTime;
    25.                
    26.                                 if (touch.phase == TouchPhase.Began) {
    27.                                         startPosition [touch.fingerId] = touch.position;
    28.                                 }
    29.                
    30.                                 if (touch.phase == TouchPhase.Moved) {
    31.                                         if (Vector2.Distance (startPosition [touch.fingerId], touch.position) > touchMaxDeviation) {
    32.                                                 hasDeviated [touch.fingerId] = true;
    33.                                         }
    34.                                 }
    35.                
    36.                                 if (touch.phase == TouchPhase.Ended) {
    37.                                         if (hasDeviated [touch.fingerId] == false && touchDuration [touch.fingerId] <= touchMaxDuration) {
    38.                                                 v3 = Camera.main.ScreenToWorldPoint (startPosition [touch.fingerId]);
    39.                                                 end = v3;
    40.                                                 start = transform.position;
    41.                                                 v3.Normalize ();
    42.                                                 //            Vector2.MoveTowards (transform.position, startPosition [touch.fingerId], speed);
    43.                                                 Debug.Log ("Move");
    44.                                                 move = true;
    45.                                         }
    46.                                         hasDeviated [touch.fingerId] = false;
    47.                                         touchDuration [touch.fingerId] = 0;
    48.                                 }
    49.                
    50.                                 if (touch.phase == TouchPhase.Canceled) {
    51.                                         hasDeviated [touch.fingerId] = false;
    52.                                         touchDuration [touch.fingerId] = 0;
    53.                                 }
    54.                         }
    55.                 }
    56.                 Debug.Log (transform.position);
    57.                 transform.position += (start - end).normalized * speed * Time.deltaTime;
    58.                 transform.position = new Vector3 (transform.position.x, transform.position.y, 0);
    59.                
    60.         }
    61. }
     
  2. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    Hah, when I read your title and description I was sure you were committing the common abuse of Lerp. But no, that's not the problem in this case.

    So let's see, the key bit of your code is this line:
    Code (CSharp):
    1. transform.position += (start - end).normalized * speed * Time.deltaTime;
    This basically points a vector in the direction of travel, with length of speed * the frame time, and steps that much. This could obviously overstep your goal — you really should be using Vector3.MoveTowards here instead — but it's not obvious to me why the speed would not be constant. You are normalizing the start-end vector, so it shouldn't matter how far apart these are.

    Er, there is another funny thing here though... why are you using start-end instead of end-start? Seems to me that you're actually moving directly away from the end point every step, rather than towards it, unless speed is negative. Does anything change speed while the code is running?
     
  3. A.Killingbeck

    A.Killingbeck

    Joined:
    Feb 21, 2014
    Posts:
    483
    Use brackets?
     
  4. ThermalFusion

    ThermalFusion

    Joined:
    May 1, 2011
    Posts:
    906
    I see you're only moving in x and y.
    If the start and end positions don't also only move in x and y, you will get this same result as your speed will be aimed more along the z axis, causing speed in x y to slow when you get closer.
    Your direction is normalized in 3D, but you then negate the effect by snapping to 2D after moving. You will have to normalize direction in 2D too.

    Code (csharp):
    1. Debug.Log (transform.position);
    2. start.z = 0f;
    3. end.z = 0f;
    4. transform.position += (start - end).normalized * speed * Time.deltaTime;
    5. transform.position = new Vector3 (transform.position.x, transform.position.y, 0);
    Edit: just wrestle with copy paste...
    Edit2: If only explaining properly was easy...
     
    Last edited: Sep 22, 2014
  5. ThermalFusion

    ThermalFusion

    Joined:
    May 1, 2011
    Posts:
    906
    OK, for my own sense of satisfaction, lets try and explain that properly. Here's what happens step by step:
    You calculate your movement direction in 3D and you normalize this vector.
    Then you move in 3D using this direction and a speed.
    You then reset the Z position of the object to keep it at a specific Z depth. You probably do this because it's a 2D game and you want your moving object to stay at the same Z depth.
    However, if your start and end positions don't lie on the same Z depth you will introduce 3D movement which is then negated by resetting the Z depth. This causes a motion loss in 2D since the Z movement is just removed.
    If you make sure your direction vector is flat on the plane you want to move on before you normalize it, you will remove this effect.
     
  6. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    Yeah, that could be it! I was assuming that the start and end positions were in the Z plane, but they might not be... in which case, it would fail as @ThermalFusion described.
     
  7. Deleted User

    Deleted User

    Guest

    Yep, thanks ThermalFusion. That was the problem all along.