Hacer que los juegos sean interactivos a menudo significa manipular propiedades y atributos de objetos:
Las propiedades son parte de la clase de objetos. Por ejemplo, la propiedad BasePart.Anchored controla la física para la parte. En un juego de atletismo, es posible que desees anclar un disco o jabalina en el instante en que aterriza para que los jugadores tengan un indicador visual de cuánto ha viajado.
Los atributos son esencialmente propiedades personalizadas que tú defines. Por ejemplo, el proyecto de referencia Plant utiliza atributos para establecer el precio de compra de las semillas y el tamaño máximo que una maceta puede contener.
Orden de replicación
Antes de comenzar a recuperar y manipular objetos, debes entender el orden de replicación.
El motor de Roblox no garantiza el orden en que los objetos (y los cambios en los objetos) se replican del servidor al cliente, lo que hace que el método Instance:WaitForChild() sea esencial para acceder a objetos en scripts del cliente, particularmente objetos en Workspace.
Por ejemplo, si un script del servidor cambia una propiedad de alguna instancia en el Workspace y luego llama a RemoteEvent:FireAllClients(), el cambio de propiedad podría replicarse al cliente antes o después de que se dispare RemoteEvent.OnClientEvent. Utiliza los métodos y eventos disponibles para detectar cambios en lugar de asumir que un cambio se ha replicado. Los cambios del mismo tipo, como dos cambios de atributo, generalmente sí llegan en orden.
Cuando los clientes lanzan un juego por primera vez, algunos aspectos de la replicación y la ejecución de scripts son predecibles:
El cliente carga el contenido de ReplicatedFirst, como una pantalla de carga, activos y scripts.
Los LocalScripts (y Scripts con un RunContext de Client) en ReplicatedFirst se ejecutan. Estos scripts pueden obtener de forma segura objetos de ReplicatedFirst sin usar Instance:WaitForChild():
-- Segurolocal ReplicatedFirst = game:GetService("ReplicatedFirst")local LoadingScreen = require(ReplicatedFirst.LoadingScreen)Estos scripts no pueden obtener de forma segura objetos de otros servicios, porque podrían no haberse cargado aún:
-- No segurolocal ReplicatedStorage = game:GetService("ReplicatedStorage")local PickupManager = require(ReplicatedStorage.PickupManager)Puedes utilizar WaitForChild() en estos scripts para obtener objetos de otros servicios, pero hacerlo anula los beneficios de usar ReplicatedFirst.
El cliente continúa cargando el resto del juego.
Cuando termina, se dispara el evento Loaded y IsLoaded() devuelve verdadero.
Los LocalScripts en Players.[Player].PlayerScripts (copiados de StarterPlayerScripts) se ejecutan, así como los Scripts del cliente en ReplicatedStorage. Estos scripts pueden obtener de forma segura objetos de ReplicatedStorage sin usar WaitForChild().
El modelo Character del jugador aparece en el juego.
Los LocalScripts en Workspace.[Character] (copiados de StarterCharacterScripts) se ejecutan.
Si tu juego utiliza streaming de instancias (Workspace.StreamingEnabled), algunos o la mayoría de los objetos pueden no haberse cargado en el espacio de trabajo, por lo que usar WaitForChild() para acceder a objetos del espacio de trabajo se convierte en una medida de seguridad aún más importante. En particular, consulta stream in y controles de streaming por modelo para información adicional sobre la carga y ajuste del comportamiento de streaming.
Obtener objetos
El primer paso para modificar las propiedades y atributos de un objeto es obtener una referencia al objeto. La solución más simple es hacer que el script sea un hijo del objeto en el Explorer y usar script.Parent para hacer referencia al objeto.

local sign = script.Parent
La solución más universal es obtener el objeto de un servicio utilizando métodos como Instance:FindFirstChild() o Instance:WaitForChild().

local ReplicatedStorage = game:GetService("ReplicatedStorage")local signsFolder = ReplicatedStorage:WaitForChild("Signs")local sign = signsFolder:WaitForChild("InteractiveSign")
Modificar propiedades
Las propiedades son sencillas de acceder: solo usa un . después de la referencia del objeto — aunque si estás trabajando con un modelo, es posible que necesites elegir una parte individual en lugar del modelo mismo.

local ReplicatedStorage = game:GetService("ReplicatedStorage")local chair = ReplicatedStorage:WaitForChild("Chair")chair.LeftArmRest.Size = Vector3.new(10, 1, 10)
Crear atributos
Aunque puedes crear atributos programáticamente, la solución más común es crearlos con valores predeterminados en la interfaz de usuario de Studio. Luego puedes usar scripts para modificar sus valores en respuesta a las acciones del jugador.

Para obtener información sobre cómo crear atributos en Studio, consulta atributos de instancias.
Establecer atributos
Para modificar el valor de un atributo, llama a Instance:SetAttribute() con un nombre y un valor.
Crear o Modificar Atributolocal cabbage = script.Parentcabbage:SetAttribute("Harvestable", true)
Si el atributo no existe ya, este método lo crea.
Obtener valores de atributo
Para obtener el valor de un atributo existente, llama a Instance:GetAttribute() en la instancia.
Obtener Valor del Atributolocal cabbage = script.Parentcabbage:SetAttribute("Harvestable", true)local isHarvestable = cabbage:GetAttribute("Harvestable")print(isHarvestable) --> true
De manera similar, puedes obtener todos los atributos llamando a Instance:GetAttributes(). Este método devuelve un diccionario de pares clave-valor.
Obtener Todos los Atributoslocal cabbage = script.Parentlocal cabbageAttributes = cabbage:GetAttributes()print(cabbageAttributes.GrowthRate) --> 2for k, v in cabbageAttributes doprint(k, v)end
Eliminar atributos
Para eliminar un atributo, establece su valor en nil.
Eliminar Atributolocal cabbage = script.Parentcabbage:SetAttribute("GrowthRate", nil)
Detectar cambios
Hay varias formas de escuchar cambios en propiedades y atributos:
- El evento Instance.AttributeChanged escucha cambios en cualquier atributo y pasa el nombre del atributo cambiado como parámetro.
- El método Instance:GetPropertyChangedSignal() te permite escuchar cambios en una propiedad y no pasa parámetros.
- El método Instance:GetAttributeChangedSignal() te permite escuchar cambios en un atributo y no pasa parámetros.
Debido a la información mínima que estos eventos y métodos pasan como parámetros, todos ellos son adecuadas para funciones anónimas, particularmente Instance:GetPropertyChangedSignal() y Instance:GetAttributeChangedSignal(). Para aprender más sobre funciones anónimas y trabajar con eventos, consulta Eventos.
Escuchar Cambios
local cabbage = script.Parent
-- Funciones locales
local function onAnyPropertyChange(property)
-- Ignorar cambios en atributos
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
-- Escuchar cambios y conectar funciones locales
cabbage.Changed:Connect(onAnyPropertyChange)
cabbage.AttributeChanged:Connect(onAnyAttributeChange)
-- Escuchar cambios y conectar funciones 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 y GetPropertyChangedSignal()
cabbage.Name = "Cabbage1"
-- Dispara Changed y AttributeChanged
cabbage:SetAttribute("Grow", false)
-- Dispara Changed, AttributeChanged y GetAttributeChangedSignal()
cabbage:SetAttribute("GrowthRate", 3)