- Home /
How to move an object along x-axis between two points?
I am trying to move an enemy character in a 2d game along the x-axis between the positions (-4,0) and (4,0). Currently, the object moves to right side indefinitely not returning to (-4,0) as intended.
Following is the script I have tried to write (no error message appears in unity):
void Update () {
transform.Translate (Vector2.right * 0.1f);
if(transform.position.x == 4)
{
transform.Translate (-Vector2.right * 0.1f);
}
if(transform.position.x == -4)
{
transform.Translate (Vector2.right * 0.1f);
}
}
}
This is my first experience with programming so any help will be appreciated a lot. Thanks!
Answer by robertbu · Apr 20, 2014 at 11:25 PM
As for the code at the link, any code by @Eric5h5 is worth looking at and learning from. And I applaud you going out and finding a solution for yourself. But before you 'abandon' this question, you might puzzle out why your code did not work. There are several significant problems.
Never compare floating point numbers with '=='. Floating point numbers are imprecise, so your adding 0.1f over multiple frames might yield a value of 4.00000000000001...and this value would fail the comparison. When you can, use inequality. For example here, you could use '>='. Sometimes you need something more exact. Mathf.Approximately() can be helpful.
Your logic does not allow the object to reverse. That is, if line 3 were true, you would back up for a single frame, but then line 10 would be true, so you would head forward, which would make line line 3 true...and so on.
While it is not the reason for your failure, when moving something through the Transform, you want to use 'Time.deltaTime'. Not every frame take the same amount of time, so using a fixed value will make your code run at different speeds on different devices, plus it may jitter as the frame rate changes.
So here is a quick rewrite of your code:
using UnityEngine;
using System.Collections;
public class Example1 : MonoBehaviour {
private bool dirRight = true;
public float speed = 2.0f;
void Update () {
if (dirRight)
transform.Translate (Vector2.right * speed * Time.deltaTime);
else
transform.Translate (-Vector2.right * speed * Time.deltaTime);
if(transform.position.x >= 4.0f) {
dirRight = false;
}
if(transform.position.x <= -4) {
dirRight = true;
}
}
}
In Unity there is often many want to accomplish the same task. Here is another method of moving the block back and forth between two positions. It used Mathf.PingPong().
public class Example2 : MonoBehaviour {
private Vector3 pos1 = new Vector3(-4,0,0);
private Vector3 pos2 = new Vector3(4,0,0);
public float speed = 1.0f;
void Update() {
transform.position = Vector3.Lerp (pos1, pos2, Mathf.PingPong(Time.time*speed, 1.0f));
}
}
And yet one more solution using Mathf.Sin(). This version will feel more natural...more line a pendulum swinging between two positions. It is the same as the previous example except with one line changed:
public class Example3 : MonoBehaviour {
private Vector3 pos1 = new Vector3(-4,0,0);
private Vector3 pos2 = new Vector3(4,0,0);
public float speed = 1.0f;
void Update() {
transform.position = Vector3.Lerp (pos1, pos2, (Mathf.Sin(speed * Time.time) + 1.0f) / 2.0f);
}
}
Wow! Thanks for your very informative response Robert! It definitely helps a lot!
Nice answer, however most of the time you want relative movement, not to absolute positions. The way I do it is place the object at the first point to oscillate, then have a "posDiff" position difference variable.
public class Anim : $$anonymous$$onoBehaviour {
private Vector3 pos1;
private Vector3 pos2;
public Vector3 posDiff= new Vector3 (0f, 0f, 20f);
public float speed = 1.0f;
void Start() {
pos1 = transform.position;
pos2 = transform.position + posDiff;
}
void Update () {
transform.position = Vector3.Lerp(pos1, pos2, $$anonymous$$athf.PingPong(Time.time*speed, 1.0f));
transform.Rotate(Vector3.up * 10f * Time.deltaTime);
}
}
That's awesome @robertbu! Thanks for taking the time to post such a good explanation.
Answer by Blcktfn · Jan 12, 2015 at 01:48 PM
Hey there,
I use following code segment for move an object from a to b
The GameObject move left and right.
public float t=1f; // speed
public float l= 10f; // length from 0 to endpoint.
public float posX = 1f; // Offset
void Update() {
Vector3 pos = new Vector3 ( posX+Mathf.PingPong (t * Time.time, l),0, 0);
transform.position = pos;
}
Answer by Ammar-Ali · Apr 20, 2014 at 11:11 PM
Edit: I used a coroutine script from another community answer so that solved the problem.
http://answers.unity3d.com/questions/14279/make-an-object-move-from-point-a-to-point-b-then-b.html
Answer by zaai · Oct 26, 2017 at 05:55 PM
public Transform pointA;
public Transform pointB;
public bool isRight = true;
public float speed = 0.3f;
private Vector3 pointAPosition;
private Vector3 pointBPosition;
// Use this for initialization
void Start ()
{
pointAPosition = new Vector3 (pointA.position.x, 0, 0);
pointBPosition = new Vector3 (pointB.position.x, 0, 0);
}
// Update is called once per frame
void Update ()
{
Vector3 thisPosition = new Vector3 (transform.position.x, 0, 0);
if (isRight) {
transform.position = Vector3.MoveTowards (transform.position, pointB.position, speed);
if (thisPosition.Equals (pointBPosition)) {
//Debug.Log ("Position b");
isRight = false;
}
} else {
transform.position = Vector3.MoveTowards (transform.position, pointA.position, speed);
if (thisPosition.Equals (pointAPosition)) {
//Debug.Log ("Position a");
isRight = true;
}
}
}
I just added this in update . This did the trick.
Vector2 start = transform.position;
start.x = 2 * $$anonymous$$athf.Sin(Time.time); //
transform.position = start;
Answer by alihaider786786 · Mar 11, 2019 at 02:30 PM
try these two lines. its helping me to refuse a dog (gameobject) to eat. its moving both positive and negative Z.
iTween.RotateTo (face.gameObject, iTween.Hash ("z", -10f, "time", 0.5f)); iTween.RotateTo (face.gameObject, iTween.Hash ("z", 10f, "time", 0.5f,"easetype",iTween.EaseType.linear,"looptype",iTween.LoopType.pingPong));