Eventos Remotos e Chamadas

*Este conteúdo é traduzido por IA (Beta) e pode conter erros. Para ver a página em inglês, clique aqui.

As experiências do Roblox são multijogador por padrão, então todas as experiências hermeticamente se comunicam entre o servidor e os clientes conectados. No caso mais simples, à medida que os jogadores movem seus personagens, certas propriedades Humanoid são comunicadas ao servidor, o que passa esta informação para outros clientes conectados.

Eventos e chamadas remotos permitem que você se comunique até a fronteira cliente-servidor:

  • RemoteEvents habilita a comunicação de um caminho (enviar uma solicitação e não retornar para uma resposta).
  • UnreliableRemoteEvents habilita a comunicação de um caminho para dados que mudam continuamente ou não são críticos para o estado do jogo. Esses eventos trocam ordem e confiabilidade para melhorar o performanceda rede.
  • RemoteFunctions habilita comunicação de duas vias (enviar uma solicitação e retornar até que uma resposta seja recebida do destinatário).

Ao contrário de Eventos Vinculáveis, que têm mais utilidade limitada, os casos de uso para eventos e funções remotos são demasiado numerosos para listar:

  • Jogabilidade do Jogo - jogabilidadebásica, como um jogador chegando ao fim de um nível, pode exigir um evento remoto. Um script de cliente notifica o servidor e os scripts de servidor redefinem a posição do jogador.
  • Verificação do servidor - Se um jogador tentar beber uma poção, eles realmente têm essa poção? Para garantir a justiça, o servidor deve ser a fonte da verdade para uma experiência. Um script de cliente pode usar um evento remoto para notificar o servidor que o jogador está bebendo uma poção, e então os scripts do servidor podem decidir se o jogador realmente tem essa poção e se conferir quaisquer benefícios.
  • Atualizações na interface do usuário - À medida que o estado do jogo muda, os scripts do servidor podem usar eventos remotos para notificar os clientes de alterações em pontuações, metas, etc.
  • Compras no Mercado de Experiência - Para uma implementação de exemplo que usa funções remotas, veja Solicitando Compras de Assinatura.

Rápida referência

As tabelas a seguir servem como referência rápida para como usar RemoteEvents e RemoteFunctions para comunicar entre o cliente e o servidor.

> > >
Cliente → Servidor
ClienteRemoteEvent:FireServer(args)
ServidorRemoteEvent.OnServerEvent:Connect(function(player, args))
Servidor → Cliente
ServidorRemoteEvent:FireClient(player, args)
ClienteRemoteEvent.OnClientEvent:Connect(function(args))
Servidor → Todos os Clientes
ServidorRemoteEvent:FireAllClients(args)
ClienteRemoteEvent.OnClientEvent:Connect(function(args))

Eventos Remotos

Um objeto RemoteEvent facilita a comunicação assíncrona, de um lado, entre o cliente e o servidor sem a necessidade de uma resposta.

Para criar um novo RemoteEvent via a janela Explorer no Studio:

  1. Passe o mouse sobre o contêiner no qual você deseja inserir o RemoteEvent. Para garantir o acesso tanto do servidor quanto do cliente, ele deve estar em um lugar onde ambos os lados possam vê-lo, como ReplicatedStorage, embora em alguns casos seja apropriado armazená-lo em Workspace ou dentro de um
  2. Clique no botão que aparece à direita do nome do contêiner e insira uma instância RemoteEvent .
  3. Renomeie a instância para descrever seu propósito.

Uma vez que você criou um RemoteEvent, pode facilitar uma comunicação de um cliente para o servidor , de um servidor para o cliente ou do servidor para todos os clientes 2> .

Cliente → Servidor
Servidor → Cliente
Servidor → Todos os Clientes

Cliente → Servidor

Você pode usar um LocalScript para trigger um evento no servidor 服務器 ao chamar o método Class.RemoteEvent:FireServer()|FireServer() no

ClienteRemoteEvent:FireServer(args)
ServidorRemoteEvent.OnServerEvent:Connect(function(player, args))

O seguinte Script conecta um gerador de eventos a OnServerEvent que cria um novo Class.

Conexão de Evento - Script

local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Obtenha referência à instância de evento remoto
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function onCreatePart(player, partColor, partPosition)
print(player.Name .. " fired the RemoteEvent")
local newPart = Instance.new("Part")
newPart.Color = partColor
newPart.Position = partPosition
newPart.Parent = workspace
end
-- Conectar função ao evento
remoteEvent.OnServerEvent:Connect(onCreatePart)
Gerenciador de Eventos - LocalScript

local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Obtenha referência à instância de evento remoto
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- Fire o evento remoto e passe argumentos adicionais
remoteEvent:FireServer(Color3.fromRGB(255, 0, 0), Vector3.new(0, 25, -20))

Servidor → Cliente

Você pode usar um Script

ServidorRemoteEvent:FireClient(player, args)
ClienteRemoteEvent.OnClientEvent:Connect(function(args))

O seguinte LocalScript conecta um gerenciador de eventos ao evento OnClientEvent. O acompanhante Script então ouve os jogadores entrantes no servidor e chama 2>Class.RemoteEvent:FireClient()|FireClient()2> para cada com dados arbitrários.

Conexão de Evento - LocalScript

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
-- Obtenha referência à instância de evento remoto
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local player = Players.LocalPlayer
local function onNotifyPlayer(maxPlayers, respawnTime)
print("[Client] Event received by player", player.Name)
print(maxPlayers, respawnTime)
end
-- Conectar função ao evento
remoteEvent.OnClientEvent:Connect(onNotifyPlayer)
Gerenciador de Eventos - Script

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
-- Obtenha referência à instância de evento remoto
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- Ouça jogadores entrantes e envie eventos remotos para cada
local function onPlayerAdded(player)
print("[Server] Firing event to player", player.Name)
remoteEvent:FireClient(player, Players.MaxPlayers, Players.RespawnTime)
end
Players.PlayerAdded:Connect(onPlayerAdded)

Servidor → Todos os Clientes

Você pode usar um Script para acionar um evento em todos os clientes ao chamar o método FireAllClients() em um Class.

ServidorRemoteEvent:FireAllClients(args)
ClienteRemoteEvent.OnClientEvent:Connect(function(args))

O seguinte LocalScript conecta um evento handle ao evento OnClientEvent que produz um tempo de contagem restante. O acompanhante Script então chama 1> Class.RemoteEvent:FireAllClients()|FireAllClients()1> em um

Conexão de Evento - LocalScript

local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Obtenha referência à instância de evento remoto
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function onTimerUpdate(seconds)
print(seconds)
end
-- Conectar função ao evento
remoteEvent.OnClientEvent:Connect(onTimerUpdate)
Gerenciador de Eventos - Script

local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Obtenha referência à instância de evento remoto
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local countdown = 5
-- Fire o RemoteEvent todos os segundos até o tempo expirar
for timeRemaining = -1, countdown do
remoteEvent:FireAllClients(countdown - timeRemaining)
task.wait(1)
end

Chamadas Remotas

Um objeto RemoteFunction facilita a comunicação sincrona, de duas vias, entre o cliente e o servidor. O remetente de uma função remota produzirá até que receba uma resposta do destinatário.

Para criar uma nova RemoteFunction via a janela Explorer no Studio:

  1. Passe o mouse sobre o contêiner no qual você deseja inserir o RemoteFunction. Para garantir o acesso tanto do servidor quanto do cliente, ele deve estar em um lugar onde ambos os lados possam vê-lo, como ReplicatedStorage, embora em alguns casos seja apropriado armazená-lo em Workspace ou dentro de um
  2. Clique no botão que aparece à direita do nome do contêiner e insira uma instância RemoteFunction .
  3. Renomeie a instância para descrever seu propósito.

Uma vez que você criou um RemoteFunction, pode facilitar a comunicação de duas maneiras entre cliente e servidor ou entre servidor e cliente.

Cliente → Servidor → Cliente
Servidor → Cliente → Servidor

Cliente → Servidor → Cliente

Você pode usar um LocalScript para chamar uma função no servidor Class.RemoteFunction:ExecuteServer() ao chamar o método Class

ClienteRemoteFunction:InvokeServer(args)
ServidorRemoteFunction.OnServerInvoke = function(player, args)

O seguinte Script define a função de retorno via OnServerInvoke e retorna o solicitado Part através de seu valor de retorno extra. O acompanhante 1> Class.LocalScript1> então chama 4> Class.Remote

Chamada de Conexão - Script

local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Obtenha referência à instância de função remota
local remoteFunction = ReplicatedStorage:FindFirstChildOfClass("RemoteFunction")
-- Função de retorno
local function createPart(player, partColor, partPosition)
print(player.Name .. " requested a new part")
local newPart = Instance.new("Part")
newPart.Color = partColor
newPart.Position = partPosition
newPart.Parent = workspace
return newPart
end
-- Definir a função como o retorno de chamada de uma função remota
remoteFunction.OnServerInvoke = createPart
Invocação de Evento - LocalScript

local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Obtenha referência à instância de função remota
local remoteFunction = ReplicatedStorage:FindFirstChildOfClass("RemoteFunction")
-- Passe uma cor e posição ao invocar o retorno de chamada
local newPart = remoteFunction:InvokeServer(Color3.fromRGB(255, 0, 0), Vector3.new(0, 25, -20))
-- Saia a referência de parte retornada
print("The server created the requested part:", newPart)

Servidor → Cliente → Servidor

Você pode usar um Script para chamar uma função no cliente ao chamar o método Class.RemoteFunction:ExecuteClient()|ExecuteClient() em um Class.RemoteFunction , mas tem riscos sérios a seguir:

  • Se o cliente thrower um erro, o servidor também throwerá o erro.
  • Se o cliente se desconectar enquanto estiver sendo invocado, InvokeClient() apresenta um erro.
  • Se o cliente não retornar um valor, o servidor gera para sempre.

Para ações que não requerem comunicações de duas vias, como atualizar um Interface gráfica do usuário, use um RemoteEvent e comunique-se de servidor para cliente.

Limitações de Argumento

Quando você executa um RemoteEvent ou invoca um RemoteFunction, ele avança quaisquer argumentos que você passe com o evento ou para a função de retorno. Qualquer tipo de objeto Roblox, como um Enum , 2>Class.Instance2> ou outros, pode ser passado, assim como os tipos

Índices não-string

Se quaisquer índices de uma tabela passada forem tipos não padrão, como um Instance, userdata ou 2>função2>, o Roblox automaticamente converte esses índices em strins.

Conexão de Evento - LocalScript

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function onEventFire(passedTable)
for k, v in passedTable do
print(typeof(k)) --> string / cadeia / texto
end
end
-- Conectar função ao evento
remoteEvent.OnClientEvent:Connect(onEventFire)
Gerenciador de Eventos - Script

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- Ouça jogadores entrantes e envie eventos remotos para cada
local function onPlayerAdded(player)
remoteEvent:FireClient(player,
{
[workspace.Baseplate] = true
}
)
end
Players.PlayerAdded:Connect(onPlayerAdded)

Funções Passadas

Funções incluídas como argumentos para um RemoteEvent ou RemoteFunction não serão replicadas ao longo da fronteira cliente-servidor , tornando impossível passar funções remotamente. Em vez disso, o argumento resultante do lado do receptor será 1> nil1>.

Conexão de Evento - LocalScript

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function onClientEvent(func)
print(func) --> zero
end
remoteEvent.OnClientEvent:Connect(onClientEvent)
Gerenciador de Eventos - Script

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function testFunction()
print("Hello world!")
end
-- Evento remoto de fogo com função como um argumento
remoteEvent:FireAllClients(testFunction)

Índice de Tabelas

Se você passar uma tabela de dados, não passe uma tabela misturada de chaves numericas e string. Em vez disso, passe uma tabela que consiste inteiramente de pares de chaves (dicionário) ou inteiramente de índices numericos.

Conexão de Evento - Script

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function onEventFire(player, passedTable)
for k, v in passedTable do
print(k .. " = " .. v)
--> 1 = Espada
--> 2 = Arco
--> CharName = Diva Dragonslayer
--> CharClass = Desviado
end
end
-- Conectar função ao evento
remoteEvent.OnServerEvent:Connect(onEventFire)
Gerenciador de Eventos - LocalScript

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- Tabela numericamente indexada
local inventoryData = {
"Sword", "Bow"
}
-- Tabela de dicionário
local characterData = {
CharName = "Diva Dragonslayer",
CharClass = "Rogue"
}
remoteEvent:FireServer(inventoryData)
remoteEvent:FireServer(characterData)

Identidades de Tabela

Tabelas passadas como argumentos para eventos/ callbacks remotos são copiadas, o que significa que elas não serão exatamente equivalentes às fornecidas quando o evento é disparado ou invocado o retorno de chamada. As tabelas retornadas ao invoker não serão exatamente equivalentes às fornecidas. Você pode demonstrar isso ao executar o seguinte script em um RemoteFunction e observar como as identidades de tabelas diferem.

Chamada de Conexão - Script

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteFunction = ReplicatedStorage:FindFirstChildOfClass("RemoteFunction")
-- Função de retorno
local function returnTable(player, passedTable)
-- Identificador de tabela de saída na invocação
print(tostring(passedTable)) --> tabela: 0x48eb7aead27563d9
return passedTable
end
-- Definir a função como o retorno de chamada de uma função remota
remoteFunction.OnServerInvoke = returnTable
Invocação de Evento - LocalScript

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteFunction = ReplicatedStorage:FindFirstChildOfClass("RemoteFunction")
local inventoryData = {
"Sword", "Bow"
}
-- Exibe a identificação original da tabela
print(tostring(inventoryData)) --> tabela: 0x059bcdbb2b576549
local invokeReturn = remoteFunction:InvokeServer(inventoryData)
-- Identificar a tabela de saída ao retornar
print(tostring(invokeReturn)) --> table: 0x9fcae7919563a0e9

Metatabelas

Se uma tabela tiver uma metabela, toda a informação de metabela é perdida no transfer. No exemplo de código a seguir, a propriedade NumWheels faz parte da metabela Car. Quando o servidor receber a tabela a seguir, a tabela truck tem a propriedade 2> Name

Conexão de Evento - Script

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function onEvent(player, param)
print(param) --> { ["Nome"] = "MyTruck"]
end
-- Conectar função ao evento
remoteEvent.OnServerEvent:Connect(onEvent)
Gerenciador de Eventos - LocalScript

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local Car = {}
Car.NumWheels = 4
Car.__index = Car
local truck = {}
truck.Name = "MyTruck"
setmetatable(truck, Car)
-- Evento de fogo com tabela incluída uma metabela
remoteEvent:FireServer(truck)

Instâncias não replicadas

Se um RemoteEvent ou RemoteFunction passar um valor que só é visível para o remetente, o Roblox não replica-o através da fronteira cliente-servidor e passa nil em vez do valor. Por

Gerenciador de Eventos - Script

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerStorage = game:GetService("ServerStorage")
local Players = game:GetService("Players")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- Será recebido como "nil" porque o cliente não pode acessar o armazenamento do servidor
local storedPart = Instance.new("Part")
storedPart.Parent = ServerStorage
local function onPlayerAdded(player)
remoteEvent:FireClient(player, storedPart)
end
Players.PlayerAdded:Connect(onPlayerAdded)

Da mesma forma, se você criar uma peça em um LocalScript e tentar passá-la para um Script, o servidor verá nil porque a peça não é replicável para o servidor.

Gerenciador de Eventos - LocalScript

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- Será recebido como "nil" porque o servidor não conhece esta parte
local clientPart = Instance.new("Part")
clientPart.Parent = workspace
remoteEvent:FireServer(clientPart)