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?
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:
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);
}
}
}
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.