Juraj Juraj
Juraj Juraj

Reputation: 19

Unity3d lift movement down with keycode

this code does so when I press the A key or the B key, the elevator stops upwards on the first or second floor.

The question is

How do I modify the code that when the elevator is on the second floor, for example, and I press the A key again to make the elevator go down to the first floor?

Question two

If I replace

if (Input.GetKey (KeyCode.A)) {} 

with this

if (Input.GetKeyUp (KeyCode.Keypad1)) {} 

so the code does not work. Why?

Thank you for advice

Sorry for the bad English. Here is the code

public GameObject lift;
private bool keyHHit=false;
private bool keyHHitB=false;

void Update () 
{
    if (Input.GetKey(KeyCode.B)) 
    { 
        keyHHit=true;
    }

    if( keyHHit==true)
    {
        if(transform.localPosition.y >= 14.52)
        {  
            transform.Translate(new Vector3(0, 0, 0) * 2 * Time.deltaTime, Space.Self);
        }
        else
        {
            transform.Translate(new Vector3(0, 2, 0) * 2 * Time.deltaTime, Space.Self);
        }
    }      

     if (Input.GetKey(KeyCode.A)) 
     { 
         keyHHitB=true;                       
     }

     if( keyHHitB==true)
     {
         if(transform.localPosition.y >= 8.52)
         {  
             transform.Translate(new Vector3(0, 0, 0) * 2 * Time.deltaTime, Space.Self);
         }
         else
         {
             transform.Translate(new Vector3(0, 2, 0) * 2 * Time.deltaTime, Space.Self);
             //transform.Translate(Vector3.up * 0.05f);
         }
     }               
 }

Upvotes: 0

Views: 215

Answers (1)

derHugo
derHugo

Reputation: 90659

So if I understand you correctly

  • you have two or 3 floors (doesn't matter, could be more later).

  • Once you press a button you want to move towards the target floor until you reach there. "Lock" input meanwhile

  • Once you reached a floor "unlock" Input again and allow to also go down if the current floor is above the target floor

I would use a Coroutine and Vector3.Lerp for this.

First lets have a class for floors so it is easier to add additional floors later

[Serializable]
public class FloorSetting
{
    public KeyCode Key;
    public Vector3 Position;
}

Then simply have an array of all floors target positions and according keys

// Configure these floors in the Inspector
// simply add the entries you need and adjust buttons and target positions
[SerializeField] private FloorSetting[] floors;

[SerializeField] private float moveUnitsPerSecond = 1f;

// This flag is for blocking any Input while moving
// thus preventing concurrent routines
private bool isMoving;

private void Update()
{
    // if already moving do nothing
    if(isMoving) return;

    // check if any of the configured keys was pressed and start moving
    // towards the according position
    foreach(var floor in floors)
    {
        // You want to use GetKeyDown to only get the first press event
        // you don't care about continues press since you will keep moving automatically until reaching the floor
        if(Input.GetKeyDown(floor.Key))
        {
            StartCoroutine(MoveRoutine(floor.Position));
        }
    }
}

private IEnumerator MoveRoutine(Vector3 targetPosition)
{
    // block concurrent routine
    if(isMoving) yield break;

    isMoving = true;


    // Get the duration of movement
    var startPosition = transform.position;
    var duration = Vector3.Distance(startPosition, targetPosition) / moveUnitsPerSecond;

    // Move smoothly towards the target position and add some easing
    var timePassed = 0f;
    while(timePassed <= duration)
    {
        // A interpolation factor between 0 and 1
        var factor = timePassed / duration;
        // optionally add ease-in and out
        factor = Mathf.SmoothStep(0, 1, factor);

        // Set the position to an interpolated position between start and target depending on the factor
        transform.position = Vector3.Lerp(startPosition, targetPosition, factor);

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

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

    // Just to be sure in he end set it to hard position
    transform.position = targetPosition;

    // optionally add some cooldown in seconds
    yield return new WaitForSeconds(1f);

    // Release the lock so next move can start now
    isMoving = false;
}

If you don't need the easing you could as well also implement it lot easier using Vector3.MoveTowards like e.g.

while(!Mathf.Approximately(Vector3.Distance(transform.position, targetPosition), 0)
{
    transform.position = Vector3.MoveTowards(transform.position, targetPosition, moveUnitsPerSecond);

    yield return null;
}

transform.position = targetPosition;

Note: Typed on smartphone but I hope the idea gets clear

Upvotes: 1

Related Questions