transform position * speed

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

1. baazul

Joined:
Jul 29, 2018
Posts:
38
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

Joined:
Oct 23, 2006
Posts:
6,528
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

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

4. Griz

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

Joined:
Nov 21, 2010
Posts:
1,166
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

Joined:
Jul 29, 2018
Posts:
38
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

Joined:
Oct 23, 2006
Posts:
6,528
You need to call it each frame.

baazul likes this.
8. baazul

Joined:
Jul 29, 2018
Posts:
38
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

Joined:
Jul 29, 2018
Posts:
38
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

Joined:
Oct 23, 2006
Posts:
6,528
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

Joined:
Jul 29, 2018
Posts:
38
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

Joined:
Oct 23, 2006
Posts:
6,528
Sorry, my mistake. remove the ".x" from that line.

baazul likes this.
13. baazul

Joined:
Jul 29, 2018
Posts:
38
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

Joined:
Oct 23, 2006
Posts:
6,528
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

Joined:
Jul 29, 2018
Posts:
38
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

Joined:
Oct 23, 2006
Posts:
6,528
I assume the parent object is scaled. In local coordinates, the scale makes a difference.

baazul likes this.
17. baazul

Joined:
Jul 29, 2018
Posts:
38
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

Joined:
Oct 23, 2006
Posts:
6,528
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

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