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): using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class PlatformElevator : MonoBehaviour { public int[] stops; public Vector3[] coordinates; //manual input of floor coordinates public float smoothing = 10f; [SerializeField] private int currentFloor; public Text elevatorText; private bool onElevator; private bool inTransit = false; private Vector3 destination; private bool directionUp; //unused // Start is called before the first frame update void Start() { for (int i = 0; i < stops.Length; i++) { if (coordinates[i] == transform.position) { currentFloor = i; } } } // Update is called once per frame void Update() { if ((Input.GetKeyDown(KeyCode.DownArrow) == true) && (onElevator == true) && inTransit == false) //if going down { inTransit = true; // lock further movement orders until next floor if (currentFloor == stops.Length - 1) { Debug.Log("Already at bottom floor."); } else { destination = coordinates[currentFloor + 1]; transform.position = Vector3.Lerp(transform.position, destination, smoothing * Time.deltaTime); } } if ((Input.GetKeyDown(KeyCode.UpArrow) == true) && (onElevator == true) && inTransit == false) //if going up { inTransit = true; if (currentFloor == 0) { Debug.Log("Already at top floor."); } else { destination = coordinates[currentFloor - 1]; transform.position = Vector3.Lerp(transform.position, destination, smoothing * Time.deltaTime); } } if(transform.position == destination) { inTransit = false; for (int i = 0; i < stops.Length; i++) { if (coordinates[i] == destination) { currentFloor = i; } } } } private void OnTriggerEnter(Collider other) { if (other.CompareTag("Player")) { elevatorText.gameObject.SetActive(true); onElevator = true; } } private void OnTriggerExit(Collider other) { if (other.CompareTag("Player")) { elevatorText.gameObject.SetActive(false); onElevator = false; } } } Perhaps changing the bit in the key press (else) to this? Code (CSharp): finalDestination = coordinates[currentFloor - 1]; //transform.position = Vector3.Lerp(transform.position, destination, smoothing * Time.deltaTime); destination = new Vector3(transform.position.x, (float)(transform.position.y+0.1), transform.position.z); 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...
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.
Your code is overcomplicated and hard to follow. Using @Kurt-Dekker suggestions, your code should look something like this (not tested) Code (CSharp): public class Elevator : MonoBehavior { [SerializeField] private List<Transform> stops; // assign from Editor using empty GameObjects [SerializeField] private float speed = 1; // 1 m/s private Transform currentStop; private bool isMoving; private bool isActive; private void Awake() { // initialize currentStop to the 1st one currentStop = stops[0]; } private void Update() { if (isActive) MoveElevator(); } private void MoveElevator() { // check if we reached our destination... if (Vector3.Distance(transform.position, currentStop.position) < 0.01f) { isMoving = false; return; } // maybe use a Tween library for a better result (easing) transform.Position = Vector3.MoveTowards(transform.position, currentStop, speed * Time.deltaTime); isMoving = true; } // returns bool to know if operation was successful or not (maybe play a "failed/error" sound effect when false?) private bool TryMoveToNextStop() { // if we're moving or we're on the last stop return false if (isMoving || stops.IndexOf(currentStop) == stops.Count - 1) return false; currentStop = stops[stops.IndexOf(currentStop) + 1]; return true; } private bool TryMoveToPreviousStop() { // if we're moving or we're on the first stop return false if (isMoving || stops.IndexOf(currentStop) == 0) return false; currentStop = stops[stops.IndexOf(currentStop) - 1]; return true; } // To do: add logic to set isActive to true/false when TriggerEnter/Exit // and call TryMoveToNext/PreviousStop when player presses relevant keys... }