Simulate elevator running system in unity

Simulate elevator running system in unity

提示:需要创建三个脚本,分别是 "FloorButton"、"Doors" 和 "Elevator",需要基本模型和功能按钮,添加相机。



foreword

Use the powerful functions of Unity and C# language to develop the elevator simulation system, nanny-level tutorial, just follow the steps to achieve the desired result. (The original project documents will also be issued later, you can refer to the study)


提示:以下是本篇文章正文内容,下面案例可供参考

1. Model and button (game object) classification preparation

According to the figure below, store the external buttons and internal buttons of the elevator separately, and then create three new scripts, named Doors, FloorButton, and Elevator respectively, and then assign this script to the object according to the figure below. (The number buttons in the elevator and the Up and Down outside can be directly used as a cube. In this case, the UI button is not used. The object clicked by the mouse is the game object)
insert image description here

Two, plug-in import

To prepare for the opening and closing of the elevator door, the DOTween plug-in is used for the door animation. By calling the DOLocalMove method provided by the DOTween library, the animation effect of opening and closing the door is realized to simulate the effect of the elevator door opening. Don't worry, the plug-in is ready here, download it directly, and drag it into the Assets folder of unity (you can also download it on the DOTween official website yourself, the latest one is currently used).

Download link:
Download DOTween folder
Link: https://pan.baidu.com/s/1eZFcDl_uCHhQUnbQBZImCQ?pwd=6m19
Extraction code: 6m19

3. Screenplay

The next step is the script. The parameters that can be changed in the script will tell you how to change them.
Each line of code has comments, the explanation is very clear, even novices can understand it completely.

1. Script for "FloorButton"

The code is as follows (example):
There are two static variables in the ok script, which are "requestDict" and "destinationList". These variables are used to store the request for the elevator, where "requestDict" is a dictionary to store the state of the up or down request, and "destinationList" is a list to store the request to reach the floor.

using System.Collections.Generic;
using UnityEngine;
public class FloorButton : MonoBehaviour
{
    
    
    // 存储Up或Down的请求
    public static Dictionary<string, int> requestDict = new Dictionary<string, int>();
    // 存储到达楼层的请求
    public static List<int> destinationList = new();
    private void OnMouseDown()
    {
    
    
        // 如果鼠标点击的物体名字是Up或者Down
        if (gameObject.name == "Up" || gameObject.name == "Down")
        {
    
    
            // 找到父级的名字
            string floorName = transform.parent.gameObject.name;
            // 记录请求楼层号和Up还是Down
            requestDict[floorName] = gameObject.name == "Up" ? 1 : -1;
        }
        else
        {
    
    
            // 将名字当作到达楼层号
            int destinationFloor = int.Parse(gameObject.name);
            // 记录到达楼层请求
            if (!destinationList.Contains(destinationFloor))
            {
    
    
                destinationList.Add(destinationFloor);
            }
        }
    }
}

2. Script for "Doors"

The code is as follows (example):
There are two private variables "floorDoorL" and "floorDoorR" in the script, representing the left and right Transform objects of the elevator door respectively. There is also a public variable "doorWidth" indicating the distance of the door movement, and two variables of Vector3 type "LOriginPos" and "ROriginPos", which store the original positions of the left door and the right door respectively.

using DG.Tweening;
using UnityEngine;
 public class Doors : MonoBehaviour
{
    
    
    private Transform floorDoorL; // 电梯门左侧的Transform对象
    private Transform floorDoorR; // 电梯门右侧的Transform对象
    public readonly float doorWidth = 0.022f; // 门移动的距离
    private Vector3 LOriginPos; // 左门原始位置
    private Vector3 ROriginPos; // 右门原始位置
    void Start()
    {
    
    
        floorDoorL = transform.Find("doorL"); // 获取左门Transform对象
        floorDoorR = transform.Find("doorR"); // 获取右门Transform对象
        LOriginPos = floorDoorL.localPosition; // 记录原始位置
        ROriginPos = floorDoorR.localPosition;
    }
    public void OpenDoor()
    {
    
    
        // 左门向左移动
        floorDoorL.DOLocalMove(LOriginPos - new Vector3(doorWidth, 0, 0), 1f);
        // 右门向右移动
        floorDoorR.DOLocalMove(ROriginPos + new Vector3(doorWidth, 0, 0), 1f);
    }
    public void CloseDoor()
    {
    
    
        // 左门回到原始位置
        floorDoorL.DOLocalMove(LOriginPos, 1f);
        // 右门回到原始位置
        floorDoorR.DOLocalMove(ROriginPos, 1f);
    }
}

3. Script for “Elevator”


The code is as follows (example):
There are some public variables in the script, such as speed, floor height, the lowest floor and the highest floor (can be modified according to needs) and so on. There are also private variables such as the initial position of the elevator, scripts for all floor doors, current floor number and whether the elevator is running, etc.

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Elevator : MonoBehaviour
{
    
    
    public float speed = 2; // 电梯速度
    public float floorHeight = 6; // 楼层高度
    public int minFloor = 1; // 最底层
    public int maxFloor = 5; // 最高层
    private Vector3 initialPosition; // 电梯初始位置
    private Doors[] floorDoors; // 获取所有楼层门的脚本
    private int currentFloor; // 当前楼层
    private bool isRunning; // 电梯是否运行
    void Start()
    {
    
    
        // 找到所有楼层门的GameObject,并获取其上的 Doors 脚本
        floorDoors = FindObjectsOfType<Doors>();
        //使用Lambda表达式作为参数,用游戏对象的名称进行比较排序
        Array.Sort(floorDoors, (a, b) => string.Compare(a.name, b.name));
        initialPosition = transform.position;
        currentFloor = Mathf.FloorToInt(initialPosition.y / floorHeight) + 1;
    }
    void Update()
    {
    
    
        // 电梯未运行时,开始处理请求
        if (!isRunning)
        {
    
    
            StartCoroutine(HandleRequests());
        }
    }
    private IEnumerator HandleRequests()
    {
    
    
        isRunning = true;
        // 处理Up或Down请求
        foreach (KeyValuePair<string, int> request in FloorButton.requestDict)
        {
    
    
            int targetFloor = int.Parse(request.Key);
            // 检查满足条件的楼层
            if ((request.Value == 1 && targetFloor >= currentFloor) || (request.Value == -1 && targetFloor <= currentFloor)||(request.Value == 1 && targetFloor <= currentFloor) || (request.Value == -1 && targetFloor >= currentFloor))
            {
    
    
                yield return StartCoroutine(MoveToFloor(targetFloor));
                // 打开电梯门
                OpenElevatorDoor();
                // 等待乘客进出电梯
                yield return new WaitForSeconds(4);
                // 关闭电梯门
                CloseElevatorDoor();
                yield return new WaitForSeconds(2);
                // 移除已完成的请求
                FloorButton.requestDict.Remove(request.Key);
                break;
            }
        }
        // 处理到达楼层请求
        for (int i = 0; i < FloorButton.destinationList.Count; i++)
        {
    
    
            yield return StartCoroutine(MoveToFloor(FloorButton.destinationList[i]));
            // 打开电梯门
            OpenElevatorDoor();
            // 等待乘客进出电梯
            yield return new WaitForSeconds(4);
            // 关闭电梯门
            CloseElevatorDoor();
            yield return new WaitForSeconds(3);
            // 移除已到达的楼层
            FloorButton.destinationList.RemoveAt(i);
        }
        // 请求列表为空时,返回初始位置
        if (FloorButton.requestDict.Count == 0 && FloorButton.destinationList.Count == 0)
        {
    
    
            yield return new WaitForSeconds(5);
            yield return StartCoroutine(MoveToFloor(Mathf.FloorToInt(initialPosition.y / floorHeight) + 1));
        }
        isRunning = false;
    }
    private IEnumerator MoveToFloor(int targetFloor)
    {
    
    
        // 计算目标位置
        Vector3 targetPosition = new(initialPosition.x, (targetFloor - 1) * floorHeight, initialPosition.z);
        // 移动电梯
        while (Vector3.Distance(transform.position, targetPosition) > 0.01f)
        {
    
    
            transform.position = Vector3.MoveTowards(transform.position, targetPosition, speed * Time.deltaTime);
            yield return null;
        }
        // 更新当前楼层
        currentFloor = targetFloor;        
    }
    private void OpenElevatorDoor()
    {
    
    
        floorDoors[currentFloor-1].OpenDoor();    
    }
    private void CloseElevatorDoor()
    {
    
    
        floorDoors[currentFloor-1].CloseDoor();
    }
}

Summarize

In this project, I learned how to use the powerful functions of Unity and C# language to develop an elevator simulation system. Specifically, the following were learned:

  1. Coroutine: A coroutine is a lightweight thread that can be used to handle asynchronous operations in Unity, such as animations, network requests, and more. By using the yield return statement to suspend the execution of coroutine functions, we can give other coroutine functions a chance to run when appropriate, making the overall program more efficient.

  2. Static Variables: Static variables are defined on class level and all instances share the same variable. We can use static variables to record the user's request to click the elevator button and the request to reach the floor, and can share these requests among multiple scripts, so as to conveniently control the movement of the elevator and the floor judgment.

  3. DOTween library: DOTween is a plugin for Unity that can be used to create animation effects. The plugin provides the DOLocalMove method, which helps us to animate the opening and closing of the elevator doors. By using this plug-in, we can add various animation effects to the game more conveniently.

  4. Lambda expressions: Lambda expressions are concise anonymous functions that can be used for sorting, filtering, mapping, and more. In this project, we use Lambda expressions to sequence the floor doors to ensure that the elevator opens and closes the doors in the correct order.

In short, in this project, I learned how to use the powerful functions of Unity and C# language to implement a basic elevator system, and mastered many useful programming skills and tools. These skills and knowledge will help you build complex mechanisms and systems more confidently in development.

Guess you like

Origin blog.csdn.net/qq_43238378/article/details/129990170