Krótka odpowiedź
Żeby skryptować w Roblox Studio, najedź myszką na ServerScriptService w Explorerze, kliknij + i wstaw Script. Studio otworzy go w Script Editorze. Napisz Luau, na przykład print("Hello"), kliknij Play (F5) i przeczytaj wynik w oknie Output (menu Window albo zakładka Script). Script działa na serwerze i zmienia rzeczy dla wszystkich; LocalScript w StarterPlayerScripts działa na urządzeniu jednego gracza.
- Najpierw naucz się czterech rzeczy: zmiennych (
local coins = 3), funkcji (local function name() ... end), instrukcji if i eventów (part.Touched:Connect(...)). Cztery skrypty z tego poradnika są zbudowane z tego, plus pętli i tabel. - Używaj
task.wait(), niewait(). Dokumentacja Roblox oznacza globalnewait()jako przestarzałe i zastąpione przeztask.wait(). - W opcjach widoku okna Output włącz Show Context, żeby każda linia mówiła, czy przyszła z Server, czy z Client.
Na tej stronie
Zanim zaczniesz: Studio, Baseplate i okno Output
Potrzebujesz Roblox Studio i konta Roblox, nic więcej: ani edytora kodu, ani pluginu. Wszystkie skrypty z tego poradnika piszesz we wbudowanym Script Editorze Studio.
- Zainstaluj Roblox Studio, darmową aplikację Roblox na Windowsa i Maca, i zaloguj się na swoje konto Roblox.
- Otwórz Studio. Strona startowa pokazuje szablony: wybierz Baseplate. Dostajesz podłoże z teksturą siatki 4x4 i SpawnLocation, czyli miejsce, w którym pojawia się twój awatar, gdy grasz.
- Jeśli nie widać okien Explorer i Properties, otwórz je z menu Window albo z zakładki Home. Explorer pokazuje każdy obiekt w twojej grze; Properties pokazuje ustawienia tego, co zaznaczysz.
- Otwórz Output z menu Window albo z zakładki Script. Tam pojawiają się komunikaty i błędy z twoich skryptów.
- W opcjach widoku okna Output włącz Show Context, które oznacza każdy komunikat jako Client albo Server, i Show Source, które pokazuje skrypt i numer linii, z której przyszedł.
| Skrypt | Typ | Gdzie trafia | Czego uczy |
|---|---|---|---|
FirstScript | Script | ServerScriptService | Zmiennych, funkcji, instrukcji if, pętli i tabeli |
ColourChanger | Script | Wewnątrz Part w Workspace | Zmieniania właściwości, script.Parent i pętli, która czeka |
TouchPad | Script | Wewnątrz Part o nazwie Pad | Eventów, znajdowania gracza, który dotknął partu, i debounce |
MyFirstLocalScript | LocalScript | StarterPlayerScripts, wewnątrz StarterPlayer | Kodu działającego na urządzeniu gracza, naciśnięć klawiszy i tego, co zostaje na tym urządzeniu |
Workspace
Baseplate Part
SpawnLocation SpawnLocation
Part Part new
ColourChanger Script new
Pad Part new
TouchPad Script new
ServerScriptService
FirstScript Script new
StarterPlayer
StarterPlayerScripts
MyFirstLocalScript LocalScript new
Krok 1: napisz swój pierwszy skrypt
- W Explorerze najedź myszką na ServerScriptService, kliknij przycisk + i wybierz Script (skrót to Ctrl+I albo ⌘I na Macu). Studio tworzy skrypt i otwiera go w Script Editorze.
- Kliknij nowy skrypt prawym przyciskiem, wybierz Rename i nazwij go
FirstScript. Nazwa nie zmienia tego, co robi skrypt, ale mówi ci, który skrypt co wypisał. - Nowe skrypty zaczynają się od jednej linii,
print("Hello world!"). Usuń ją i wklej kod poniżej. - Kliknij Play (F5), z wybranym Test w rozwijanej liście po jego lewej stronie. Studio rozpoczyna test i stawia twojego awatara na SpawnLocation.
- Przeczytaj linie w Output i kliknij Stop (Shift+F5). Stop przywraca też każdy obiekt do stanu sprzed kliknięcia Play, więc wszystko, co przesunąłeś lub przemalowałeś podczas gry, wraca na miejsce.
-- Script w ServerScriptService o nazwie FirstScript.
-- Twój pierwszy Luau: zmienne, funkcja, instrukcja if, pętla i tabela.
-- Kliknij Play (F5) i przeczytaj wyniki w oknie Output.
-- Zmienna to nazwa, która przechowuje wartość
local gameName = "Coin Run"
local coinsToWin = 3
-- Funkcja to nazwany blok kodu, który możesz uruchamiać, ile razy chcesz.
-- name i goal to jej parametry; return oddaje wartość temu, kto ją wywołał.
local function describe(name: string, goal: number): string
return `{name}: collect {goal} coins to win`
end
print(describe(gameName, coinsToWin)) --> Coin Run: collect 3 coins to win
-- Instrukcja if uruchamia kod tylko wtedy, gdy jej warunek jest prawdziwy
if coinsToWin > 5 then
print("That is a long game")
elseif coinsToWin > 1 then
print("That is a short game")
else
print("One coin and you win")
end
-- Pętla for powtarza kod określoną liczbę razy
for count = 1, coinsToWin do
print("Coin number", count)
end
-- Tabela przechowuje listę wartości; ta pętla odwiedza każdą po kolei
local colours = { "Red", "Green", "Blue" }
for position, colour in colours do
print(position, colour) --> 1 Red, potem 2 Green, potem 3 Blue
end
Wszystko po -- w linii to komentarz: Luau go pomija, więc możesz zostawiać sobie notatki. Komentarze --> pokazują, co wypisuje ta linia.
Output powinien pokazać te osiem linii, przemieszanych z komunikatami samego Studio. Gdy print dostaje więcej niż jedną wartość, wstawia między nimi spację. Z włączonymi Show Context i Show Source każda linia ma dodatkowo etykietę Server i FirstScript z numerem linii.
Coin Run: collect 3 coins to win
That is a short game
Coin number 1
Coin number 2
Coin number 3
1 Red
2 Green
3 Blue
Dopasuj każdą linię do kodu, który ją wypisał. Później zrobisz to samo z komunikatami błędów, więc warto się do tego przyzwyczaić już teraz.
FirstScript używa tylko czystego Luau, bez obiektów Roblox, więc działa też w darmowym Luau playground w przeglądarce. Zmień tam jakąś wartość i uruchom ponownie, żeby zobaczyć, co się zmienia.
| Kod | Idea | Co oznacza |
|---|---|---|
local gameName = "Coin Run" | Zmienna | Nazwa, która przechowuje wartość. local oznacza, że może jej używać tylko ten skrypt albo blok, w którym jest. Tekst w cudzysłowie to string (ciąg znaków); 3 to number (liczba). Nazwy rozróżniają wielkość liter, więc coinsToWin i CoinsToWin to dwie różne zmienne. |
local function describe(name: string, goal: number): string | Funkcja | Nazwany blok kodu, który możesz uruchamiać, ile razy chcesz. name i goal to jej parametry: wartości przekazywane przy każdym wywołaniu. : string i : number to opcjonalne adnotacje typów. Luau używa ich, żeby ostrzegać cię o błędach w Script Editorze; kod działa tak samo bez nich. |
return | Wartość zwracana | Oddaje wartość kodowi, który wywołał funkcję. print(describe(gameName, coinsToWin)) wypisuje to, co zwróci describe. |
`{name}: collect {goal} coins to win` | Interpolacja stringów | Tekst w odwrotnych apostrofach może zawierać wartości: Luau podmienia {name} i {goal} na ich aktualne wartości. |
if, elseif, else, end | Instrukcja if | Luau sprawdza warunki od góry do dołu i uruchamia tylko pierwszy prawdziwy. coinsToWin wynosi 3, czyli nie więcej niż 5, ale więcej niż 1, więc wypisuje się tylko "That is a short game". |
for count = 1, coinsToWin do | Liczbowa pętla for | Uruchamia kod w środku raz dla każdej liczby od 1 do coinsToWin, z count równym 1, potem 2, potem 3. |
{ "Red", "Green", "Blue" } i for position, colour in colours do | Tabela i pętla | Tabela użyta jako lista, którą Luau nazywa array (tablicą). Pozycje zaczynają się od 1, nie od 0. Pętla odwiedza każdy element i daje ci jego pozycję i wartość. |
Każdy blok, który zaczyna się od function, if, for albo while, zamyka się słowem end. Jeden brakujący end nie pozwala uruchomić całego skryptu; czytanie błędów pokazuje komunikat, który wtedy dostajesz.
Krok 2: zmień part ze skryptu
Skrypty stają się przydatne, gdy zmieniają rzeczy w świecie. Ustawienia, które widzisz w oknie Properties, takie jak Color, Transparency czy Anchored partu, to właściwości, i skrypt też może je zmieniać.
- W zakładce Home kliknij Part. Studio dodaje blok do Workspace. Jego nazwa nie ma znaczenia.
- W Explorerze najedź myszką na nowy part, kliknij + i wstaw Script. Nazwij go
ColourChangeri zastąp jego zawartość kodem poniżej. - Kliknij Play. Part robi się czerwony, potem niebieski, potem zielony, zmieniając się raz na sekundę, i zaczyna od nowa.
-- Script wewnątrz Part w Workspace, o nazwie ColourChanger.
-- Skrypty zmieniają te same właściwości, które widzisz w oknie Properties.
-- Ten daje swojemu partowi nowy kolor co sekundę, dla wszystkich graczy.
local part = script.Parent :: BasePart -- part, w którym jest ten skrypt
local colours = {
Color3.fromRGB(255, 85, 85), -- czerwony
Color3.fromRGB(85, 170, 255), -- niebieski
Color3.fromRGB(85, 255, 127), -- zielony
}
part.Anchored = true -- zakotwiczony part zostaje tam, gdzie go postawisz
local index = 1
while true do
part.Color = colours[index]
index = index % #colours + 1 -- 1, 2, 3 i znowu 1
task.wait(1) -- sekunda przerwy (stare wait() jest przestarzałe)
end
script.Parentto obiekt, w którym jest skrypt, tutaj part. Przeciągnij skrypt do innego partu, a zmieni tamten.:: BasePartto rzutowanie typu (type cast). Mówi Script Editorowi, że rodzic jest partem, żeby mógł sprawdzać właściwości, których na nim używasz. Luau używa typów tylko do ostrzeżeń i podpowiedzi, więc rzutowanie nie zmienia tego, co robi linia.part.Coloripart.Anchoredto te same właściwości, które widzisz w oknie Properties, z tymi samymi nazwami. Roblox używa pisowni amerykańskiej, więc właściwość toColor, chociaż ten skrypt nazywa się ColourChanger.Anchored = truetrzyma part w miejscu: dokumentacja Roblox mówi, że zakotwiczony part nigdy nie porusza się przez grawitację, kolizje ani żadną inną fizykę.colours[index]odczytuje element z listy.#coloursto długość listy, 3, a%daje resztę z dzielenia, więcindex % #colours + 1liczy 1, 2, 3, 1, 2, 3.while true dopowtarza się w nieskończoność, dlategotask.wait(1)w środku jest ważne. Dokumentacja Roblox mówi, żeby w nieskończonej pętli zawsze dawać przerwę, taką jaktask.wait(): bez niej gra się zamraża, a Studio się zawiesza.
ColourChanger to Script, więc działa na serwerze, a wszyscy gracze w grze widzą ten sam kolor w tym samym momencie. Krok 4 pokazuje drugi typ skryptu.
Krok 3: zareaguj na gracza eventem
Większość kodu gry czeka, aż coś się stanie: gracz dołącza, part zostaje dotknięty, ktoś klika przycisk. Roblox nazywa to eventami. Żeby uruchomić kod, gdy event zajdzie, podłączasz do niego funkcję.
- Wstaw kolejny Part i nazwij go dokładnie
Pad, z wielkim P. Zostaw go bezpośrednio w Workspace, nie w folderze ani modelu, bo LocalScript z kroku 4 szuka go właśnie tam. - Zrób z niego płaską platformę, na którą da się wejść, na przykład ustawiając jego
Sizena6, 1, 6w oknie Properties. Przesuń go na podłoże blisko SpawnLocation i zaznacz Anchored, żeby się nie ruszał. - Najedź myszką na Pad, kliknij +, wstaw Script, nazwij go
TouchPadi wklej kod poniżej. - Kliknij Play i wejdź na platformę. Robi się żółta na 2 sekundy, a Output podaje twoje imię.
-- Script wewnątrz Part w Workspace o nazwie Pad, skrypt o nazwie TouchPad.
-- Eventy: gdy gracz wejdzie na platformę, świeci na żółto, a Output mówi, kto to był.
-- Debounce sprawia, że nie odpala się wiele razy na sekundę, gdy gracz na niej stoi.
local Players = game:GetService("Players")
local pad = script.Parent :: BasePart
local COOLDOWN_SECONDS = 2
local normalColour = pad.Color
local busy = false
local function onTouched(otherPart: BasePart)
if busy then
return -- nadal czeka po ostatnim dotknięciu
end
-- Postać to Model, który zawiera część ciała (albo czapkę), która dotknęła
local character = otherPart:FindFirstAncestorOfClass("Model")
local player = character and Players:GetPlayerFromCharacter(character)
if not player then
return -- dotknął jej luźny part albo NPC, a nie gracz
end
busy = true
print(`{player.Name} stepped on the pad`)
pad.Color = Color3.fromRGB(255, 220, 0)
task.wait(COOLDOWN_SECONDS)
pad.Color = normalColour
busy = false
end
pad.Touched:Connect(onTouched)
| Kod | Co robi |
|---|---|
pad.Touched:Connect(onTouched) | Podłącza funkcję do eventu Touched platformy, więc Roblox uruchamia onTouched za każdym razem, gdy coś jej dotknie, i przekazuje jej part, który dotknął. |
otherPart | Part, który dotknął platformy: stopa, noga, uchwyt czapki albo narzędzie, które trzyma gracz. To nigdy nie jest sam gracz, więc dwie kolejne linie ustalają, czyj to part. |
otherPart:FindFirstAncestorOfClass("Model") | Idzie w górę od tego partu do pierwszego przodka, którego klasa to dokładnie Model, czyli do postaci. Ponieważ nazwa klasy musi się zgadzać dokładnie, pomija czapkę (klasa Accessory) i narzędzie w ręce (klasa Tool). |
Players:GetPlayerFromCharacter(character) | Zwraca Playera, do którego ten model należy jako postać, albo nil, jeśli to niczyja postać, na przykład NPC. character and na początku pomija wywołanie, gdy nie znaleziono żadnego modelu, co zostawia player jako nil. |
if not player then return end | Zatrzymuje się tutaj dla wszystkiego, co nie jest graczem. return wychodzi z funkcji wcześniej. |
Dlaczego platforma potrzebuje debounce
Strona Roblox o debounce ostrzega, że Touched odpala się kilka razy bardzo szybko, gdy party się stykają, a idąca postać ma kilka części ciała. Bez sprawdzenia jeden krok na platformie mógłby wypisać wiele linii i w kółko restartować żółte świecenie.
Zmienna busy to debounce. Pierwsze dotknięcie ustawia ją na true, a każde dotknięcie w ciągu kolejnych 2 sekund trafia na if busy then return end i się zatrzymuje. Po task.wait(COOLDOWN_SECONDS) platforma wraca do swojego koloru, a busy wraca na false. COOLDOWN_SECONDS jest pisane wielkimi literami, bo to ustawienie, które nie zmienia się w trakcie gry, zgodnie z konwencją, którą Roblox sugeruje dla stałych.
Ta platforma ma jeden debounce dla wszystkich, więc drugi gracz, który na nią wejdzie w ciągu tych 2 sekund, zostanie zignorowany. Dla świecącej platformy to w porządku. Platforma, która daje nagrody, powinna mieć osobny czas oczekiwania dla każdego gracza, tak jak platforma z monetami w poradniku o tabeli wyników (po angielsku).
Krok 4: twój pierwszy LocalScript i czym się różni
Działająca gra to serwer plus jeden klient na każdego gracza. Wszystko wcześniej było Scriptem, który działa na serwerze, więc jego zmiany docierają do wszystkich graczy. LocalScript natomiast działa na urządzeniu jednego gracza. Naciśnięcia klawiszy, kamera i menu na ekranie są obsługiwane właśnie tam, bo tylko to urządzenie o nich wie.
- W Explorerze rozwiń StarterPlayer, najedź myszką na StarterPlayerScripts, kliknij + i wstaw LocalScript. Nazwij go
MyFirstLocalScripti wklej kod poniżej. - Kliknij Play. Output pokazuje
Hello,i twoje imię, z etykietą Client. - Kliknij w widok gry i naciśnij E. Platforma blednie. Naciśnij E jeszcze raz, żeby ją przywrócić.
- Gdy test nadal trwa, kliknij przełącznik Client/Server w kontrolkach testu Studio, żeby przejść do serwerowej kopii gry. Tam platforma jest pełna: serwer nigdy nie dowiedział się o zmianie.
-- LocalScript w StarterPlayer > StarterPlayerScripts o nazwie MyFirstLocalScript.
-- LocalScript działa na urządzeniu jednego gracza. Naciśnij E: Pad blednie tylko na twoim
-- ekranie, bo zmiana partu zrobiona tutaj nie dociera do serwera ani do nikogo innego.
local Players = game:GetService("Players")
local UserInputService = game:GetService("UserInputService")
local player = Players.LocalPlayer
print(`Hello, {player.Name}`) -- pojawia się w Output, oznaczone jako Client
UserInputService.InputBegan:Connect(function(input: InputObject, gameProcessed: boolean)
if gameProcessed then
return -- klawisz został użyty do czegoś innego, na przykład pisania na czacie
end
if input.KeyCode == Enum.KeyCode.E then
local pad = workspace:FindFirstChild("Pad")
if pad and pad:IsA("BasePart") then
pad.Transparency = if pad.Transparency == 0 then 0.6 else 0
end
end
end)
Players.LocalPlayerto gracz, na którego urządzeniu działa skrypt. Roblox ustawia go tylko dla LocalScriptów i ModuleScriptów, które one wymagają przez require, więc kod serwera nie może go używać.UserInputService.InputBeganodpala się, gdy gracz zaczyna naciskać klawisz, klikać albo dotykać ekranu.gameProcessedma wartośćtrue, gdy silnik już użył tego wejścia, na przykład kliknięcia przycisku albo klawisza wpisanego na pasku czatu, więc skrypt je ignoruje.workspace:FindFirstChild("Pad")zwraca dziecko o nazwie Pad albonil, jeśli go nie ma.pad:IsA("BasePart")sprawdza, czy to naprawdę part, zanim skrypt zmieni jegoTransparency.if pad.Transparency == 0 then 0.6 else 0to wyrażenie if: wybiera jedną z dwóch wartości. Transparency 0 to pełna widoczność, a 1 to niewidzialność.- Skrypt sprintu pod Shift (po angielsku) to dobry drugi LocalScript: nasłuchuje klawisza i zmienia WalkSpeed twojej postaci.
| Typ | Działa na | Jego zmiany docierają do | Używaj do | Zwykle trafia do |
|---|---|---|---|---|
| Script | Serwerze | Wszystkich graczy | Zasad gry: monety, obrażenia, drzwi, rundy, zapis | ServerScriptService albo wewnątrz partu, gdy się uczysz |
| LocalScript | Urządzeniu jednego gracza | Tylko tego urządzenia, poza ruchem własnej postaci | Wejścia, kamery, menu na ekranie, efektów dla jednego gracza | StarterPlayerScripts albo StarterGui |
| ModuleScript | Stronie, która go wywołuje przez require() | Tego samego co skrypt, który go wymagał | Kodu współdzielonego przez kilka skryptów | ReplicatedStorage dla obu stron, ServerScriptService tylko dla serwera |
Co może zmienić oszust
Zakładaj, że oszust kontroluje wszystko na swoim urządzeniu. Może uruchamiać własne LocalScripty i zmieniać twoje, więc może sprawić, że platforma, albo cokolwiek innego, zblednie na jego ekranie. Tutaj to nieszkodliwe: zblednięcie jest tylko wizualne i zostaje na jego urządzeniu. Właśnie dlatego wszystko, co ważne, rozstrzyga Script na serwerze.
Script na serwerze też nie jest automatycznie bezpieczny. TouchPad działa na serwerze, ale urządzenie każdego gracza kontroluje fizykę jego własnej postaci, a dokumentacja bezpieczeństwa Roblox wymienia manipulowanie tym, kiedy odpala się Touched, albo blokowanie go, wśród rzeczy, które klient może robić z partami, które kontroluje. Dla świecącej platformy to bez znaczenia. Dla takiej, która płaci, sprawdzaj też coś, co serwer kontroluje sam, na przykład zasadę z poradnika o obby (po angielsku), że checkpointy liczą się tylko po kolei.
Krok 5: przetestuj cztery skrypty razem
- Wyczyść Output skrótem Ctrl+K (⌘K na Macu) i kliknij Play (F5). Output pokazuje osiem linii FirstScript z etykietą Server i twoją linię Hello z etykietą Client. Part z ColourChanger zmienia kolor co sekundę.
- Wejdź na platformę. Robi się żółta na 2 sekundy, a Output pokazuje twoje imię i "stepped on the pad" jeden raz. Chodź dalej po niej: nowa linia pojawia się najwyżej raz na 2 sekundy, a nie przy każdym odpaleniu Touched.
- Naciśnij E. Platforma blednie do Transparency 0.6. Naciśnij E jeszcze raz i jest pełna.
- Kliknij Stop. W rozwijanej liście testów wybierz Server & Clients, ustaw 2 klientów i kliknij Play (albo F7). Studio otwiera okno serwera i dwa okna klientów. W jednym kliencie naciśnij E: platforma tam blednie, a drugi klient i serwer dalej widzą ją pełną. Na koniec kliknij End Session.
- Zepsuj coś celowo. Zmień nazwę Pad na
Pad2i zagraj. Wejście na nią dalej robi ją żółtą, bo TouchPad znajduje swój part przezscript.Parent, a nie po nazwie. Naciśnięcie E teraz nic nie robi i nie ma błędu:FindFirstChild("Pad")zwróciłonil, a sprawdzenieif pad and ...po cichu pominęło resztę. Dodajprint(pad)w linii poFindFirstChild, zagraj i naciśnij E: Output pokazujenil. Taki print to najszybszy sposób, żeby sprawdzić, dlaczego skrypt nic nie robi. Kliknij Stop, usuń linię z printem i przywróć partowi nazwę Pad.
Gdzie trafiają skrypty
To, gdzie jest skrypt, decyduje, czy w ogóle się uruchomi, a Studio nie ostrzega cię, gdy nigdy tego nie zrobi. Dla skryptów, które napiszesz dalej:
| Kontener | Umieść tu | Dlaczego |
|---|---|---|
| ServerScriptService | Scripty z większością zasad twojej gry: nagrody, rundy, zapis | Działają na serwerze, a nic z ServerScriptService nie jest wysyłane do graczy. |
| Wewnątrz partu w Workspace | Script, który należy do tego partu, jak ColourChanger i TouchPad | W porządku, gdy się uczysz: part to script.Parent. W prawdziwych projektach Roblox radzi tagować party (zobacz niżej). |
| StarterPlayerScripts, wewnątrz StarterPlayer | Większość LocalScriptów: wejście, kamera, efekty dla jednego gracza | Każdy gracz dostaje własną kopię przy dołączeniu. |
| StarterGui | LocalScripty w ScreenGui, które obsługują menu na ekranie | Każdy gracz dostaje własną kopię interfejsu. |
| ReplicatedStorage | ModuleScripty wymagane zarówno przez kod serwera, jak i klienta | Obie strony go widzą. LocalScript albo Script z domyślnymi ustawieniami umieszczony tutaj nigdy się nie uruchomi. |
Strona Roblox o lokalizacjach skryptów odradza wkładanie skryptów bezpośrednio do partów w Workspace: otaguj party i obsługuj je z jednego ModuleScriptu przez CollectionService. Skrypt w parcie to nadal najłatwiejszy sposób na start i wystarczy dla jednego czy dwóch obiektów, gdy się uczysz. Poradnik o drzwiach pokazuje wzorzec z tagami, z jednym skryptem dla wszystkich drzwi, a poradnik o kliencie i serwerze (oba po angielsku) ma pełną tabelę tego, które kontenery uruchamiają które skrypty.
Gdy coś pójdzie nie tak: czytaj Output
Błędy pojawiają się w Output na czerwono. Każdy zaczyna się od miejsca, w którym wystąpił, czyli pełnej nazwy skryptu i numeru linii, a potem mówi, co poszło nie tak. Kliknij błąd, a Studio otworzy ten skrypt w tej linii. Na przykład gdybyś usunął z TouchPad sprawdzenie if not player, a na platformę spadłby luźny part, Output pokazałby:
Workspace.Pad.TouchPad:22: attempt to index nil with 'Name'
Błędy w zapisie kodu, takie jak brakujący end, pojawiają się przed kliknięciem Play: Script Editor podkreśla je na czerwono, a okno Script Analysis (przycisk Analysis w zakładce Script) je wymienia. Skrypt z takim błędem w ogóle się nie uruchamia, nawet linie przed nim.
| Komunikat | Co oznacza | Rozwiązanie |
|---|---|---|
Colour is not a valid member of Part "Workspace.Part" | Na tym obiekcie nie ma niczego o dokładnie takiej nazwie. Tutaj właściwość pisze się Color. | Skopiuj pisownię i wielkość liter z okna Properties albo z Explorera. Więcej o tym błędzie. |
attempt to index nil with 'Name' | Kod odczytał coś, tutaj .Name, z wartości, która była nil. W przykładzie wyżej player był nil, bo platformy dotknął luźny part. | Ustal, dlaczego wartość to nil, i sprawdź ją przez if, zanim jej użyjesz. Więcej o tym błędzie. |
Expected 'end' (to close 'then' at line 2), got <eof> | if w linii 2 nie ma swojego end. Dla funkcji komunikat mówi to close 'function', a <eof> oznacza koniec pliku. | Dodaj brakujący end, patrząc na linię podaną w nawiasie, a nie na ostatnią. Czasem komunikat kończy się na "did you forget to close ... at line N?". Ta część to zgadywanie Luau na podstawie twoich wcięć i może wskazywać zły blok, więc najpierw sprawdź linię z nawiasu. Więcej o błędach składni. |
Gdy skrypt nic nie robi, a Output też nic nie pokazuje, zwykle jest w miejscu, w którym nigdy się nie uruchamia, albo czeka na event, który nigdy nie zachodzi. Poradnik o błędach w skryptach (po angielsku) ma listę dla cichych skryptów i omawia dokładniej, jak czytać Output.
Co starsze poradniki skryptowania robią inaczej
Jeśli uczysz się też z filmów i postów na forach, natrafisz na stare wzorce. Oto te, które mają znaczenie, z powodem, dla którego każdy jest problemem.
| Poradnik | Problem | Ten poradnik |
|---|---|---|
Robi przerwy przez wait(1) | Dokumentacja Roblox oznacza globalne wait() jako przestarzałe i mówi, że zastąpiło je task.wait(). | task.wait(1) |
Znajduje postać przez otherPart.Parent, tak jak własna lekcja Roblox o lawie | Gdy part dotknie czapka albo narzędzie w ręce, otherPart.Parent to Accessory albo Tool, a nie postać, więc nie znajduje się żaden Humanoid i to dotknięcie przepada. | FindFirstAncestorOfClass("Model"), a potem GetPlayerFromCharacter |
Używa Touched bez debounce | Touched odpala się kilka razy bardzo szybko przy jednym kroku, więc kod uruchamia się w kółko. | Zmienna busy i czas oczekiwania |
| Wkłada LocalScript do partu w Workspace | Tam LocalScript nigdy się nie uruchamia. Działa tylko z miejsc, które należą do gracza. | LocalScripty w StarterPlayerScripts (dlaczego) |
Pisze part.Touched:connect(...) albo table.getn(list) | Poradnik Roblox o nazewnictwie mówi, że API w camelCase są w większości przestarzałe, a dokumentacja wymienia tylko Connect. table.getn jest przestarzałe na rzecz #list. | :Connect(...) i #list |
| Zmienia monety albo zadaje obrażenia w LocalScripcie | Zmiana zostaje na urządzeniu tego gracza, więc nikt inny jej nie widzi, a serwer nigdy jej nie liczy. | Zasady gry w Scriptach na serwerze |
Ćwiczenia: trzy zmiany do wypróbowania
Zmienianie kodu uczy więcej niż czytanie go. Wypróbuj te zmiany we własnej grze, po jednej, i po każdej kliknij Play.
- Niech platforma daje punkt. Dodaj skrypt Leaderstats z kroku 1 poradnika o tabeli wyników (po angielsku). Potem w TouchPad, po
busy = true, znajdź folderleaderstatsgracza i dodaj 1 do jego wartościCoins. Podpowiedź:player:FindFirstChild("leaderstats"), potemleaderstats:FindFirstChild("Coins"), potemcoins.Value += 1. Platforma z monetami w poradniku o tabeli wyników to gotowa wersja, z czasem oczekiwania dla każdego gracza. - Niech zmieniacz kolorów też blednie. Niech ColourChanger co sekundę zmienia też
Transparencypartu. Podpowiedź: dodaj drugą tabelę z liczbami od 0 do 1, na przykład{ 0, 0.3, 0.6 }, i ustawiaj z niejpart.Transparencyw linii popart.Color, używając tego samegoindex. - Wypisz kolor platformy. Niech MyFirstLocalScript wypisuje
Colorplatformy, gdy naciśniesz E. Podpowiedź:print(pad.Color)wewnątrz blokuif pad and pad:IsA("BasePart"). Naciśnij E, gdy platforma jest żółta: klient widzi kolor ustawiony przez serwer, bo zmiany zrobione na serwerze docierają do wszystkich klientów.
Czego uczyć się dalej
Użyłeś już elementów, z których zbudowana jest większość skryptów w grach. Dobra kolejność na dalej:
- LocalScript vs Script vs ModuleScript: gdzie działa każdy typ skryptu i co może zmieniać, dokładniej niż w kroku 4.
- RemoteEvents: jak LocalScript prosi serwer o zrobienie czegoś i jak serwer sprawdza tę prośbę.
- Tabela wyników: twoje pierwsze statystyki, tworzone i zmieniane na serwerze.
- Twoja pierwsza gra: krótki tor z lawą, monetami i metą, napędzany dwoma skryptami serwera, a potem opublikowany.
- Potem wybierz system do dodania: sklep z GUI, system rund, checkpointy w obby, ekran ładowania albo animację po naciśnięciu klawisza. Gdy coś się zepsuje, poradnik o błędach w skryptach pomoże ci przeczytać komunikat. Te poradniki są po angielsku.
Poradniki Coding fundamentals od Roblox (po angielsku) to dobre uzupełnienie: sześć serii, od zmiennych i funkcji przez warunki, pętle, tablice i słowniki aż po porządkowanie kodu w ModuleScriptach, z małymi projektami do zbudowania w Studio.
Częste błędy i rozwiązania
Większość problemów z pierwszym skryptem to niezgodna nazwa, skrypt w złym miejscu albo pętla bez czekania. Zostaw Output otwarty podczas testów.
Studio zamraża się albo przestaje odpowiadać po kliknięciu Play
Pętla while true do nie ma w środku żadnego czekania, więc nic innego nie może się uruchomić. Dokumentacja Roblox mówi, że nieskończona pętla bez przerwy, takiej jak task.wait(), zamraża grę i zawiesza Studio. Wstaw task.wait() do każdej pętli, która powtarza się w nieskończoność, tak jak robi ColourChanger.
Nic się nie dzieje, gdy wchodzę na platformę
Sprawdź, czy TouchPad to Script, a nie LocalScript, bezpośrednio w parcie Pad, czy nie jest wyłączony i czy właściwość CanTouch platformy jest zaznaczona. Potem wstaw print("touched", otherPart.Name) jako pierwszą linię w onTouched. Jeśli nigdy się nie wypisuje, event nie odpala; jeśli się wypisuje, problem jest niżej.
Naciśnięcie E nic nie robi
MyFirstLocalScript musi być LocalScriptem w StarterPlayerScripts: LocalScript w Workspace albo w ServerScriptService nigdy się nie uruchamia. Part musi nazywać się dokładnie Pad i być bezpośrednio w Workspace. Najpierw kliknij w widok gry i upewnij się, że nie piszesz na czacie, bo skrypt ignoruje klawisze, których gra już użyła.
Part zmienia się na moim ekranie, ale nie dla innych graczy
Zmiana została zrobiona w LocalScripcie, więc została na twoim urządzeniu. Zrób ją w Scripcie na serwerze albo niech LocalScript poprosi o nią serwer przez RemoteEvent.
ColourChanger działa w parcie, ale nie działa w ServerScriptService
Używa script.Parent jako swojego partu. W ServerScriptService rodzicem jest ServerScriptService, który nie ma Anchored ani Color, więc Output pokazuje błąd "not a valid member". Zostaw go w parcie albo nadaj partowi nazwę i znajdź go po niej, na przykład local part = workspace:WaitForChild("ColourPart") :: BasePart.
Output nic nie pokazuje
Sprawdź, czy okno Output jest otwarte (menu Window albo zakładka Script) i czy nie ma żadnego filtra: Output można filtrować po typie komunikatu, po Client lub Server i po tekście. Jeśli jest otwarte i nadal puste, skrypt prawdopodobnie nigdy się nie uruchomił. Zajrzyj na listę dla skryptów, które nic nie robią (po angielsku).
Odblokuj się z RoCode
Jeśli utkniesz przy skrypcie we własnej grze, RoCode może przeczytać go razem z tobą. RoCode to niezależny agent AI do Roblox Studio, nie robi go Roblox: piszesz na czacie w przeglądarce, a jego plugin do Studio tworzy i edytuje skrypty w twoim Explorerze.
Podczas nauki przydatny jest tryb Ask: skrypty dalej piszesz ty, a RoCode czyta to, co już jest, i odpowiada na twoje pytania.
Wyjaśnij mi linijka po linijce, co robi skrypt TouchPad w parcie Pad, i powiedz, dlaczego używa debounce.
- W trybie Ask używa tylko narzędzi do odczytu, takich jak Search Scripts i Read Script, i niczego w grze nie zmienia
- Jeśli coś wymaga poprawki, mówi, co by zmienił i gdzie, i sugeruje przejście na Build
- W Build edytuje skrypty na miejscu i sprawdza przez Check Script, czy każdy się kompiluje. To sprawdzenie kompilacji, a nie typów ani test gry
- Czyta Output Studio swoim narzędziem Check Output, w tym linie Server i Client z twojego ostatniego testu, nawet po kliknięciu Stop
W trybie Build z pluginem 3.9 lub nowszym RoCode może zrobić krótki test i przeczytać błędy, a z pluginem 3.9.11 lub nowszym sterować postacią testową, żeby sprawdzić, czy gra działa, ale nie robi zrzutów ekranu podczas działania gry, więc na platformę dalej wchodzisz ty. Jak RoCode łączy się ze Studio.
Najczęstsze pytania
Gdzie piszę skrypty w Roblox Studio?
W Explorerze najedź myszką na kontener, na przykład ServerScriptService, kliknij przycisk + i wybierz Script. Studio otworzy go w Script Editorze, w którym piszesz Luau. Skrypty serwera zwykle trafiają do ServerScriptService; LocalScripty do StarterPlayerScripts albo StarterGui.
Jak uruchomić skrypt w Roblox Studio?
Kliknij Play (F5). Studio zaczyna test, a każdy włączony Script w ServerScriptService lub Workspace uruchamia się, gdy tylko gra wystartuje; LocalScripty w StarterPlayerScripts uruchamiają się, gdy wejdziesz do testu. Run (wybierz go z rozwijanej listy obok Play albo naciśnij F8) uruchamia grę bez twojego awatara, więc w tym poradniku używaj Play. Kliknij Stop (Shift+F5), żeby zakończyć test. Żeby otworzyć istniejący skrypt, kliknij go dwukrotnie w Explorerze.
Jakiego języka programowania używa Roblox?
Luau. Roblox opisuje go jako szybki, mały, bezpieczny język skryptowy ze stopniowym typowaniem, wywodzący się z Lua 5.1, więc większość poradników do Lua nadal się przydaje. Luau dodaje funkcje takie jak interpolacja stringów w odwrotnych apostrofach i opcjonalne adnotacje typów, a Roblox dodaje własne biblioteki i obiekty, na przykład task.wait.
Czym różni się Script od LocalScriptu?
Script działa na serwerze, a jego zmiany docierają do wszystkich graczy. LocalScript działa na urządzeniu jednego gracza, do rzeczy takich jak wejście, kamera i menu na ekranie, a jego zmiany w partach, wartościach i interfejsie zostają na tym urządzeniu. Poradnik o kliencie i serwerze (po angielsku) omawia oba, plus ModuleScripty.
Czy mogę skryptować w Roblox Studio na telefonie albo iPadzie?
Strona konfiguracji Roblox opisuje Studio jako darmową aplikację na Windowsa i Maca i nie podaje żadnej wersji na telefon ani tablet, więc do pisania skryptów potrzebujesz komputera.
Dlaczego mój skrypt nic nie robi i nie pokazuje żadnego błędu?
Zwykle jest w miejscu, w którym ten typ skryptu się nie uruchamia (LocalScript w Workspace albo Script w StarterPlayerScripts), jest wyłączony albo event, na który czeka, nigdy nie zachodzi. Poradnik o błędach w skryptach ma listę kontrolną (po angielsku).
Ile trwa nauka skryptowania w Roblox?
Nikt nie poda ci uczciwej liczby: to zależy od tego, ile budujesz. Najbardziej pomaga częste pisanie małych skryptów we własnej grze. Pozmieniaj cztery skrypty stąd, spróbuj ćwiczeń, potem przejdź poradnik o twojej pierwszej grze i dodawaj po jednym systemie.
Źródła i dalsza lektura
- Roblox Creator Docs: Luau (po angielsku). czym jest Luau i skąd się wziął
- Roblox Creator Docs: Roblox Studio setup (po angielsku). Windows i Mac oraz wymagania systemowe
- Roblox Creator Docs: Output (po angielsku). otwieranie Output, filtry, Show Context i Show Source
- Roblox Creator Docs: Studio testing modes (po angielsku). Play, Run, Stop, przełącznik Client/Server i Server & Clients
- Roblox Creator Docs: Script Editor (po angielsku). gdzie otwierają się nowe skrypty i Script Analysis
- Roblox Creator Docs: Script types and locations (po angielsku). gdzie działa każdy typ skryptu i tagowanie partów zamiast wkładania do nich skryptów
- Roblox Creator Docs: Script (po angielsku). kiedy Script zaczyna działać
- Roblox Creator Docs: Control structures (po angielsku). instrukcje if, pętle i dlaczego nieskończona pętla potrzebuje czekania
- Roblox Creator Docs: Events (po angielsku). Connect i to, co Touched przekazuje twojej funkcji
- Roblox Creator Docs: Debounce patterns (po angielsku). dlaczego Touched odpala się kilka razy przy jednym kontakcie
- Roblox Creator Docs: wait (po angielsku). globalne wait() i task.wait()
- Roblox Creator Docs: Network ownership, movement validation and physics exploits (po angielsku). co klient może robić z własną postacią
- Roblox Creator Docs: Coding fundamentals (po angielsku). seria Roblox dla początkujących
Jak sprawdziliśmy kod: każdy skrypt na tej stronie przechodzi ścisłe sprawdzanie typów Luau z definicjami API Robloxa (luau-lsp, 26 października 2026). Sprawdzanie typów wyłapuje źle wpisane API i błędne typy, ale nie logikę gry, więc przetestuj go w Studio przed publikacją.