C# Lift System.

Hello eveyone,

At the moment I am trying to workout the best of making and implementing a lift system for the gameplay enviroment. It will be reaching 4 differnt floors (including groundfloor). I have worked on the sudo code and I am struggling on how to start actully making the code now.

using UnityEngine;
using System.Collections;
 
public class Lift : MonoBehaviour {
 
    //empty gameobjects at different floor heights
    GameObject floor1height;
    GameObject floor2height;
    GameObject floor3height;
    GameObject floor4height;
    // current Floor Number
    int currentfloor;
    // Floor desitination
    int floordes;
    // inside buttons for pressing floors
    GameObject input1;
    GameObject input2;
    GameObject input3;
    GameObject input4;
    // outside buttons
    GameObject floor1input;
    GameObject floor2input;
    GameObject floor3input;
    GameObject floor4input;
 
    // Use this for initialization
    void Start () {
        int currentfloor = 1;
    }
   
    // Update is called once per frame
    void Update () {
        //if (input1 or floorinput1 is pressed){
        //        floordes=1;
        //}   
        //if (input2 or floorinput2 is pressed){
        //        floordes=2;
        //}   
        //if (input3 or floorinput3 is pressed){
        //        floordes=3;
        //}   
        //if (input 4 or floorinput4 is pressed){
        //        floordes=4;
        //}   
        //if (floordes=1){
        //      wait for 3 seconds;
        //        head to floorheight1;
        //}
        //if (floordes=2){
        //        wait for 3 seconds;
        //        head to floorheight2;
        //}
        //if (floordes=3){
        //         wait for 3 seconds;
        //        head to floorheight3;
        //}
        //if (floordes=4){
        //        wait for 3 seconds;
        //        head to floorheight4;
        //}
 
    }
}

If anyone has anyways I could improve the system please feel free to comment.

I have started to think/script on how I could get the “buttons” to work but im abit stuck.
I have gotten the idea that if the mouse is over the “floor 1 button” and then if mouse clicks I could use that to select the floor. The issue that I am having hower is that im stuck on how to code this. I started a test where if the mouse is over it will print the objects name. Now I want to know if there is a way get my “Test” code to work properly,

using UnityEngine;
using System.Collections;
 
public class MouseOver : MonoBehaviour {
 
    public GameObject button1;
 
    void OnMouseOver(){       
        print (gameObject.name);    
    }
}
// Test/idea area
//
//     void OnMouseOver(button1){
//        print (gameObject.name):
//    }
//
//
//

thanks

Maxo

Just some advice here:
If it’s a building then theoretically all floors will be the same height, so you could compress all of your height variables into a float representing the standard height of 1 floor in the building.

Then you could create the actual position for the lift to arrive at programmatically, then you could use this lift solution in any building by just specifying how many floors there are.

positionToArriveAt = new Vector3(liftPosition.x,floorHeight*floorNumber,liftPosition.z);

Apart from that, this is how I would setup the code:

using System;
using UnityEngine;

//In 1 .cs file
class ElevatorButton : MonoBehaviour
{
  public event System.Action<int> ButtonPressed;
  public int m_floorNumber;
  public void Pressed()
  {
     if(ButtonPressed != null)
    {
      ButtonPressed(m_floorNumber);
     }
  }
}


//In a different .cs file
using UnityEngine;
using Systems.Collections.Generic;
class Elevator : MonoBehaviour
{
   public List<ElevatorButton> m_buttons;
   void Start()
   {
         foreach(ElevatorButton button in m_buttons)
        {
            var thisButton = button;
            thisButton.ButtonPressed += delegate(int floorNumber)
             {
                      StartCoroutine(TravelToFloor(floorNumber));
             };
        }
    }

  IEnumerator TravelToFloor(int floorNumber)
{
     //do your movement code here
     //while !reached floornumber
     //yield return null etc.
  }
}

So, For each physical button in your lift, add the ElevatorButton component there. Then, on “some” Gameobject in your scene(preferably something related to the actual lift) add the Elevator component and drag in each Button into the list via the inspector.

Then, somewhere in your player controlling script, to actually detect a button, you can use
Unity - Scripting API: Physics.Raycast, you will need a collider on each button for this to work.

Then, when your Raycast returns true, take the collider info from it.
Then simply write:

ElevatorButton button = collider.gameObject.GetComponent<ElevatorButton>();

if(button != null)
{
  button.Pressed();
}

Obviously there will be missing steps but I think that puts you in the right direction. code is untested btw

I’m not sure why you use a gameobject for floor height, sure it can be done that way too but basically the only thing you need is the Y position for each floor as the elevator only goes up and down.

For the button clicking script you can use raycasting.

And you can try something like this

if (Input.GetMouseButtonDown(0)){ //You pressed left mouse button
            Ray CameraRay = camera.ViewportPointToRay(new Vector3(0.5F, 0.5F, 0)); //gets the middle position of your screen
            RaycastHit hit;
            if (Physics.Raycast (CameraRay,out hit, 3)){   //3 means how FAR the ray goes, 3 might be good but you can adjust it for your needs
                Debug.Log ("Object:" + hit.collider.name); //the object collider name we hit,change this to an if statement for whatever object you want to hit.
            }
        }

Hopefully that gets you started.

Thanks guys some very usefull help here,

Firstly I like the idea of not using the gameobjects for each floor.

secondly I have never usd Raycasting before. Quick question looking at the documention quickly I was a little bit losed, how do I make the object know if it has been hit

Also @ A.Killingbeck tryed to test your code in a test scene I have build and I am coming up with these two errors.

IEnumerator requires a “using System.Collections;”

As for not finding ElevatorButton, are the 2 scripts within the same folder? Have you made the class name actually called ElevatorButton or something else?

Sorry, I had a brain fat, named something else.

Going to be doing alot more work on this hopefully tomorrow, hopefully ill have less bainfats then

If you have a script on an object with a public variable, say a bool named ‘on’, then you can use a raycasthit object in your raycast and modify that variable.

Vector3 start = Camera.main.transform.position;
Vector3 end = start + Camera.main.transform.forward * 3;//change 3 for ray distance
RaycastHit hit;

if(Physics.Linecast(start, end, out hit))
{
    YourButtonScript s = hit.transform.GetComponent<YourButtonScript>();
    if(s != null)
    {
        s.on = true;//you can also just call a function in the script
    }
}