Object moves smoothly in two directions ?

Hi.
I want to move object from one point to another smoothly in two directions. Before i used time and it give me good movement from part 1 to 2 to 3 but I couldn’t invert it from part 3 to 2 to 1. Is there any idea how to do it ?
Here is my script:

public Transform target;
public float dis, zz;

// Update is called once per frame
void Update()
{
    dis = transform.position.y - target.transform.position.y;
    transform.localPosition = new Vector3(transform.localPosition.x, transform.localPosition.y, zz);
        // part 1
    if (dis < 0.0f && dis > -0.3f)
    {
            zz = -0.3f;
     }
        // part 2
    if (dis < 0.31f && dis > -0.6f)
    {
            zz = -0.6f;
     }
        // part 3
    if (dis < 0.61f && dis > -0.9f)
    {
             zz = -0.9f;
      
    }

There are a couple of points from your script.

Line 8 is using zz but its value is not being set until later down the code. Typically, you would want to calculate a value and then use it immediately. Otherwise, each frame you will be using the value from the previous frame.

Also, zz is being set an absolute value. You do not seem to be adding it to anything so I’m not sure how you are getting movement from that code. Maybe you are moving the parent object as well?

Typically, if you want to move something smoothly between points over time, you would consider using Vector3.Lerp. You would Lerp between some start point and your target end point. You would need to switch round your target end point each time the Lerp reaches 1 to get that ‘patrolling between 2 points’ effect.

It looks like you are trying to calculate the speed as a function of the distance from the target. In that case, play around with the Lerp parameters to get the effect you like. Maybe try Lerp(transform.position, targetPosition, 0.1f).

I tried Lerp before and failed because its a child object. I used time method. It’s strange method and difficult to read, but worked except one thing that need to fix. Look at this script:

public Transform target;
public float dis, zz;

void Start()
{
    zz = -0.1F;
}

void Update()
{

    dis = transform.position.y - target.transform.position.y;
    transform.localPosition = new Vector3(transform.localPosition.x, transform.localPosition.y, zz);


    if (dis < 0.0f && dis > -3.3f)
    {

        if (zz > -0.3)
        {
            zz -= Time.deltaTime * 1;
            if (zz <= -0.1f)
            {
                zz = -0.1f;
                print("back 1");
            }
        }

        if (zz < -0.3f)
        {
            print("forward 1");
            zz += Time.deltaTime * 1;

        }

    }

    if (dis < -3.31f && dis > -6.3f)
    {

        if (zz > -0.6)
        {
            zz -= Time.deltaTime * 1;
            if (zz <= -0.5f)
            {
                zz = -0.5f;
                print("back 2");
            }
        }

        if (zz < -0.61f)
        {
            print("forward 2");
            zz += Time.deltaTime * 1;

        }

    }
}

when zz value is 0.5f and get back to 0.1f it moves not smoothly. especially part “forward 1”. I stopped here and I hope some one here tell me what to do.

Being a child object will not affect the Lerp function in any way.

It seems you are wanting something like an object ‘patrolling’ between two points. But that code is difficult to follow.

This should achieve something close to what you are looking for :

public class CMoveBetween : MonoBehaviour
{
    void Update()
    {
        transform.position = Vector3.Lerp( transform.position, vTarget, 0.1f );

        if( Vector3.SqrMagnitude( transform.position - vTarget ) < kfTurnPoint )
        {
            bTargetB = !bTargetB;
            vTarget = bTargetB ? vPosB : vPosA;
        }
    }

#pragma warning disable 649
    [SerializeField]
    Vector3 vPosA, vPosB;  // Patrol between these two points.
#pragma warning restore 649

    const float kfTurnPoint = 0.05f;
    Vector3 vTarget;
    bool bTargetB = true;
}

Or, you could try the code in the top answer in this thread. That uses a sinusoidal pattern and uses even fewer code lines.

1 Like

Thank you DOUG_B for your points and details.
Will lerp do the same thing if i have 8 points ?
Also, If i make animation for child object, will that work the same if parent rotate and moves around ?

Not directly- Lerp only takes 2 reference points.

However, it wouldn’t be too difficult to make that change. In the code I gave, you would need to add more ‘waypoints’ (I would suggest an array or a List). Then when the object is within the turning point, rather than just swapping target between vPosA / vPosB, you would need to make the current position be first pos in Lerp and the next pos in the array/List being the next (taking care to handle the end of the list) - e.g.

if( Vector3.SqrMagnitude( transform.position - vTarget ) < kfTurnPoint )
{
    vPosA = transform.position;
    vTarget = <<next waypoint - taking care of end-of-list>>;
}

That is quite a wordy explanation but hopefully the intention comes across? :slight_smile:

Moving the parent will affect all (sub)children. Moving children will not affect the parental hierarchy.

1 Like

That’s good.
Thank you man.

1 Like