Search Unity

transform position * speed

Discussion in 'Scripting' started by baazul, Sep 13, 2019.

  1. baazul

    baazul

    Joined:
    Jul 29, 2018
    Posts:
    42
    Hello,

    I have a GameObject that I would like to move on the X Axis.

    For exemple,

    I want it to move once (and not teleport but move rather slowly) to X -300
    Then move back to X -700

    Currently I am using this:

    Code (CSharp):
    1. transform.position += Vector3.right * speed * Time.deltaTime;
    then

    Code (CSharp):
    1. transform.position += Vector3.left* (speed/2) * Time.deltaTime;
    But the position it moves to is always slightly different while I want it to be precise.

    Or maybe I can add another game object of 1 pixel at the place I want it stop and move my first game object until it collide ?

    Thank you
     
    Last edited: Sep 13, 2019
  2. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,775
    You could use
    Code (csharp):
    1. transform.position = Vector3.MoveToward(transform.position, new Vector3(-300f, 0f, 0f), speed * Time.deltaTime);
     
    baazul likes this.
  3. baazul

    baazul

    Joined:
    Jul 29, 2018
    Posts:
    42
    it says 'Vector3' does not contain a definition for 'MoveToward". I am looking for information on google to have it work
     
  4. Grizmu

    Grizmu

    Joined:
    Aug 27, 2013
    Posts:
    131
    baazul likes this.
  5. exiguous

    exiguous

    Joined:
    Nov 21, 2010
    Posts:
    1,749
    When the object shall fly back and forth between two points Vector3.Lerp should do the job. https://docs.unity3d.com/ScriptReference/Vector3.Lerp.html
    Just calculate how long it shall take and change the t parameter accordingly between 0 and 1. So when it starts at point A have it 0 and then increase it each update until it reaches 1 when it shall arrive there. Then decrease it to go back to the start.
     
    baazul likes this.
  6. baazul

    baazul

    Joined:
    Jul 29, 2018
    Posts:
    42
    I'll have a look at your suggestion exiguous thank you.

    So now it is working, here my function:

    Code (CSharp):
    1.     public void TransformPlayerPositionIn()
    2.     {
    3.         transform.position = Vector3.MoveTowards(transform.position, new Vector3(-300f, 165f, 0f), speed * Time.deltaTime);
    4.     }
    However the GameObject only move slightly then stop after a fraction of a second it does not reach it's goal. Am I supposed to add something else for it to keep going to the right direction or maybe something else in my code is stopping it ?
     
    Last edited: Sep 13, 2019
  7. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,775
    You need to call it each frame.
     
    baazul likes this.
  8. baazul

    baazul

    Joined:
    Jul 29, 2018
    Posts:
    42
    Also, if I put it in void update, it keeps going but it moves to the top left instead of moving only on the X axis only ^^

    It's starting position is:

    Anchors "middle center" Pos X -700, Pos Y 165, Pos Z 0

    And I am using this currently:

    Code (CSharp):
    1. transform.position = Vector3.MoveTowards(transform.position, new Vector3(-300f, 165f, 0f), speed * Time.deltaTime);
     
  9. baazul

    baazul

    Joined:
    Jul 29, 2018
    Posts:
    42
    When I call it only 1 frame, the end position is:

    Pos X -727.1769
    Pos Y 180.0452
    Pos Z -18.2428

    While it would make sense to me to be something like:

    Pos X -673.1769
    Pos Y 165
    Pos Z 0

    What am I missing ?
     
  10. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,775
    If you explicitly only want to move it in one dimension, there's a version of MoveTowards for floats:
    Code (csharp):
    1. Vector3 pos = transform.position;
    2. pos.x = Mathf.MoveTowards(pos.x, -300f, speed * Time.deltaTime);
    3. transform.position = pos.x;
     
    baazul likes this.
  11. baazul

    baazul

    Joined:
    Jul 29, 2018
    Posts:
    42
    Thank you,

    Now I have this inside the void update for testing purpose:

    Code (CSharp):
    1.     void Update()
    2.     {
    3.         Vector3 pos = transform.position;
    4.         pos.x = Mathf.MoveTowards(pos.x, -300f, speed * Time.deltaTime);
    5.         transform.position = pos.x;
    6.     }
    and on the last "pos.x" it says: cannot implicitly convert type 'float' to 'UnityEngine.Vector3'
     
  12. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,775
    Sorry, my mistake. remove the ".x" from that line.
     
    baazul likes this.
  13. baazul

    baazul

    Joined:
    Jul 29, 2018
    Posts:
    42
    Thank you, so now it is indeed moving on only the X axis. However, it is moving to the wrong direction. It is still in my void update and It goes from:

    Pos X -700

    to

    Pos X -31243.53
     
  14. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,775
    Where are you getting that number?
    If it's in the inspector (and -300 is the number you want as seen in the inspector), that's transform.localPosition, instead of transform.position.
     
    baazul likes this.
  15. baazul

    baazul

    Joined:
    Jul 29, 2018
    Posts:
    42
    yes it was within the inspector and now it works! Thank you :)

    One last thing, I did not change the speed but it's moving way slower since I am using transform.localPosition. Any idea why ?
     
  16. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,775
    I assume the parent object is scaled. In local coordinates, the scale makes a difference.
     
    baazul likes this.
  17. baazul

    baazul

    Joined:
    Jul 29, 2018
    Posts:
    42
    Yes it is, seems a bit weird to me by the way. The parent object is the Canvas and it is scaled to 0.00925925. Should I worry about it ?

    And another thing if I may.

    I did not find a way to call something every frame outside of the void update. My last attempt was something like this within an IEnumerator

    transform.position += Vector3.right * speed * Time.deltaTime;
    yield return new WaitForSeconds(0.01f);
    transform.position += Vector3.right * speed * Time.deltaTime;
    yield return new WaitForSeconds(0.01f);
    transform.position += Vector3.right * speed * Time.deltaTime;
    yield return new WaitForSeconds(0.01f);
    transform.position += Vector3.right * speed * Time.deltaTime;
    yield return new WaitForSeconds(0.01f);
    transform.position += Vector3.right * speed * Time.deltaTime;
    yield return new WaitForSeconds(0.01f);

    It works but... Is this a good practice or...?
     
  18. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,775
    Yeah, that's a bad practice. besides being inconvenient to code, it will move an inconsistent distance. (If the fps is higher, Time.deltaTime will be smaller, but you're running it a fixed number of times. If using Time.deltaTime, it should be something that's happening every frame.) So two things you need to learn:
    1) loops;
    2) "yield return null" yields for one frame
    So combine these:
    Code (csharp):
    1. Vector3 pos = transform.localPosition;
    2. while (pos.x != -300f) {
    3. pos.x = Matf.MoveTowards(pos.x, -300f, speed * Time.deltaTime);
    4. transform.localPosition = pos;
    5. yield return null;
    6. }
    (Sidenote: Normally, using == or != to compare two floats is a bad idea; this is a specific situation where it's not a problem)
     
    baazul likes this.
  19. baazul

    baazul

    Joined:
    Jul 29, 2018
    Posts:
    42
    works perfectly now and it will help me to improve other part of my code, thank you