Roblox · Анимации
Заходишь в зону — сверху и снизу выезжают чёрные полосы, камера облетает точки, внизу субтитры. Потом камера возвращается, и можно играть.
Синим — что нужно создать.
Workspace ├─ CutsceneTrigger (Part) — зона запуска: прозрачная, CanCollide выкл.; атрибут Repeat — показывать каждый раз └─ CutscenePoints (Folder) └─ 1, 2, 3… (Part) — передняя грань — куда смотрит камера; атрибуты Text, Time, Hold StarterGui └─ CutsceneGui (ScreenGui) — ResetOnSpawn выкл., IgnoreGuiInset вкл. ├─ Top, Bottom (Frame) — чёрные полосы, спрятаны за краями экрана └─ Subtitle (TextLabel) StarterPlayer → StarterPlayerScripts └─ CutsceneLocal (LocalScript)
Где: StarterPlayer → StarterPlayerScripts · LocalScript
Зачем: Полосы, полёт камеры, субтитры.
-- плавное движение камеры
local TS = game:GetService("TweenService")
-- этот игрок
local player = game.Players.LocalPlayer
-- его камера
local camera = workspace.CurrentCamera
-- зона, где начинается катсцена
local trigger = workspace:WaitForChild("CutsceneTrigger")
-- точки камеры 1, 2, 3…
local points = workspace:WaitForChild("CutscenePoints")
-- чёрные полосы и субтитры
local gui = player:WaitForChild("PlayerGui"):WaitForChild("CutsceneGui")
-- верхняя полоса
local top = gui:WaitForChild("Top")
-- нижняя полоса
local bottom = gui:WaitForChild("Bottom")
-- текст
local subtitle = gui:WaitForChild("Subtitle")
-- управление персонажем
local controls = require(player:WaitForChild("PlayerScripts"):WaitForChild("PlayerModule")):GetControls()
-- идёт катсцена
local playing = false
-- уже показывали
local played = false
-- показать или спрятать полосы кино
local function Bars(show)
-- полсекунды
local info = TweenInfo.new(0.5)
-- верхняя выезжает сверху
TS:Create(top, info, {Position = show and UDim2.fromScale(0, 0) or UDim2.fromScale(0, -0.12)}):Play()
-- нижняя — снизу
TS:Create(bottom, info, {Position = show and UDim2.fromScale(0, 0.88) or UDim2.fromScale(0, 1)}):Play()
-- конец функции
end
-- сама катсцена
local function Play()
-- точки
local list = points:GetChildren()
-- по номерам
table.sort(list, function(a, b) return (tonumber(a.Name) or 0) < (tonumber(b.Name) or 0) end)
-- точек нет
if #list == 0 then return end
-- идёт
playing = true
-- персонаж стоит
controls:Disable()
-- полосы кино
Bars(true)
-- камерой управляет скрипт
camera.CameraType = Enum.CameraType.Scriptable
-- встаём в первую точку
camera.CFrame = list[1].CFrame
-- каждая точка
for i, point in ipairs(list) do
-- субтитр этой точки
subtitle.Text = point:GetAttribute("Text") or ""
-- к следующей точке летим
if i > 1 then
-- за Time секунд
local tween = TS:Create(camera, TweenInfo.new(point:GetAttribute("Time") or 3, Enum.EasingStyle.Sine), {CFrame = point.CFrame})
-- летим
tween:Play()
-- ждём
tween.Completed:Wait()
-- конец проверки
end
-- смотрим Hold секунд
task.wait(point:GetAttribute("Hold") or 1)
-- конец перебора
end
-- субтитр убираем
subtitle.Text = ""
-- полосы уезжают
Bars(false)
-- камера снова у игрока
camera.CameraType = Enum.CameraType.Custom
-- можно ходить
controls:Enable()
-- кончилась
playing = false
-- атрибут Repeat — показывать каждый раз
played = not trigger:GetAttribute("Repeat")
-- конец функции
end
-- зоны что-то коснулось
trigger.Touched:Connect(function(otherPart)
-- идёт или уже было
if playing or played then return end
-- только свой персонаж
if not player.Character or not otherPart:IsDescendantOf(player.Character) then return end
-- показываем
Play()
-- конец обработчика
end)Запусти Play (или Run) и убедись: