zinie
zinie

Reputation: 11

How can I move a character from one point to a specific point at any desired speed?

I used from this code but it does not do it:

public Transform[] points;
public float speed;

private void OnTriggerEnter2D(Collider2D other)
{
    if (other.tag == "door1") 
    {       
        transform.position = Vector3.Lerp(transform.position, points[1].position, speed * Time.deltaTime);
    }
}

That is, I want the pig to go to a higher point on the ground at a desired speed when it hits the trigger (see the photo attached to see it)

How can I move a character from one point to a specific point at any desired speed?

Upvotes: 0

Views: 312

Answers (2)

derHugo
derHugo

Reputation: 90669

Two problems here:

  • you are calling that line exactly once when you enter the collider so the movement is applied for I single frame!
  • Lerp interpolates linear between two positions using a factor between 0 and 1. You every time use the current position as start point so what would happen if if you called this continuously is approximating the position getting slower and slower every frame which is not what you describe. You want to move with a constant speed.

You most likely would rather use a Coroutine and MoveTowards for that

private void OnTriggerEnter2D(Collider2D other)
{
    // Better use CompareTag here
    if (other.CompareTag("door1"))
    {     
        // Start a routine for the continuous movement
        StartCoroutine(MoveTo(points[1].position, speed);
    }
}

private IEnumerator MoveTo(Vector3 targetPosition, float linearSpeed)
{
    // This uses an approximation of 0.00001 for equality
    while(transform.position != targetPosition)
    {
        // with a constant speed of linearSpeed Units / second
        // move towards the target position without overshooting
        transform.position = Vector3.MoveTowards(transform.position, targetPosition, linearSpeed * Time.deltaTime);

        // Tell Unity to "pause" the routine here, render this frame
        // and continue from here in the next frame
        yield return null;
    }

    // to be sure to end up with exact values set the target position fix when done
    transform.position = targetPosition;
}

Alternatively a bit more complex looking but more powerful would be to rather calculate the required time depending on the speed but still adding some smoothing like e.g.

private void OnTriggerEnter2D(Collider2D other)
{
    if (other.CompareTag("door1"))
    {     
        StartCoroutine (MoveTo(points[1].position, speed);
    }
}

private IEnumerator MoveTo(Vector3 targetPosition, float averageSpeed)
{ 
    // store the initial position
    var from = transform.position;
    // Get the expected duration depending on distance and speed
    var duration = Vector3.Distance(from, targetPosition) / averageSpeed;

    // This is increased over time
    var timePassed = 0;
    while(timePassed < duration)
    {
        // This linear grows from 0 to 1
        var factor = timePassed / duration;
        // Adds some ease-in and ease-out at beginning and end of the movement
        factor = Mathf.SmoothStep(0, 1, factor);

        // linear interpolate on the smoothed factor 
        transform.position = Vector3.Lerp(from, targetPosition, factor);

        // increase by time passed since last frame
        timePassed += Time.deltaTime;

        // Tell Unity to "pause" the routine here, render this frame
        // and continue from here in the next frame
        yield return null;
    }

    // to be sure to end up with exact values set the target position fix when done
    transform.position = targetPosition;
}

Upvotes: 1

JonasMH
JonasMH

Reputation: 1183

OnTriggerEnter2D is only called once on every collider enter. Given you are only moving it by speed * Time.deltaTime with Time.deltaTime being in the order of 0.008 - 0.100 it may only move slightly.

Depending on what you want, are you sure you don't want to completely move the object or alternatively set a flag that starts moving it in the update() method?

Upvotes: 0

Related Questions