Eventi remoti e callback

*Questo contenuto è tradotto usando AI (Beta) e potrebbe contenere errori. Per visualizzare questa pagina in inglese, clicca qui.

I giochi Roblox sono multiplayer per impostazione predefinita, quindi tutti i giochi comunicano intrinsecamente tra il server e i client connessi dei giocatori. Nel caso più semplice, mentre i giocatori muovono i loro personaggi, alcune proprietà Humanoid, come gli stati, vengono comunicate al server, il quale passa queste informazioni agli altri client connessi.

Gli eventi remoti e i callback ti permettono di comunicare attraverso il confine client-server:

  • RemoteEvents abilitano la comunicazione unidirezionale (inviando una richiesta e non aspettando una risposta).
  • UnreliableRemoteEvents permettono la comunicazione unidirezionale per dati che cambiano continuamente o non sono critici per lo stato del gioco. Questi eventi scambiano ordinamento e affidabilità per migliorare le prestazioni di rete.
  • RemoteFunctions consentono la comunicazione bidirezionale (inviando una richiesta e aspettando finché non si riceve una risposta dal destinatario).

A differenza degli eventi bindabili, che hanno un'utilità più limitata, i casi d'uso per eventi remoti e funzioni sono troppo numerosi per essere elencati:

  • Gioco - Il gameplay di base, come un giocatore che raggiunge la fine di un livello, può richiedere un evento remoto. Uno script client notifica il server, e gli script del server ripristinano la posizione del giocatore.
  • Verifica del server - Se un giocatore cerca di bere una pozione, ha realmente quella pozione? Per garantire equità, il server deve essere la fonte di verità per un gioco. Uno script client può usare un evento remoto per notificare il server che il giocatore sta bevendo una pozione, e poi gli script del server possono decidere se il giocatore ha effettivamente quella pozione e se conferire eventuali benefici.
  • Aggiornamenti dell'interfaccia utente - Man mano che lo stato del gioco cambia, gli script del server possono utilizzare eventi remoti per notificare ai client le modifiche ai punteggi, obiettivi, ecc.
  • Acquisti nel Marketplace di gioco - Per un esempio di implementazione che utilizza funzioni remote, vedere Acquisti di abbonamenti.

Riferimento rapido

Le seguenti tabelle servono come riferimento rapido su come utilizzare RemoteEvents e RemoteFunctions per comunicare tra il client e il server.

Client → Server
ClientRemoteEvent:FireServer(args)
ServerRemoteEvent.OnServerEvent:Connect(function(player, args))
Server → Client
ServerRemoteEvent:FireClient(player, args)
ClientRemoteEvent.OnClientEvent:Connect(function(args))
Server → Tutti i Client
ServerRemoteEvent:FireAllClients(args)
ClientRemoteEvent.OnClientEvent:Connect(function(args))

Eventi remoti

Un oggetto RemoteEvent facilita la comunicazione asincrona, unidirezionale attraverso il confine client-server senza aspettare una risposta.

Per creare un nuovo RemoteEvent tramite la finestra Explorer in Studio:

  1. Passa sopra il contenitore in cui vuoi inserire il RemoteEvent. Per garantire l'accesso sia al server che al client, deve trovarsi in un luogo visibile da entrambe le parti, come ReplicatedStorage, anche se in alcuni casi è appropriato conservarlo in Workspace o all'interno di un Tool.
  2. Fai clic sul pulsante che appare a destra del nome del contenitore e inserisci un'istanza di RemoteEvent.
  3. Rinomina l'istanza per descriverne lo scopo.

Una volta creato un RemoteEvent, può facilitare la comunicazione unidirezionale da client a server, da server a client, o da server a tutti i client.

Client → Server
Server → Client
Server → Tutti i Client

Client → server

Puoi utilizzare un LocalScript per attivare un evento sul server chiamando il metodo FireServer() su un RemoteEvent. Se passi argomenti a FireServer(), questi vengono passati al gestore dell'evento sul server con alcune limitazioni. Nota che il primo parametro del gestore dell'evento sul server è sempre l'oggetto Player del client che lo chiama, e i parametri aggiuntivi seguono.

ClientRemoteEvent:FireServer(args)
ServerRemoteEvent.OnServerEvent:Connect(function(player, args))

Il seguente Script collega un gestore dell'evento a OnServerEvent che crea un nuovo Part sul server. Il LocalScript accompagnatorio chiama poi FireServer() sull'istanza di RemoteEvent con il Color e la Position desiderati per la parte.

Connessione Evento - Script

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Workspace = game:GetService("Workspace")
-- Ottieni riferimento all'istanza di evento remoto
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function onCreatePart(player, partColor, partPosition)
print(player.Name .. " ha attivato il RemoteEvent")
local newPart = Instance.new("Part")
newPart.Color = partColor
newPart.Position = partPosition
newPart.Parent = Workspace
end
-- Collega la funzione all'evento
remoteEvent.OnServerEvent:Connect(onCreatePart)
Attivazione Evento - LocalScript

local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Ottieni riferimento all'istanza di evento remoto
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- Attiva l'evento remoto e passa argomenti aggiuntivi
remoteEvent:FireServer(Color3.fromRGB(255, 0, 0), Vector3.new(0, 25, -20))

Server → client

Puoi utilizzare un Script per attivare un evento su un client chiamando il metodo FireClient() su un RemoteEvent. Il primo argomento per FireClient() è l'oggetto Player del client a cui vuoi rispondere all'evento, e argomenti aggiuntivi vengono passati al client con alcune limitazioni. Nota che il gestore dell'evento non deve includere l'oggetto Player come primo argomento perché puoi determinare il giocatore sul client con Players.LocalPlayer.

ServerRemoteEvent:FireClient(player, args)
ClientRemoteEvent.OnClientEvent:Connect(function(args))

Il seguente LocalScript collega un gestore dell'evento a OnClientEvent. Il Script accompagnatorio ascolta i giocatori in arrivo al server e chiama FireClient() per ciascuno con dati arbitrari.

Connessione Evento - LocalScript

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
-- Ottieni riferimento all'istanza di evento remoto
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local player = Players.LocalPlayer
local function onNotifyPlayer(maxPlayers, respawnTime)
print("[Client] Evento ricevuto dal giocatore", player.Name)
print(maxPlayers, respawnTime)
end
-- Collega la funzione all'evento
remoteEvent.OnClientEvent:Connect(onNotifyPlayer)
Attivazione Evento - Script

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
-- Ottieni riferimento all'istanza di evento remoto
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- Ascolta i giocatori in arrivo e attiva l'evento remoto per ciascuno
local function onPlayerAdded(player)
print("[Server] Attivando evento per il giocatore", player.Name)
remoteEvent:FireClient(player, Players.MaxPlayers, Players.RespawnTime)
end
Players.PlayerAdded:Connect(onPlayerAdded)

Server → tutti i client

Puoi utilizzare un Script per attivare un evento su tutti i client chiamando il metodo FireAllClients() su un RemoteEvent. A differenza di FireClient(), il metodo FireAllClients() non richiede un oggetto Player perché attiva il RemoteEvent per tutti i client.

ServerRemoteEvent:FireAllClients(args)
ClientRemoteEvent.OnClientEvent:Connect(function(args))

Il seguente LocalScript collega un gestore dell'evento a OnClientEvent che restituisce il tempo rimanente del countdown. Il Script accompagnatorio quindi chiama FireAllClients() in un ciclo ogni secondo per attivare il RemoteEvent per tutti i client.

Connessione Evento - LocalScript

local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Ottieni riferimento all'istanza di evento remoto
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function onTimerUpdate(seconds)
print(seconds)
end
-- Collega la funzione all'evento
remoteEvent.OnClientEvent:Connect(onTimerUpdate)
Attivazione Evento - Script

local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Ottieni riferimento all'istanza di evento remoto
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local countdown = 5
-- Attiva il RemoteEvent ogni secondo fino alla scadenza
for timeRemaining = -1, countdown do
remoteEvent:FireAllClients(countdown - timeRemaining)
task.wait(1)
end

Callback remoti

Un oggetto RemoteFunction facilita la comunicazione sincrona, bidirezionale attraverso il confine client-server. Il mittente di una funzione remota attenderà fino a ricevere una risposta dal destinatario.

Per creare una nuova RemoteFunction tramite la finestra Explorer in Studio:

  1. Passa sopra il contenitore in cui vuoi inserire il RemoteFunction. Per garantire l'accesso sia al server che al client, deve trovarsi in un luogo visibile da entrambe le parti, come ReplicatedStorage, anche se in alcuni casi è appropriato conservarlo in Workspace o all'interno di un Tool.
  2. Fai clic sul pulsante che appare a destra del nome del contenitore e inserisci un'istanza di RemoteFunction.
  3. Rinomina l'istanza per descriverne lo scopo.

Una volta creato un RemoteFunction, può facilitare la comunicazione bidirezionale tra client e server oppure tra server e client.

Client → Server → Client
Server → Client → Server

Client → server → client

Puoi usare un LocalScript per chiamare una funzione sul server chiamando il metodo InvokeServer() su un RemoteFunction. A differenza di un evento remoto, il LocalScript che invoca il RemoteFunction attende fino a quando il callback restituisce. Gli argomenti che passi a InvokeServer() vengono passati al callback OnServerInvoke del RemoteFunction con alcune limitazioni. Nota che se definisci più callback per lo stesso RemoteFunction, solo l'ultima definizione verrà eseguita.

ClientRemoteFunction:InvokeServer(args)
ServerRemoteFunction.OnServerInvoke = function(player, args)

Il seguente Script definisce la funzione di callback tramite OnServerInvoke e restituisce il Part richiesto attraverso il valore di ritorno. Il LocalScript accompagnatorio chiama poi InvokeServer() con argomenti extra che definiscono il colore e la posizione della parte richiesta.

Connessione Callback - Script

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Workspace = game:GetService("Workspace")
-- Ottieni riferimento all'istanza di funzione remota
local remoteFunction = ReplicatedStorage:FindFirstChildOfClass("RemoteFunction")
-- Funzione di callback
local function createPart(player, partColor, partPosition)
print(player.Name .. " ha richiesto una nuova parte")
local newPart = Instance.new("Part")
newPart.Color = partColor
newPart.Position = partPosition
newPart.Parent = Workspace
return newPart
end
-- Imposta la funzione come callback della funzione remota
remoteFunction.OnServerInvoke = createPart
Attivazione Evento - LocalScript

local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Ottieni riferimento all'istanza di funzione remota
local remoteFunction = ReplicatedStorage:FindFirstChildOfClass("RemoteFunction")
-- Passa un colore e una posizione quando invochi il callback
local newPart = remoteFunction:InvokeServer(Color3.fromRGB(255, 0, 0), Vector3.new(0, 25, -20))
-- Stampa il riferimento alla parte restituita
print("Il server ha creato la parte richiesta:", newPart)

Server → client → server

Puoi usare un Script per chiamare una funzione sul client chiamando il metodo InvokeClient() su un RemoteFunction, ma ha seri rischi come segue:

  • Se il client genera un errore, il server genera anch'esso l'errore.
  • Se il client si disconnette mentre viene invocato, InvokeClient() genera un errore.
  • Se il client non restituisce un valore, il server attende per sempre.

Per azioni che non richiedono comunicazioni bidirezionali, come l'aggiornamento di un'interfaccia utente, usa un RemoteEvent e comunica da server a client.

Limitazioni degli argomenti

Quando attivi un RemoteEvent o invochi un RemoteFunction, trasmette qualunque argomento che passi con l'evento o alla funzione di callback. Qualsiasi tipo di oggetto Roblox come un Enum, un Instance o altri può essere passato, così come i tipi Luau come numeri, stringhe e booleani, sebbene dovresti esplorare attentamente le seguenti limitazioni.

Indici non stringa

Se qualche indice di una tabella passata è di tipi non stringa, come un Instance, userdata o funzione, Roblox converte automaticamente quegli indici in stringhe.

Connessione 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
end
end
-- Collega la funzione all'evento
remoteEvent.OnClientEvent:Connect(onEventFire)
Attivazione Evento - Script

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local Workspace = game:GetService("Workspace")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- Ascolta i giocatori in arrivo e attiva l'evento remoto per ciascuno
local function onPlayerAdded(player)
remoteEvent:FireClient(player,
{
[Workspace.Baseplate] = true
}
)
end
Players.PlayerAdded:Connect(onPlayerAdded)

Funzioni passate

Le funzioni incluse come argomenti per un RemoteEvent o RemoteFunction non saranno replicate attraverso il confine client-server, rendendo impossibile passare funzioni a distanza. Invece, l'argomento risultante sul lato ricevente sarà nil.

Connessione Evento - LocalScript

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function onClientEvent(func)
print(func) --> nil
end
remoteEvent.OnClientEvent:Connect(onClientEvent)
Attivazione Evento - Script

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function testFunction()
print("Ciao mondo!")
end
-- Attiva evento remoto con funzione come argomento
remoteEvent:FireAllClients(testFunction)

Indicizzazione delle tabelle

Se passi una tabella di dati, non passare una tabella mista di chiavi numeriche e stringa. Invece, passa una tabella che consista interamente di coppie chiave-valore (dizionario) o interamente di indici numerici.

Connessione 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 = Spada
--> 2 = Arco
--> CharName = Diva Dragone
--> CharClass = Ladro
end
end
-- Collega la funzione all'evento
remoteEvent.OnServerEvent:Connect(onEventFire)
Attivazione Evento - LocalScript

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- Tabella indicizzata numericamente
local inventoryData = {
"Spada", "Arco"
}
-- Tabella dizionario
local characterData = {
CharName = "Diva Dragone",
CharClass = "Ladra"
}
remoteEvent:FireServer(inventoryData)
remoteEvent:FireServer(characterData)

Identità delle tabelle

Le tabelle passate come argomenti agli eventi/callback remoti vengono copiate, il che significa che non saranno esattamente equivalenti a quelle fornite quando si attiva l'evento o si invoca il callback. Inoltre, le tabelle restituite all'invocatore non saranno esattamente equivalenti a quelle fornite. Puoi dimostrare ciò eseguendo il seguente script su un RemoteFunction e osservando come l'identità delle tabelle differisca.

Connessione Callback - Script

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteFunction = ReplicatedStorage:FindFirstChildOfClass("RemoteFunction")
-- Funzione di callback
local function returnTable(player, passedTable)
-- Stampa l'identità della tabella all'invocazione
print(tostring(passedTable)) --> table: 0x48eb7aead27563d9
return passedTable
end
-- Imposta la funzione come callback della funzione remota
remoteFunction.OnServerInvoke = returnTable
Attivazione Evento - LocalScript

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteFunction = ReplicatedStorage:FindFirstChildOfClass("RemoteFunction")
local inventoryData = {
"Spada", "Arco"
}
-- Stampa l'identità della tabella originale
print(tostring(inventoryData)) --> table: 0x059bcdbb2b576549
local invokeReturn = remoteFunction:InvokeServer(inventoryData)
-- Stampa l'identità della tabella al momento del ritorno
print(tostring(invokeReturn)) --> table: 0x9fcae7919563a0e9

Metatables

Se una tabella ha un metatable, tutte le informazioni del metatable andranno perse durante il trasferimento. Nel seguente campione di codice, la proprietà NumWheels fa parte del metatable di Car. Quando il server riceve la seguente tabella, la tabella truck ha la proprietà Name ma non la proprietà NumWheels.

Connessione Evento - Script

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function onEvent(player, param)
print(param) --> {["Name"] = "Il Mio Camion"}
end
-- Collega la funzione all'evento
remoteEvent.OnServerEvent:Connect(onEvent)
Attivazione Evento - LocalScript

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local Car = {}
Car.NumWheels = 4
Car.__index = Car
local truck = {}
truck.Name = "Il Mio Camion"
setmetatable(truck, Car)
-- Attiva evento con tabella che include un metatable
remoteEvent:FireServer(truck)

Istanza non replicate

Se un RemoteEvent o un RemoteFunction passa un valore che è visibile solo al mittente, Roblox non lo replica attraverso il confine client-server e passa nil invece del valore. Ad esempio, se un Script passa un discendente di ServerStorage, il client che ascolta l'evento riceverà un valore nil perché quell'oggetto non è replicabile per il client.

Attivazione Evento - Script

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerStorage = game:GetService("ServerStorage")
local Players = game:GetService("Players")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- Sarà ricevuto come "nil" perché il client non può accedere a ServerStorage
local storedPart = Instance.new("Part")
storedPart.Parent = ServerStorage
local function onPlayerAdded(player)
remoteEvent:FireClient(player, storedPart)
end
Players.PlayerAdded:Connect(onPlayerAdded)

Allo stesso modo, se crei una parte in un LocalScript e provi a passarla a un Script, il server vedrà nil perché la parte non è replicabile per il server.

Attivazione Evento - LocalScript

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Workspace = game:GetService("Workspace")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- Sarà ricevuto come "nil" perché il server non conosce questa parte
local clientPart = Instance.new("Part")
clientPart.Parent = Workspace
remoteEvent:FireServer(clientPart)
© 2026 Roblox Corporation. Roblox, il logo Roblox e Powering Imagination sono tra i nostri marchi registrati e non registrati negli Stati Uniti. e altri paesi.