Criar jogos interativos frequentemente significa manipular propriedades e atributos de objetos:
Propriedades são parte da classe do objeto. Por exemplo, a propriedade BasePart.Anchored controla a física para a parte. Em um jogo de atletismo, você pode querer ancorar um disco ou dardo no instante em que aterrissa, para que os jogadores tenham um indicador visual de quão longe ele viajou.
Atributos são essencialmente propriedades personalizadas que você define. Por exemplo, o projeto de referência Plant usa atributos para definir o preço de compra de sementes e o tamanho máximo da planta que um vaso pode conter.
Ordem de replicação
Antes de começar a recuperar e manipular objetos, você deve ter uma compreensão da ordem de replicação.
O Motor Roblox não garante a ordem em que os objetos (e as mudanças nos objetos) são replicados do servidor para o cliente, o que torna o método Instance:WaitForChild() essencial para acessar objetos em scripts do cliente, particularmente objetos em Workspace.
Por exemplo, se um script do servidor alterar uma propriedade de alguma instância no Workspace e depois chamar RemoteEvent:FireAllClients(), a mudança de propriedade pode replicar para o cliente antes ou depois que RemoteEvent.OnClientEvent dispare. Use os métodos e eventos disponíveis para detectar mudanças em vez de assumir que uma mudança foi replicada. Mudanças do mesmo tipo, como duas alterações de atributo, geralmente chegam em ordem.
Quando os clientes lançam um jogo pela primeira vez, alguns aspectos da replicação e execução de scripts são previsíveis:
O cliente carrega o conteúdo de ReplicatedFirst, como uma tela de carregamento, ativos e scripts.
LocalScripts (e Scripts com um RunContext de Client) em ReplicatedFirst são executados. Esses scripts podem obter objetos de ReplicatedFirst sem usar Instance:WaitForChild():
-- Segurolocal ReplicatedFirst = game:GetService("ReplicatedFirst")local LoadingScreen = require(ReplicatedFirst.LoadingScreen)Esses scripts não podem obter objetos com segurança de outros serviços, porque eles podem não ter sido carregados ainda:
-- Não segurolocal ReplicatedStorage = game:GetService("ReplicatedStorage")local PickupManager = require(ReplicatedStorage.PickupManager)Você pode usar WaitForChild() nesses scripts para obter objetos de outros serviços, mas isso anula os benefícios de usar ReplicatedFirst.
O cliente continua carregando o restante do jogo.
Quando termina, o evento Loaded é acionado e IsLoaded() retorna verdadeiro.
LocalScripts em Players.[Player].PlayerScripts (copiados de StarterPlayerScripts) são executados, assim como os Scripts do cliente em ReplicatedStorage. Esses scripts podem obter objetos de ReplicatedStorage sem usar WaitForChild().
O modelo Character do jogador é gerado no jogo.
LocalScripts em Workspace.[Character] (copiados de StarterCharacterScripts) são executados.
Se o seu jogo usar streaming de instâncias (Workspace.StreamingEnabled), alguns ou a maioria dos objetos podem não ter sido carregados no workspace, então usar WaitForChild() para acessar objetos do workspace torna-se uma medida de segurança ainda mais importante. Em particular, veja stream in e controles de streaming por modelo para mais informações sobre como carregar e ajustar o comportamento de streaming.
Obter objetos
O primeiro passo para modificar propriedades e atributos de objetos é obter uma referência ao objeto. A solução mais simples é fazer o script ser um filho do objeto no Explorer e usar script.Parent para referenciar o objeto.

local sign = script.Parent
A solução mais universal é obter o objeto de um serviço usando métodos como Instance:FindFirstChild() ou Instance:WaitForChild().

local ReplicatedStorage = game:GetService("ReplicatedStorage")local signsFolder = ReplicatedStorage:WaitForChild("Signs")local sign = signsFolder:WaitForChild("InteractiveSign")
Modificar propriedades
Propriedades são acessíveis de forma direta — basta usar um . após a referência do objeto — embora, se você estiver trabalhando com um modelo, possa precisar escolher uma parte individual em vez do modelo em si.

local ReplicatedStorage = game:GetService("ReplicatedStorage")local chair = ReplicatedStorage:WaitForChild("Chair")chair.LeftArmRest.Size = Vector3.new(10, 1, 10)
Criar atributos
Embora você possa criar atributos programaticamente, a solução mais comum é criá-los com valores padrão na interface do usuário do Studio. Depois, você pode usar scripts para modificar seus valores em resposta a ações dos jogadores.

Para informações sobre como criar atributos no Studio, veja atributos de instância.
Definir atributos
Para modificar o valor de um atributo, chame Instance:SetAttribute() com um nome e valor.
Criar ou Modificar Atributolocal cabbage = script.Parentcabbage:SetAttribute("Harvestable", true)
Se o atributo ainda não existir, este método o cria.
Obter valores de atributos
Para obter o valor de um atributo existente, chame Instance:GetAttribute() na instância.
Obter Valor do Atributolocal cabbage = script.Parentcabbage:SetAttribute("Harvestable", true)local isHarvestable = cabbage:GetAttribute("Harvestable")print(isHarvestable) --> true
Da mesma forma, você pode obter todos os atributos chamando Instance:GetAttributes(). Este método retorna um dicionário de pares chave-valor.
Obter Todos os Atributoslocal cabbage = script.Parentlocal cabbageAttributes = cabbage:GetAttributes()print(cabbageAttributes.GrowthRate) --> 2for k, v in cabbageAttributes doprint(k, v)end
Deletar atributos
Para deletar um atributo, defina seu valor como nil.
Deletar Atributolocal cabbage = script.Parentcabbage:SetAttribute("GrowthRate", nil)
Detectar mudanças
Existem várias maneiras de ouvir mudanças de propriedades e atributos:
- O evento Instance.AttributeChanged ouve mudanças em qualquer atributo e passa o nome do atributo alterado como um parâmetro.
- O método Instance:GetPropertyChangedSignal() permite que você ouça mudanças em uma propriedade e não passa parâmetros.
- O método Instance:GetAttributeChangedSignal() permite que você ouça mudanças em um atributo e não passa parâmetros.
Devido à informação mínima que esses eventos e métodos passam como parâmetros, todos eles são adequados para funções anônimas, particularmente Instance:GetPropertyChangedSignal() e Instance:GetAttributeChangedSignal(). Para saber mais sobre funções anônimas e como trabalhar com eventos, veja Eventos.
Ouvir por Mudanças
local cabbage = script.Parent
-- Funções locais
local function onAnyPropertyChange(property)
-- Ignorar mudanças em atributos
if property ~= "Attributes" then
print(property) --> Nome
print(cabbage[property]) --> Cabbage1
end
end
local function onAnyAttributeChange(attribute)
print(attribute) --> Grow, GrowthRate
print(cabbage:GetAttribute(attribute)) --> false, 3
end
-- Ouvir por mudanças e conectar a funções locais
cabbage.Changed:Connect(onAnyPropertyChange)
cabbage.AttributeChanged:Connect(onAnyAttributeChange)
-- Ouvir por mudanças e conectar a funções anônimas
cabbage:GetPropertyChangedSignal("Name"):Connect(function()
print(cabbage.Name) --> Cabbage1
end)
cabbage:GetAttributeChangedSignal("GrowthRate"):Connect(function()
print(cabbage:GetAttribute("GrowthRate")) --> 3
end)
-- Dispara Changed e GetPropertyChangedSignal()
cabbage.Name = "Cabbage1"
-- Dispara Changed e AttributeChanged
cabbage:SetAttribute("Grow", false)
-- Dispara Changed, AttributeChanged e GetAttributeChangedSignal()
cabbage:SetAttribute("GrowthRate", 3)