505 lines
15 KiB
Markdown
505 lines
15 KiB
Markdown
# Lua API Рублокса (справочник для скриптеров)
|
||
|
||
Этот документ — полный список того, что работает в Lua-скриптах Рублокса.
|
||
API максимально приближен к Roblox, чтобы можно было переносить чужие
|
||
скрипты с минимальными правками.
|
||
|
||
> **Как переключить скрипт на Lua:** в шапке вкладки редактора кода кликни
|
||
> по переключателю **JS / Lua**. Подсветка синтаксиса и автодополнение
|
||
> автоматически переключатся.
|
||
|
||
---
|
||
|
||
## Содержание
|
||
|
||
1. [Базовые типы](#базовые-типы)
|
||
2. [DataModel: game, workspace, Players](#datamodel)
|
||
3. [Part — куб на сцене](#part)
|
||
4. [Создание и удаление](#создание-и-удаление)
|
||
5. [События: Touched, Heartbeat, RemoteEvent](#события)
|
||
6. [Таймеры: task.wait, task.delay](#таймеры)
|
||
7. [GUI: TextLabel, TextButton, Frame](#gui)
|
||
8. [Звук: Sound](#звук)
|
||
9. [Анимации: TweenService](#tweenservice)
|
||
10. [Игрок: Humanoid, LocalPlayer](#игрок)
|
||
11. [Чего пока нет](#чего-пока-нет)
|
||
|
||
---
|
||
|
||
## Базовые типы
|
||
|
||
### `Vector3`
|
||
|
||
```lua
|
||
local v = Vector3.new(1, 2, 3)
|
||
print(v.X, v.Y, v.Z) -- 1 2 3
|
||
print(v.Magnitude) -- 3.7416... (длина)
|
||
print(v.Unit) -- нормализованный
|
||
print(v:Dot(otherVec)) -- скалярное произведение
|
||
print(v:Cross(otherVec)) -- векторное произведение
|
||
local mid = v:Lerp(otherVec, 0.5) -- линейная интерполяция
|
||
|
||
-- Константы:
|
||
Vector3.zero -- (0,0,0)
|
||
Vector3.one -- (1,1,1)
|
||
Vector3.xAxis -- (1,0,0)
|
||
Vector3.yAxis, Vector3.zAxis
|
||
```
|
||
|
||
Поддержаны операторы: `+`, `-`, `*` (на число), `/`, унарный `-`.
|
||
|
||
### `Color3`
|
||
|
||
```lua
|
||
local c = Color3.new(0.5, 0.2, 0.8) -- 0..1 каждый
|
||
local c2 = Color3.fromRGB(255, 128, 0) -- 0..255
|
||
local c3 = Color3.fromHSV(0.1, 0.8, 1)
|
||
local c4 = Color3.fromHex("#FF8000")
|
||
local mid = c:Lerp(c2, 0.5)
|
||
print(c:ToHex()) -- "#7F33CC"
|
||
```
|
||
|
||
### `UDim2` / `UDim` / `Vector2`
|
||
|
||
Для GUI-координат:
|
||
|
||
```lua
|
||
local pos = UDim2.new(0.5, 0, 0.5, 0) -- центр экрана (scale/offset)
|
||
local pos2 = UDim2.fromScale(0.2, 0.1)
|
||
local pos3 = UDim2.fromOffset(100, 50) -- в пикселях
|
||
```
|
||
|
||
### `CFrame`
|
||
|
||
```lua
|
||
local cf = CFrame.new(0, 10, 0) -- позиция
|
||
local cf2 = CFrame.lookAt(eye, target) -- упрощённый
|
||
print(cf.Position) -- Vector3
|
||
```
|
||
|
||
### `Enum`
|
||
|
||
```lua
|
||
Enum.KeyCode.W
|
||
Enum.KeyCode.Space
|
||
Enum.Material.Plastic, Enum.Material.Neon, Enum.Material.Wood
|
||
Enum.UserInputType.MouseButton1
|
||
Enum.HumanoidStateType.Running
|
||
```
|
||
|
||
---
|
||
|
||
## DataModel
|
||
|
||
Виртуальное дерево, как в Roblox:
|
||
|
||
```lua
|
||
game -- корневой DataModel
|
||
game.Workspace -- = workspace (короче)
|
||
game.Players -- сервис игроков
|
||
game.Players.LocalPlayer -- локальный игрок
|
||
game.ReplicatedStorage -- хранилище общих ресурсов
|
||
game.StarterGui -- стартовое GUI
|
||
game.Lighting -- свет
|
||
```
|
||
|
||
Методы:
|
||
|
||
```lua
|
||
local svc = game:GetService("RunService")
|
||
local part = workspace:FindFirstChild("Coin")
|
||
local part2 = workspace:FindFirstChildOfClass("Part")
|
||
local all = workspace:GetChildren() -- массив всех детей
|
||
local descendants = workspace:GetDescendants()
|
||
local sib = workspace.Coin:FindFirstAncestorOfClass("Workspace")
|
||
print(workspace:IsA("Workspace")) -- true
|
||
```
|
||
|
||
---
|
||
|
||
## Part
|
||
|
||
`Part` — куб/сфера/цилиндр на сцене. **Это обёртка над примитивом Рублокса.**
|
||
Скрипт привязанный к кубу получает его через `script.Parent`:
|
||
|
||
```lua
|
||
-- script.Parent — Part к которому прицеплен скрипт
|
||
print(script.Parent.Name) -- "Part_1"
|
||
|
||
-- Чтение свойств
|
||
print(script.Parent.Position) -- Vector3
|
||
print(script.Parent.Size) -- Vector3
|
||
print(script.Parent.Color) -- Color3
|
||
print(script.Parent.Anchored) -- bool
|
||
print(script.Parent.CanCollide) -- bool
|
||
print(script.Parent.Transparency) -- 0..1
|
||
|
||
-- Запись (двигает куб в реальном времени!)
|
||
script.Parent.Position = Vector3.new(0, 10, 0)
|
||
script.Parent.Size = Vector3.new(5, 1, 5)
|
||
script.Parent.Color = Color3.fromRGB(255, 0, 0)
|
||
script.Parent.Anchored = false -- куб начнёт падать (физика)
|
||
script.Parent.Transparency = 0.5 -- полупрозрачный
|
||
script.Parent.CFrame = CFrame.new(0, 20, 0)
|
||
```
|
||
|
||
---
|
||
|
||
## Создание и удаление
|
||
|
||
### `Instance.new`
|
||
|
||
```lua
|
||
-- Создать Part на сцене
|
||
local p = Instance.new("Part")
|
||
p.Position = Vector3.new(0, 5, 0)
|
||
p.Size = Vector3.new(2, 2, 2)
|
||
p.Color = Color3.fromRGB(255, 100, 0)
|
||
p.Anchored = true
|
||
p.Parent = workspace
|
||
|
||
-- Удалить через 3 секунды
|
||
task.delay(3, function()
|
||
p:Destroy()
|
||
end)
|
||
```
|
||
|
||
Поддержанные классы:
|
||
- **Сцена:** `Part`, `WedgePart`, `MeshPart`
|
||
- **События:** `RemoteEvent`, `BindableEvent`
|
||
- **GUI:** `ScreenGui`, `Frame`, `TextLabel`, `TextButton`, `ImageLabel`,
|
||
`ImageButton`, `TextBox`, `ScrollingFrame`
|
||
- **Звук:** `Sound`
|
||
- **Прочее:** `Folder`, `Humanoid`, `Configuration`, любой `ClassName`
|
||
|
||
---
|
||
|
||
## События
|
||
|
||
### `script.Parent.Touched` — касание игрока
|
||
|
||
```lua
|
||
script.Parent.Touched:Connect(function(hit)
|
||
print("Игрок коснулся!", hit.Name)
|
||
local h = game.Players.LocalPlayer.Character:FindFirstChildOfClass("Humanoid")
|
||
if h then
|
||
h:TakeDamage(100) -- KillBrick
|
||
end
|
||
end)
|
||
```
|
||
|
||
### `RunService.Heartbeat` — каждый кадр
|
||
|
||
```lua
|
||
local RunService = game:GetService("RunService")
|
||
RunService.Heartbeat:Connect(function(dt)
|
||
-- dt — время с прошлого кадра (~0.016)
|
||
script.Parent.Position = script.Parent.Position + Vector3.new(0, 0.1, 0)
|
||
end)
|
||
```
|
||
|
||
### `BindableEvent` / `RemoteEvent` — общение между скриптами
|
||
|
||
```lua
|
||
-- Скрипт A создаёт событие в общем месте
|
||
local event = Instance.new("BindableEvent")
|
||
event.Name = "MyEvent"
|
||
event.Parent = game.ReplicatedStorage
|
||
|
||
-- Скрипт B подписывается
|
||
local event = game.ReplicatedStorage:WaitForChild("MyEvent")
|
||
event.Event:Connect(function(msg, num)
|
||
print("Получено:", msg, num)
|
||
end)
|
||
|
||
-- Скрипт A триггерит
|
||
event:Fire("привет", 42)
|
||
```
|
||
|
||
### `Humanoid.Died`
|
||
|
||
```lua
|
||
local h = game.Players.LocalPlayer.Character:FindFirstChildOfClass("Humanoid")
|
||
h.Died:Connect(function()
|
||
print("игрок умер")
|
||
end)
|
||
h.HealthChanged:Connect(function(newHp)
|
||
print("здоровье:", newHp)
|
||
end)
|
||
```
|
||
|
||
---
|
||
|
||
## Таймеры
|
||
|
||
### `task.wait(сек)` — приостановить скрипт
|
||
|
||
```lua
|
||
print("сейчас")
|
||
task.wait(1)
|
||
print("через секунду")
|
||
```
|
||
|
||
`task.wait` **не блокирует** другие скрипты — это yield через coroutines.
|
||
Можно использовать в `while true do ... task.wait(0.1) end` без проблем.
|
||
|
||
### `task.delay(сек, fn)` — выполнить через
|
||
|
||
```lua
|
||
task.delay(2, function()
|
||
print("через 2 секунды")
|
||
end)
|
||
```
|
||
|
||
### `task.spawn(fn)` — асинхронно
|
||
|
||
```lua
|
||
task.spawn(function()
|
||
print("параллельно с основным потоком")
|
||
end)
|
||
```
|
||
|
||
---
|
||
|
||
## GUI
|
||
|
||
### Базовая иерархия
|
||
|
||
```lua
|
||
-- ScreenGui — корень всех GUI
|
||
local sg = Instance.new("ScreenGui")
|
||
sg.Parent = game.Players.LocalPlayer.PlayerGui
|
||
|
||
-- TextLabel — статичный текст
|
||
local label = Instance.new("TextLabel")
|
||
label.Parent = sg
|
||
label.Text = "Привет!"
|
||
label.TextColor3 = Color3.fromRGB(255, 255, 0)
|
||
label.BackgroundColor3 = Color3.fromRGB(50, 30, 20)
|
||
label.Position = UDim2.new(0.4, 0, 0.1, 0) -- 40% от ширины, 10% от высоты
|
||
label.Size = UDim2.new(0.2, 0, 0.05, 0)
|
||
label.TextSize = 24
|
||
|
||
-- TextButton — кликабельная кнопка
|
||
local btn = Instance.new("TextButton")
|
||
btn.Parent = sg
|
||
btn.Text = "Нажми"
|
||
btn.Position = UDim2.new(0.4, 0, 0.5, 0)
|
||
btn.Size = UDim2.new(0.2, 0, 0.08, 0)
|
||
btn.MouseButton1Click:Connect(function()
|
||
print("Клик!")
|
||
label.Text = "Нажата!"
|
||
end)
|
||
```
|
||
|
||
### Свойства
|
||
|
||
| Свойство | Тип | Описание |
|
||
|----------------------|-----------|-----------------------------------|
|
||
| `Text` | string | Видимый текст |
|
||
| `TextColor3` | Color3 | Цвет текста |
|
||
| `TextSize` | number | Размер шрифта |
|
||
| `BackgroundColor3` | Color3 | Цвет фона |
|
||
| `BackgroundTransparency` | 0..1 | 0=сплошной, 1=прозрачный |
|
||
| `Position` | UDim2 | Позиция (scale=%, offset=px/10) |
|
||
| `Size` | UDim2 | Размер |
|
||
| `Visible` | bool | Виден или нет |
|
||
|
||
### События кнопок
|
||
|
||
```lua
|
||
btn.MouseButton1Click:Connect(fn) -- ЛКМ клик
|
||
btn.MouseEnter:Connect(fn) -- наведение
|
||
btn.MouseLeave:Connect(fn) -- увод
|
||
btn.Activated:Connect(fn) -- = MouseButton1Click
|
||
```
|
||
|
||
---
|
||
|
||
## Звук
|
||
|
||
```lua
|
||
local sound = Instance.new("Sound")
|
||
sound.SoundId = "coin" -- или "jump", "win", "lose", "hit", "click", "pickup"
|
||
sound.Volume = 1 -- 0..2
|
||
sound.PlaybackSpeed = 1 -- pitch
|
||
sound:Play()
|
||
```
|
||
|
||
Также Roblox-AssetID работает с эвристикой:
|
||
|
||
```lua
|
||
sound.SoundId = "rbxassetid://1234567890" -- автоподбор по имени переменной
|
||
```
|
||
|
||
Поддержанные звуки (процедурные, не из файлов):
|
||
- `jump` — прыжок
|
||
- `pickup` — подбор
|
||
- `coin` — звон монеты
|
||
- `win` — победа
|
||
- `lose` — поражение
|
||
- `click` — клик
|
||
- `hit` — удар
|
||
|
||
Зацикливание:
|
||
|
||
```lua
|
||
sound.Looped = true
|
||
sound:Play() -- играет до sound:Stop()
|
||
```
|
||
|
||
---
|
||
|
||
## TweenService
|
||
|
||
Плавная анимация свойств:
|
||
|
||
```lua
|
||
local TweenService = game:GetService("TweenService")
|
||
|
||
local part = script.Parent
|
||
local tween = TweenService:Create(
|
||
part,
|
||
{ Time = 2 }, -- длительность 2 сек
|
||
{ Position = Vector3.new(0, 20, 0),
|
||
Color = Color3.fromRGB(255, 0, 0) } -- цели
|
||
)
|
||
tween:Play()
|
||
|
||
tween.Completed:Connect(function()
|
||
print("Анимация завершилась!")
|
||
end)
|
||
```
|
||
|
||
Работает с `Position`, `Size`, `Color` (Vector3/Color3) и числовыми
|
||
свойствами (`Transparency`, `TextSize`, и т.д.).
|
||
|
||
---
|
||
|
||
## Игрок
|
||
|
||
### `game.Players.LocalPlayer`
|
||
|
||
```lua
|
||
local plr = game.Players.LocalPlayer
|
||
print(plr.Name, plr.UserId, plr.DisplayName)
|
||
print(plr.Character) -- Model
|
||
```
|
||
|
||
### `Humanoid`
|
||
|
||
```lua
|
||
local char = game.Players.LocalPlayer.Character
|
||
local h = char:FindFirstChildOfClass("Humanoid")
|
||
|
||
print(h.Health, h.MaxHealth)
|
||
print(h.WalkSpeed) -- скорость ходьбы
|
||
print(h.JumpPower) -- сила прыжка
|
||
|
||
h.Health = 0 -- мгновенная смерть → респавн
|
||
h:TakeDamage(50) -- урон с учётом invulnerability
|
||
|
||
h.Died:Connect(function()
|
||
print("Помер")
|
||
end)
|
||
h.HealthChanged:Connect(function(newHp)
|
||
if newHp < 30 then
|
||
print("Здоровье низкое!")
|
||
end
|
||
end)
|
||
```
|
||
|
||
### `HumanoidRootPart`
|
||
|
||
```lua
|
||
local hrp = char:FindFirstChild("HumanoidRootPart")
|
||
print(hrp.Position)
|
||
```
|
||
|
||
---
|
||
|
||
## Чего пока нет
|
||
|
||
Не работает (пока):
|
||
|
||
- **Скрипты не делятся на Server/LocalScript** — все скрипты client-side.
|
||
- **DataStoreService** — методы есть, но возвращают nil/no-op.
|
||
- **`workspace:Raycast`** / **`game.Lighting.ClockTime`** — заглушки.
|
||
- **`Players.PlayerAdded`** — никогда не фейерится (только один игрок).
|
||
- **3D-анимации (`Animation` instance + `AnimationController`)** —
|
||
`LoadAnimation` возвращает заглушку.
|
||
- **`Sound` из файлов** — только встроенные процедурные.
|
||
- **`SurfaceGui` / `BillboardGui`** — нет, только `ScreenGui`.
|
||
- **`Model:MoveTo` / `:SetPrimaryPartCFrame`** — нет.
|
||
- **Networking (`RemoteFunction:InvokeServer`)** — RemoteEvent работает
|
||
только в пределах одного клиента.
|
||
|
||
Если что-то из этого критично — открой issue в репо.
|
||
|
||
---
|
||
|
||
## Пример: KillBrick + монета + GUI-счётчик
|
||
|
||
Положи 1 куб и 1 шарик на сцене. К каждому привяжи скрипт:
|
||
|
||
**На кубе (KillBrick):**
|
||
```lua
|
||
script.Parent.Color = Color3.fromRGB(200, 30, 30)
|
||
script.Parent.Touched:Connect(function()
|
||
local h = game.Players.LocalPlayer.Character:FindFirstChildOfClass("Humanoid")
|
||
if h then h:TakeDamage(100) end
|
||
end)
|
||
```
|
||
|
||
**На шарике (Coin):**
|
||
```lua
|
||
script.Parent.Color = Color3.fromRGB(255, 215, 0)
|
||
script.Parent.Touched:Connect(function()
|
||
-- Запускаем событие на ReplicatedStorage
|
||
local re = game.ReplicatedStorage:FindFirstChild("CoinPicked")
|
||
if not re then
|
||
re = Instance.new("BindableEvent")
|
||
re.Name = "CoinPicked"
|
||
re.Parent = game.ReplicatedStorage
|
||
end
|
||
re:Fire()
|
||
script.Parent:Destroy()
|
||
end)
|
||
```
|
||
|
||
**Глобальный скрипт (GUI):**
|
||
```lua
|
||
local sg = Instance.new("ScreenGui")
|
||
sg.Parent = game.Players.LocalPlayer.PlayerGui
|
||
|
||
local label = Instance.new("TextLabel")
|
||
label.Parent = sg
|
||
label.Text = "Монет: 0"
|
||
label.Position = UDim2.new(0.05, 0, 0.05, 0)
|
||
label.Size = UDim2.new(0.1, 0, 0.05, 0)
|
||
label.TextSize = 20
|
||
label.TextColor3 = Color3.fromRGB(255, 215, 0)
|
||
|
||
local count = 0
|
||
task.spawn(function()
|
||
while not game.ReplicatedStorage:FindFirstChild("CoinPicked") do
|
||
task.wait(0.1)
|
||
end
|
||
game.ReplicatedStorage.CoinPicked.Event:Connect(function()
|
||
count = count + 1
|
||
label.Text = "Монет: " .. count
|
||
local sound = Instance.new("Sound")
|
||
sound.SoundId = "coin"
|
||
sound:Play()
|
||
end)
|
||
end)
|
||
```
|
||
|
||
Получится: красный куб убивает, золотая монета даёт +1 к счётчику со
|
||
звуком.
|
||
|
||
---
|
||
|
||
**Версия документации:** Этап 7 (готово после реализации Этапов 1-6).
|
||
Если что-то описанное здесь не работает — это баг, репортуй.
|