Roblox · 2D Раннер · урок 1

Карта и камера сбоку

Трасса из платформ, которая уходит вдоль одной оси, и камера, которая всегда смотрит на персонажа сбоку — трёхмерная игра выглядит как двумерная.

Структура

Синим — что добавляем на этом уроке.

Workspace
├─ Map (Folder) — все платформы трассы
│  └─ Platform1, Platform2, … (Part) — Anchored; одна линия вдоль оси X
└─ SpawnLocation (SpawnLocation) — в начале трассы; лицом в сторону бега
StarterPlayer
└─ StarterPlayerScripts
   └─ CameraScript (LocalScript)

Шаги

  1. File → New → один из первых трёх шаблонов. Лишнее с карты удали, Baseplate можно оставить как пол или убрать.
  2. Workspace → «+» → Folder «Map». Строй платформы внутри неё (Anchored — вкл.).
  3. Трасса идёт в одну линию: от SpawnLocation в сторону минуса оси X (против красной стрелки инструмента Move). Все платформы — на одной глубине (одинаковая координата Z), иначе персонаж с них свалится.
  4. Чередуй ровные участки, ступеньки, ямы и платформы на разной высоте — чтобы было где прыгать.
  5. Поставь SpawnLocation в начале трассы. Включи Orientation Indicator (правой кнопкой по детали): передняя сторона должна смотреть туда, куда бежать.
  6. StarterPlayer → StarterPlayerScripts → «+» → LocalScript «CameraScript» — текст из «Скриптов».
  7. OFFSET = Vector3.new(0, 2, -50): камера на 50 студий сбоку от персонажа, бег идёт слева направо. Убери минус у 50 — камера перейдёт на другую сторону трассы. Поменяй местами 0 и −50 — камера встанет позади персонажа.
  8. FieldOfView — угол обзора: чем меньше, тем «площе» картинка и тем дальше нужно отодвигать камеру.

Скрипты

CameraScript

Где: StarterPlayer → StarterPlayerScripts · LocalScript
Зачем: Каждый кадр ставит камеру сбоку от персонажа.

-- игрок на этом компьютере
local player = game.Players.LocalPlayer
-- его камера
local camera = workspace.CurrentCamera
-- события каждого кадра
local RunService = game:GetService("RunService")
-- камера на 50 студий сбоку и чуть выше персонажа
local OFFSET = Vector3.new(0, 2, -50)

-- настроить камеру для нового персонажа
local function Setup(character)
    -- центр персонажа
    local hrp = character:WaitForChild("HumanoidRootPart")
    -- его здоровье и движение
    local humanoid = character:WaitForChild("Humanoid")
    -- камерой управляет скрипт, а не мышь
    camera.CameraType = Enum.CameraType.Scriptable
    -- узкий угол обзора — картинка почти плоская, как в 2D
    camera.FieldOfView = 40
    -- каждый кадр, сразу после стандартной камеры
    RunService:BindToRenderStep("CameraCFrame", Enum.RenderPriority.Camera.Value + 1, function()
        -- точка, где стоит камера
        local position = hrp.Position + OFFSET
        -- ставим камеру и смотрим на персонажа
        camera.CFrame = CFrame.lookAt(position, hrp.Position)
    -- конец функции кадра
    end)
    -- персонаж погиб
    humanoid.Died:Connect(function()
        -- отключаем слежение — новый персонаж включит его снова
        RunService:UnbindFromRenderStep("CameraCFrame")
    -- конец обработчика
    end)
-- конец функции
end

-- каждый новый персонаж
player.CharacterAdded:Connect(Setup)
-- персонаж уже успел появиться до запуска скрипта
if player.Character then Setup(player.Character) end

Проверка

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