Search Unity

Question Elevator platform

Discussion in 'Scripting' started by ElMagnifico, Sep 12, 2020.

  1. ElMagnifico

    ElMagnifico

    Joined:
    Aug 27, 2018
    Posts:
    71
    I'm trying to make an elevator platform that moves between floors. The basic idea is that the scrip is attached to the eleveator itself. A trigger box checked weather he player is on it.

    the elevators coordinates are X = -3, Y = -21, Z = 196 at start with the other two floors being at Y = -51 and Y = -90 respectively.

    I tried writing it like his, but it moves just a little and stops. Obviously my method is flawed. So suggestions are needed.

    Could I simply do a update/LERP of a position along Y axis by 0.1 every update? Is there a better/more efficient way?

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.UI;
    5.  
    6. public class PlatformElevator : MonoBehaviour
    7. {
    8.  
    9.     public int[] stops;
    10.     public Vector3[] coordinates;  //manual input of floor coordinates
    11.     public float smoothing = 10f;
    12.     [SerializeField] private int currentFloor;
    13.     public Text elevatorText;
    14.     private bool onElevator;
    15.     private bool inTransit = false;
    16.     private Vector3 destination;
    17.     private bool directionUp;   //unused
    18.  
    19.     // Start is called before the first frame update
    20.     void Start()
    21.     {
    22.         for (int i = 0; i < stops.Length; i++)
    23.         {
    24.             if (coordinates[i] == transform.position)
    25.             {
    26.                 currentFloor = i;
    27.             }
    28.         }
    29.     }
    30.  
    31.  
    32.     // Update is called once per frame
    33.     void Update()
    34.     {
    35.  
    36.         if ((Input.GetKeyDown(KeyCode.DownArrow) == true) && (onElevator == true) && inTransit == false) //if going down
    37.         {
    38.             inTransit = true; // lock further movement orders until next floor
    39.             if (currentFloor == stops.Length - 1)
    40.             {
    41.                 Debug.Log("Already at bottom floor.");
    42.             }
    43.             else
    44.             {
    45.                 destination = coordinates[currentFloor + 1];
    46.                 transform.position = Vector3.Lerp(transform.position, destination, smoothing * Time.deltaTime);
    47.             }
    48.         }
    49.  
    50.         if ((Input.GetKeyDown(KeyCode.UpArrow) == true) && (onElevator == true) && inTransit == false)  //if going up
    51.         {
    52.             inTransit = true;
    53.             if (currentFloor == 0)
    54.             {
    55.                 Debug.Log("Already at top floor.");
    56.             }
    57.             else
    58.             {
    59.                 destination = coordinates[currentFloor - 1];
    60.                 transform.position = Vector3.Lerp(transform.position, destination, smoothing * Time.deltaTime);
    61.             }
    62.         }
    63.  
    64.  
    65.         if(transform.position == destination)
    66.         {
    67.             inTransit = false;
    68.             for (int i = 0; i < stops.Length; i++)
    69.             {
    70.                 if (coordinates[i] == destination)
    71.                 {
    72.                     currentFloor = i;
    73.                 }
    74.             }
    75.         }
    76.  
    77.     }
    78.  
    79.  
    80.     private void OnTriggerEnter(Collider other)
    81.     {
    82.  
    83.         if (other.CompareTag("Player"))
    84.         {
    85.             elevatorText.gameObject.SetActive(true);
    86.             onElevator = true;
    87.         }
    88.     }
    89.  
    90.     private void OnTriggerExit(Collider other)
    91.     {
    92.         if (other.CompareTag("Player"))
    93.         {
    94.             elevatorText.gameObject.SetActive(false);
    95.             onElevator = false;
    96.         }
    97.     }
    98.  
    99. }
    100.  


    Perhaps changing the bit in the key press (else) to this?

    Code (CSharp):
    1.                 finalDestination = coordinates[currentFloor - 1];
    2.                 //transform.position = Vector3.Lerp(transform.position, destination, smoothing * Time.deltaTime);
    3.  
    4.                 destination = new Vector3(transform.position.x, (float)(transform.position.y+0.1), transform.position.z);
    5.                 transform.position = Vector3.Lerp(transform.position, destination, smoothing * Time.deltaTime);
    and then check for finalDesitionaion instead of destination?


    EDIT: Nope, doesn't work at all.... hmm...
     
    Last edited: Sep 12, 2020
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,742
    I would make an elevator prefab, complete with elevator control script on the root object.

    It would have an array of Transforms in the script that contain all the stops that the elevator can stop at, such as top and bottom. Then it would also have a "speed of motion" and you can Vector3.MoveTowards() the actual visible platform of the elevator each frame when it is in transit.

    Screen Shot 2020-09-12 at 8.58.30 AM.png
     
  3. Nad_B

    Nad_B

    Joined:
    Aug 1, 2021
    Posts:
    730
    Your code is overcomplicated and hard to follow. Using @Kurt-Dekker suggestions, your code should look something like this (not tested)


    Code (CSharp):
    1. public class Elevator : MonoBehavior
    2. {
    3.     [SerializeField]
    4.     private List<Transform> stops; // assign from Editor using empty GameObjects
    5.  
    6.     [SerializeField]
    7.     private float speed = 1; // 1 m/s
    8.  
    9.     private Transform currentStop;
    10.     private bool isMoving;
    11.     private bool isActive;
    12.  
    13.     private void Awake()
    14.     {
    15.         // initialize currentStop to the 1st one
    16.         currentStop = stops[0];
    17.     }
    18.  
    19.     private void Update()
    20.     {
    21.         if (isActive)
    22.             MoveElevator();
    23.     }
    24.  
    25.     private void MoveElevator()
    26.     {
    27.         // check if we reached our destination...
    28.         if (Vector3.Distance(transform.position, currentStop.position) < 0.01f)
    29.         {
    30.             isMoving = false;
    31.             return;
    32.         }
    33.  
    34.         // maybe use a Tween library for a better result (easing)
    35.         transform.Position = Vector3.MoveTowards(transform.position, currentStop, speed * Time.deltaTime);
    36.         isMoving = true;
    37.     }
    38.  
    39.     // returns bool to know if operation was successful or not (maybe play a "failed/error" sound effect when false?)
    40.     private bool TryMoveToNextStop()
    41.     {
    42.         // if we're moving or we're on the last stop return false
    43.         if (isMoving || stops.IndexOf(currentStop) == stops.Count - 1)
    44.             return false;
    45.  
    46.         currentStop = stops[stops.IndexOf(currentStop) + 1];
    47.         return true;
    48.     }
    49.  
    50.     private bool TryMoveToPreviousStop()
    51.     {
    52.         // if we're moving or we're on the first stop return false
    53.         if (isMoving || stops.IndexOf(currentStop) == 0)
    54.             return false;
    55.  
    56.         currentStop = stops[stops.IndexOf(currentStop) - 1];
    57.         return true;
    58.     }
    59.  
    60.     // To do: add logic to set isActive to true/false when TriggerEnter/Exit
    61.     // and call TryMoveToNext/PreviousStop when player presses relevant keys...
    62. }
     
    Last edited: Oct 19, 2023