Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Vector3.Lerp to move sliding door

Discussion in 'Scripting' started by nieyoub23, May 28, 2016.

  1. nieyoub23

    nieyoub23

    Joined:
    May 8, 2016
    Posts:
    27
    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));
    }
    }
    }
     
  2. Lanre

    Lanre

    Joined:
    Dec 26, 2013
    Posts:
    3,960
    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:
    Code (CSharp):
    1. transform.position = Vector3.Lerp(startPosition, endPosition, elapsedTime);
    2. 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:
    Code (CSharp):
    1. void Update () {
    2. if (Input.GetKeyUp("e")) StartCoroutine(OpenDoor());
    3. }
    4.  
    5. IEnumerator OpenDoor {
    6. float elapsedTime = 0;
    7. while (elapsedTime < totalTime) {
    8. transform.position = Vector3.Lerp(startPosition, endPosition, elapsedTime);
    9. elapsedTime += Time.deltaTime;
    10. yield return null;
    11. }
    12. }
     
  3. ericbegue

    ericbegue

    Joined:
    May 31, 2013
    Posts:
    1,353
    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:
    Code (CSharp):
    1. using UnityEngine;
    2. using DG.Tweening;
    3.  
    4. public class Door8 : MonoBehaviour
    5. {
    6.     Vector3 startPosition;
    7.     Vector3 endPosition;
    8.     float speed=0.5f;
    9.  
    10.     void Update()
    11.     {
    12.         if (Input.GetKeyDown("e"))
    13.         {
    14.             float distance = Vector3.Distance(endPosition, startPosition);
    15.             float duration = distance / speed;
    16.             transform.DOMove(endPosition, duration);
    17.         }
    18.     }
    19. }
    20.  
    Hi again @Lanre!
     
    Last edited: May 28, 2016
    Lanre likes this.
  4. cblarsen

    cblarsen

    Joined:
    Mar 10, 2007
    Posts:
    266
    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.

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class Door8 : MonoBehaviour {
    5.  
    6.     Vector3 startPosition;
    7.     Vector3 endPosition;
    8.  
    9.     public float moveDistance = 2f; // The distance we want to move the door
    10.  
    11.     public float speed = 0.5f; // Let's make this public too, so it is easy to change in the inspector
    12.  
    13.     void Start()
    14.     {
    15.         startPosition = transform.position; // startPosition is where the door is when the scene starts
    16.         endPosition = startPosition + Vector3.right * moveDistance; // You could construct endPosition in any other way you want,
    17.                                                                     // as long as it is different from startPosition, otherwise you wont get any movement
    18.     }
    19.  
    20.     float open = 0; // This variable will determine how "open" our door is
    21.     float direction = 0; // this will determine which direction the door is moving. a plus value moves towards endPosition, a minus moves towards startPosition
    22.  
    23.     void Update()
    24.     {
    25.         if(Input.GetKeyDown("e"))
    26.         {
    27.             // Pressing the key means that we want to change the direction the door is moving
    28.             if ( direction > 0 ) // If direction is 0 or 1
    29.                 direction = -1;
    30.             else
    31.                 direction = 1;
    32.         }
    33.         // Now change where the door should be with a speed dependent on how quick time passes
    34.         // We need to do this every update, not just when the key is pressed. Otherwise the door won't keep moving
    35.         open += direction * speed * Time.deltaTime;
    36.         // Also make sure that open doesn't grow outside the 0 - 1 range
    37.         open = Mathf.Clamp01( open );
    38.  
    39.         // Depending on how "open" our door is between startPosition and endPosition. Place it there. Every frame
    40.         transform.position = Vector3.Lerp( startPosition, endPosition, open );
    41.     }
    42. }
    43.  
    It looks like a lot of code, but that is mostly because of all the comments
     
  5. ericbegue

    ericbegue

    Joined:
    May 31, 2013
    Posts:
    1,353
    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:
    Code (CSharp):
    1. using UnityEngine;
    2. using DG.Tweening;
    3.  
    4. public class Door8 : MonoBehaviour
    5. {
    6.     public float openingRange = 1.0f;
    7.     public float duration = 1.0f;
    8.  
    9.     Vector3 openedPosition;
    10.     Vector3 closedPosition;
    11.  
    12.     bool isOpened = false;
    13.  
    14.     void Start()
    15.     {
    16.         closedPosition = this.transform.position;
    17.         openedPosition   = this.transform.position + Vector3.right*openingRange; // Assuming your door slide to the right.
    18.     }
    19.  
    20.     void Update()
    21.     {
    22.         if (Input.GetKeyDown("e"))
    23.         {
    24.             isOpened = !isOpened; // toggle door state
    25.             if( isOpened )
    26.                 transform.DOMove(openedPosition, duration);
    27.             else
    28.                 transform.DOMove(closedPosition, duration);
    29.         }
    30.     }
    31. }
    32.  
    Edit:
    I've just noticed that @cblarsen code handle the opening/closing behaviour as well.
     
    Last edited: May 28, 2016
  6. nieyoub23

    nieyoub23

    Joined:
    May 8, 2016
    Posts:
    27
    I just want to say thank you all for your responses!! I learned so much