Roblox · Дополнительное

Лифт

Платформа с панелью: E — вверх, Q — вниз. Едет плавно, стоящих на ней везёт с собой. Этажей сколько угодно — точки 1, 2, 3…

Структура

Синим — что нужно создать.

Workspace
└─ Elevator (Model) — PrimaryPart = Base
   ├─ Base (Part) — платформа
   ├─ Panel (Part) — панель — приварится к платформе
   │  └─ Up, Down (ProximityPrompt) — «Вверх» (E), «Вниз» (Q)
   ├─ Floors (Folder) — точки 1, 2, 3… — где центр платформы на этаже
   ├─ Configuration (Configuration) — Speed
   └─ ElevatorServer (Script)

Шаги

  1. Модель «Elevator»: платформа «Base», панель «Panel» с двумя ProximityPrompt «Up» и «Down» (разные клавиши: KeyboardKeyCode E и Q, у второй UIOffset 0, 60 — надписи не налезают).
  2. Folder «Floors»: невидимые точки с именами 1, 2, 3… — на высоте, где должен быть центр платформы на этаже.
  3. Как работает — как у движущейся платформы: детали привариваются к Base, AlignPosition тянет её к точке этажа со скоростью Speed. Платформу двигает физика, поэтому стоящие на ней едут вместе с ней (с Anchored-платформой и TweenService персонаж бы провалился или соскользнул).
  4. Наверху «Вверх» исчезает, внизу — «Вниз».

Скрипты

ElevatorServer

Где: Workspace → Elevator · Script
Зачем: Платформа ездит между этажами.

-- лифт: платформа Base, панель с кнопками, точки этажей
local model = script.Parent
-- платформа
local base = model:WaitForChild("Base")
-- панель
local panel = model:WaitForChild("Panel")
-- «Вверх»
local upPrompt = panel:WaitForChild("Up")
-- «Вниз»
local downPrompt = panel:WaitForChild("Down")
-- точки этажей 1, 2, 3…
local floorsFolder = model:WaitForChild("Floors")
-- Speed
local config = model:WaitForChild("Configuration")
-- этажи
local floors = floorsFolder:GetChildren()
-- по номерам
table.sort(floors, function(a, b) return (tonumber(a.Name) or 0) < (tonumber(b.Name) or 0) end)
-- лифт ездит только вверх-вниз
local startX, startZ = base.Position.X, base.Position.Z

-- все детали лифта
for _, part in ipairs(model:GetDescendants()) do
    -- кроме платформы и точек этажей
    if part:IsA("BasePart") and part ~= base and not part:IsDescendantOf(floorsFolder) then
        -- сварка
        local weld = Instance.new("WeldConstraint")
        -- к платформе
        weld.Part0 = base
        -- деталь
        weld.Part1 = part
        -- в деталь
        weld.Parent = part
        -- едет вместе с платформой
        part.Anchored = false
    -- конец проверки
    end
-- конец перебора
end

-- точка тяги
local attachment = Instance.new("Attachment")
-- в платформу
attachment.Parent = base
-- тянет платформу к этажу
local align = Instance.new("AlignPosition")
-- цель — точка в мире
align.Mode = Enum.PositionAlignmentMode.OneAttachment
-- кого тянем
align.Attachment0 = attachment
-- не провиснет под игроками
align.MaxForce = math.huge
-- скорость лифта
align.MaxVelocity = config.Speed.Value
-- точно держит скорость
align.Responsiveness = 50
-- пока стоит
align.Position = base.Position
-- включаем
align.Parent = base
-- не даёт наклоняться
local orientation = Instance.new("AlignOrientation")
-- держит заданный поворот
orientation.Mode = Enum.OrientationAlignmentMode.OneAttachment
-- кого держим
orientation.Attachment0 = attachment
-- поворот — как в редакторе
orientation.CFrame = base.CFrame
-- жёстко
orientation.RigidityEnabled = true
-- включаем
orientation.Parent = base
-- двигает физика — стоящих на платформе она везёт с собой
base.Anchored = false
-- физику считает сервер — у всех одинаково
base:SetNetworkOwner(nil)

-- текущий этаж
local index = 1
-- ехать на этаж i
local function Go(i)
    -- не выше последнего и не ниже первого
    index = math.clamp(i, 1, #floors)
    -- центр платформы — на высоте точки этажа
    align.Position = Vector3.new(startX, floors[index].Position.Y, startZ)
    -- «Вверх» — если есть куда
    upPrompt.Enabled = index < #floors
    -- «Вниз» — если есть куда
    downPrompt.Enabled = index > 1
-- конец функции
end
-- начинаем с первого
Go(1)
-- нажали «Вверх»
upPrompt.Triggered:Connect(function() Go(index + 1) end)
-- нажали «Вниз»
downPrompt.Triggered:Connect(function() Go(index - 1) end)

Проверка

Запусти Play (или Run) и убедись:

Собрать лифт одной командой