Tworzenie interaktywnych gier często oznacza manipulowanie właściwościami i atrybutami obiektów:
Właściwości są częścią klasy obiektu. Na przykład, właściwość BasePart.Anchored kontroluje fizykę dla części. W grze lekkoatletycznej możesz chcieć zakotwić dysk lub oszczep w momencie, gdy wyląduje, aby gracze mieli wizualny wskaźnik, jak daleko się przemieścił.
Atrybuty to zasadniczo niestandardowe właściwości, które definiujesz. Na przykład projekt referencyjny Plant używa atrybutów do ustawienia ceny zakupu nasion oraz maksymalnego rozmiaru rośliny, jaki może pomieścić doniczka.
Kolejność replikacji
Zanim zaczniesz pobierać i manipulować obiektami, musisz zrozumieć kolejność replikacji.
Silnik Roblox nie gwarantuje kolejności, w jakiej obiekty (i zmiany obiektów) są replikowane z serwera do klienta, co sprawia, że metoda Instance:WaitForChild() jest niezbędna do uzyskiwania dostępu do obiektów w skryptach klienckich, szczególnie obiektów w Workspace.
Na przykład, jeśli skrypt serwera zmienia właściwość jakiejś instancji w Workspace, a następnie wywołuje RemoteEvent:FireAllClients(), zmiana właściwości może zreplikować się do klienta przed lub po tym, jak wywoła się RemoteEvent.OnClientEvent. Używaj dostępnych metod i zdarzeń, aby wykrywać zmiany, zamiast zakładać, że zmiana została zreplikowana. Zmiany tego samego typu, takie jak dwa zmiany atrybutów, zazwyczaj przybywają w kolejności.
Kiedy klienci po raz pierwszy uruchamiają grę, niektóre aspekty replikacji i wykonywania skryptów są przewidywalne:
Klient ładuje zawartość ReplicatedFirst, taką jak ekran ładowania, zasoby i skrypty.
LocalScripts (i Scripts z RunContext równym Client) w ReplicatedFirst jest uruchamiane. Te skrypty mogą bezpiecznie pobierać obiekty z ReplicatedFirst bez użycia Instance:WaitForChild():
-- Bezpiecznelocal ReplicatedFirst = game:GetService("ReplicatedFirst")local LoadingScreen = require(ReplicatedFirst.LoadingScreen)Te skrypty nie mogą bezpiecznie pobierać obiektów z innych usług, ponieważ mogą jeszcze nie być załadowane:
-- Niebezpiecznelocal ReplicatedStorage = game:GetService("ReplicatedStorage")local PickupManager = require(ReplicatedStorage.PickupManager)Możesz użyć WaitForChild() w tych skryptach, aby uzyskać obiekty z innych usług, ale robiąc to, negujesz korzyści płynące z użycia ReplicatedFirst.
Klient kontynuuje ładowanie reszty gry.
Gdy zakończy, zdarzenie Loaded się uruchamia, a IsLoaded() zwraca true.
LocalScripts w Players.[Player].PlayerScripts (skopiowane z StarterPlayerScripts) uruchamiają się, a także skrypty klienckie Scripts w ReplicatedStorage. Te skrypty mogą bezpiecznie pobierać obiekty z ReplicatedStorage bez użycia WaitForChild().
Model Character gracza spawnuje się w grze.
LocalScripts w Workspace.[Character] (skopiowane z StarterCharacterScripts) uruchamiają się.
Jeśli twoja gra używa streaming instancji (Workspace.StreamingEnabled), niektóre lub większość obiektów może nie być załadowana do workspace, więc użycie WaitForChild() do uzyskania dostępu do obiektów workspace staje się jeszcze ważniejszym środkiem bezpieczeństwa. W szczególności, zobacz stream in oraz sterowanie streamingiem per-model dla dodatkowych informacji na temat ładowania i dostosowywania zachowania streamingu.
Pobierz obiekty
Pierwszym krokiem do modyfikacji właściwości i atrybutów obiektów jest uzyskanie odniesienia do obiektu. Najprostsze rozwiązanie to uczynić skrypt dzieckiem obiektu w Eksploratorze i użyć script.Parent, aby odwołać się do obiektu.

local sign = script.Parent
Bardziej uniwersalnym rozwiązaniem jest pobranie obiektu z usługi za pomocą metod takich jak Instance:FindFirstChild() lub Instance:WaitForChild().

local ReplicatedStorage = game:GetService("ReplicatedStorage")local signsFolder = ReplicatedStorage:WaitForChild("Signs")local sign = signsFolder:WaitForChild("InteractiveSign")
Modyfikuj właściwości
Właściwości są łatwe do uzyskania – po prostu użyj . po odniesieniu do obiektu — chociaż jeśli pracujesz z modelem, możesz potrzebować wybrać indywidualną część, a nie model.

local ReplicatedStorage = game:GetService("ReplicatedStorage")local chair = ReplicatedStorage:WaitForChild("Chair")chair.LeftArmRest.Size = Vector3.new(10, 1, 10)
Twórz atrybuty
Chociaż możesz programowo tworzyć atrybuty, bardziej powszechnym rozwiązaniem jest ich tworzenie z domyślnymi wartościami w interfejsie użytkownika Studio. Następnie możesz używać skryptów do modyfikacji ich wartości w odpowiedzi na działania graczy.

Aby uzyskać informacje na temat tworzenia atrybutów w Studio, zobacz atrybuty instancji.
Ustaw atrybuty
Aby zmodyfikować wartość atrybutu, wywołaj Instance:SetAttribute() z nazwą i wartością.
Utwórz lub Modyfikuj Atrybutlocal cabbage = script.Parentcabbage:SetAttribute("Harvestable", true)
Jeśli atrybut już nie istnieje, ta metoda go tworzy.
Pobierz wartości atrybutów
Aby uzyskać wartość jednego istniejącego atrybutu, wywołaj Instance:GetAttribute() na instancji.
Pobierz Wartość Atrybutulocal cabbage = script.Parentcabbage:SetAttribute("Harvestable", true)local isHarvestable = cabbage:GetAttribute("Harvestable")print(isHarvestable) --> true
Podobnie możesz uzyskać wszystkie atrybuty, wywołując Instance:GetAttributes(). Ta metoda zwraca słownik par klucz-wartość.
Pobierz Wszystkie Atrybutylocal cabbage = script.Parentlocal cabbageAttributes = cabbage:GetAttributes()print(cabbageAttributes.GrowthRate) --> 2for k, v in cabbageAttributes doprint(k, v)end
Usuń atrybuty
Aby usunąć atrybut, ustaw jego wartość na nil.
Usuń Atrybutlocal cabbage = script.Parentcabbage:SetAttribute("GrowthRate", nil)
Wykryj zmiany
Jest kilka sposobów, aby nasłuchiwać zmian właściwości i atrybutów:
- Zdarzenie Instance.AttributeChanged nasłuchuje zmian jakiegokolwiek atrybutu i przekazuje nazwę zmienionego atrybutu jako parametr.
- Metoda Instance:GetPropertyChangedSignal() pozwala nasłuchiwać zmian jednej właściwości i nie przekazuje żadnych parametrów.
- Metoda Instance:GetAttributeChangedSignal() pozwala nasłuchiwać zmian jednego atrybutu i nie przekazuje żadnych parametrów.
Ze względu na minimalną ilość informacji, które te zdarzenia i metody przekazują jako parametry, wszystkie z nich dobrze pasują do anonimowych funkcji, szczególnie Instance:GetPropertyChangedSignal() i Instance:GetAttributeChangedSignal(). Aby dowiedzieć się więcej o funkcjach anonimowych i pracy z zdarzeniami, zobacz Zdarzenia.
Nasłuchuj Zmian
local cabbage = script.Parent
-- Funkcje lokalne
local function onAnyPropertyChange(property)
-- Ignoruj zmiany atrybutów
if property ~= "Attributes" then
print(property) --> Name
print(cabbage[property]) --> Cabbage1
end
end
local function onAnyAttributeChange(attribute)
print(attribute) --> Grow, GrowthRate
print(cabbage:GetAttribute(attribute)) --> false, 3
end
-- Nasłuchuj zmian i podłącz do funkcji lokalnych
cabbage.Changed:Connect(onAnyPropertyChange)
cabbage.AttributeChanged:Connect(onAnyAttributeChange)
-- Nasłuchuj zmian i podłącz do anonimowych funkcji
cabbage:GetPropertyChangedSignal("Name"):Connect(function()
print(cabbage.Name) --> Cabbage1
end)
cabbage:GetAttributeChangedSignal("GrowthRate"):Connect(function()
print(cabbage:GetAttribute("GrowthRate")) --> 3
end)
-- Wywołuje Changed i GetPropertyChangedSignal()
cabbage.Name = "Cabbage1"
-- Wywołuje Changed i AttributeChanged
cabbage:SetAttribute("Grow", false)
-- Wywołuje Changed, AttributeChanged i GetAttributeChangedSignal()
cabbage:SetAttribute("GrowthRate", 3)