Vector3.Lerp to move sliding door

I am a rookie programmer and I’m trying to make a door slide open when you press the “e” button. I cant get it to slide open, every way I’ve tried so far it just snaps and with this code it seems to disappear. What am I missing?

using UnityEngine;
using System.Collections;

public class Door8:MonoBehaviour{

Vector3startPosition;
Vector3endPosition;
floatspeed=0.5f;

voidStart(){

}
voidUpdate(){

if(Input.GetKeyDown(“e”))
{
transform.position=(Vector3.Lerp(startPosition,endPosition,speed));
}
}
}

Hi. Always remember to use code tags. Also, what behaviour are you going for? Do you want to press and hold? Do you want to press once? If you want a press and hold solution, then you might do this:

transform.position = Vector3.Lerp(startPosition, endPosition, elapsedTime);
if (Input.GetKey("e")) elapsedTime += Time.deltaTime

GetKeyDown is called once–on the first frame when the key gets pressed. If you want to press once, use a coroutine like so:

void Update () {
if (Input.GetKeyUp("e")) StartCoroutine(OpenDoor());
}

IEnumerator OpenDoor {
float elapsedTime = 0;
while (elapsedTime < totalTime) {
transform.position = Vector3.Lerp(startPosition, endPosition, elapsedTime);
elapsedTime += Time.deltaTime;
yield return null;
}
}

The third parameter of the Lerp function is not a speed, but an interpolant parameter. It is a number between 0 and 1 that defines by which ratio startPosition and endPosition are mixed to obtain an in-between position. There is nothing dynamic about the Lerp function, so you would need to animate that parameter over time yourself to get your sliding animation. This technique is often called “tweening” (in-between => in-btweening => tweening).

But I like to use DOTween for such thing, it just makes your life easier:

using UnityEngine;
using DG.Tweening;

public class Door8 : MonoBehaviour
{
    Vector3 startPosition;
    Vector3 endPosition;
    float speed=0.5f;

    void Update()
    {
        if (Input.GetKeyDown("e"))
        {
            float distance = Vector3.Distance(endPosition, startPosition);
            float duration = distance / speed;
            transform.DOMove(endPosition, duration);
        }
    }
}

Hi again @Lanre !

1 Like

A number of things.
First, your animation seems to be dependent on startPosition and endPosition. But you have made them private variables (since the code is c# and you haven’t made them public). Right now, they are probably both at 0,0,0. So that’s where your door will be jumping to.
You can either make them public and put some sensible values in them, or you can put some values into them in e.g. the Start function so there are some positions to move between. I have done so in the example below.

Secondly, you are not really moving the door each Update function. You are just testing if the “e” button was pressed, and in that single frame where that happens, you place the object midway between startPosition and endPosition. (since speed is 0.5f). Lerp only executes when you call it. It doesn’t “keep moving the door” So you need to

  • call it every Update that you want the door to change position
  • give it different values to work with each time.
    I have made a suggestion below, which moves the door at an even speed between its starting position and a point 2 meters to the right of it. Hope this illustrates it.
using UnityEngine;
using System.Collections;

public class Door8 : MonoBehaviour {

    Vector3 startPosition;
    Vector3 endPosition;

    public float moveDistance = 2f; // The distance we want to move the door

    public float speed = 0.5f; // Let's make this public too, so it is easy to change in the inspector

    void Start()
    {
        startPosition = transform.position; // startPosition is where the door is when the scene starts
        endPosition = startPosition + Vector3.right * moveDistance; // You could construct endPosition in any other way you want,
                                                                    // as long as it is different from startPosition, otherwise you wont get any movement
    }

    float open = 0; // This variable will determine how "open" our door is
    float direction = 0; // this will determine which direction the door is moving. a plus value moves towards endPosition, a minus moves towards startPosition

    void Update()
    {
        if(Input.GetKeyDown("e"))
        {
            // Pressing the key means that we want to change the direction the door is moving
            if ( direction > 0 ) // If direction is 0 or 1
                direction = -1;
            else
                direction = 1;
        }
        // Now change where the door should be with a speed dependent on how quick time passes
        // We need to do this every update, not just when the key is pressed. Otherwise the door won't keep moving
        open += direction * speed * Time.deltaTime;
        // Also make sure that open doesn't grow outside the 0 - 1 range
        open = Mathf.Clamp01( open );

        // Depending on how "open" our door is between startPosition and endPosition. Place it there. Every frame
        transform.position = Vector3.Lerp( startPosition, endPosition, open );
    }
}

It looks like a lot of code, but that is mostly because of all the comments

Oh, I have completely missed that. Well spotted @cblarsen .
@nieyoub23 I guess you also want to be able to close the door as well. If that the case you would need to keep track of the door state using a bool. The code would be:

using UnityEngine;
using DG.Tweening;

public class Door8 : MonoBehaviour
{
    public float openingRange = 1.0f;
    public float duration = 1.0f;

    Vector3 openedPosition;
    Vector3 closedPosition;

    bool isOpened = false;

    void Start()
    {
        closedPosition = this.transform.position;
        openedPosition   = this.transform.position + Vector3.right*openingRange; // Assuming your door slide to the right.
    }

    void Update()
    {
        if (Input.GetKeyDown("e"))
        {
            isOpened = !isOpened; // toggle door state
            if( isOpened )
                transform.DOMove(openedPosition, duration);
            else
                transform.DOMove(closedPosition, duration);
        }
    }
}

Edit:
I’ve just noticed that @cblarsen code handle the opening/closing behaviour as well.

I just want to say thank you all for your responses!! I learned so much