Eventi e richiami remoti

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

Le esperienze Roblox sono multigiocatore per impostazione predefinita, quindi tutte le esperienze 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 specifiche, come gli stati, vengono comunicate al Server, che trasmette queste informazioni ad altri client connessi.

Gli eventi e le chiamate remote ti consentono di comunicare attraverso il confine client-server:

  • RemoteEvents abilita la comunicazione unidirezionale (invio di una richiesta e non cedere per una risposta).
  • UnreliableRemoteEvents abilita la comunicazione unidirezionale per i dati che cambiano continuamente o non sono critici per lo stato del gioco.Questi eventi scambiano l'ordine degli ordini e l'affidabilità per una migliore Prestazionedella rete.
  • RemoteFunctions attiva la comunicazione a due vie (invio di una richiesta e cedere fino a quando non viene ricevuta una risposta dal destinatario).

A differenza di eventi leganti, che hanno una utilità più limitata, i casi d'uso per eventi e funzioni remoti sono troppi per essere elencati:

  • Gameplay - Il Partitadi base, come un giocatore che raggiunge la fine di un Livello, può richiedere un evento remoto.Un script client informa il Servere gli script del server ripristinano la posizione del Giocatore.
  • Verifica del server - Se un giocatore tenta di bere una pozione, ha effettivamente quella pozione? Per garantire l'equità, il server deve essere la fonte della verità per un'esperienza. uno script client può utilizzare un evento remoto per avvisare 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 - Come cambia lo stato del gioco, gli script del server possono utilizzare eventi remoti per avvisare i client di modifiche ai punteggi, agli obiettivi, ecc.
  • Acquisti del Marketplace in-experience - Per un esempio di implementazione che utilizza funzioni remote, vedi Acquisti di abbonamento prompt .

Riferimento rapido

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

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

Eventi remoti

Un oggetto RemoteEvent asincrono facilita la comunicazione unidirezionale attraverso il confine client-server senza cedere per una risposta.

Per creare una nuova RemoteEvent attraverso la finestra Explorer in Studio:

  1. Passa il mouse sul contenitore in cui vuoi inserire il RemoteEvent .Per garantire l'Accessosia al server che al client, deve essere in un luogo in cui entrambi i lati possono vederlo, 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'esempio RemoteEvent .
  3. Rinomina l'istanza per descrivere il suo scopo.

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

Cliente → Server
>

Server → Client
>

Server → Tutti i clienti
>

Cliente → Server

Puoi usare un LocalScript per attivare un evento sul server chiamando il metodo FireServer() su un RemoteEvent .Se passi gli argomenti a FireServer() , essi passano al gestore eventi sul server con alcune limitazioni .Nota che il primo parametro del gestore eventi sul server è sempre l'oggetto Player del client che lo chiama, e i parametri aggiuntivi Seguire.

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

Il seguente Script connette un gestore di eventi a OnServerEvent che crea un nuovo Part sul Server.L'accompagnamento LocalScript poi chiama FireServer() sulla RemoteEvent istanza con il desiderato Color e Position per la parte.

Connessione evento - Script

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Workspace = game:GetService("Workspace")
-- Ottieni il riferimento all'istanza 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
-- Funzione di connessione all'evento
remoteEvent.OnServerEvent:Connect(onCreatePart)
Sparo di eventi - LocalScript

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

Server → cliente

Puoi usare un Script per attivare un evento su un cliente chiamando il metodo FireClient() su un RemoteEvent .Il primo argomento per è l'oggetto del client che vuoi rispondere all'evento e gli argomenti aggiuntivi passano al client con alcune limitazioni .Nota che il gestore eventi non deve includere l'oggetto Player come primo argomento poiché puoi determinare il giocatore sul client con Players.LocalPlayer .

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

Il seguente LocalScript connette un gestore di eventi a l'evento OnClientEvent.L'accompagnamento Script ascolta quindi 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 il riferimento all'istanza 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
-- Funzione di connessione all'evento
remoteEvent.OnClientEvent:Connect(onNotifyPlayer)
Sparring eventi - Script

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

Server → tutti i client

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

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

Il seguente LocalScript connette un gestore di eventi a un evento OnClientEvent che produce un tempo di conto alla rovescia rimanente.L'accompagnamento Script poi chiama FireAllClients() in un ciclo ogni secondo per attivare il RemoteEvent per tutti i clienti.

Connessione evento - LocalScript

local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Ottieni il riferimento all'istanza evento remoto
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function onTimerUpdate(seconds)
print(seconds)
end
-- Funzione di connessione all'evento
remoteEvent.OnClientEvent:Connect(onTimerUpdate)
Sparring eventi - Script

local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Ottieni il riferimento all'istanza evento remoto
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local countdown = 5
-- Spara l'evento remoto ogni secondo fino allo scadere del tempo
for timeRemaining = -1, countdown do
remoteEvent:FireAllClients(countdown - timeRemaining)
task.wait(1)
end

Richiami remoti

Un oggetto RemoteFunction facilita la comunicazione sincrona, a due vie, attraverso il confine client-server.Il mittente di una funzione remota renderà fino a quando non riceverà una risposta dal Destinatario.

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

  1. Passa il mouse sul contenitore in cui vuoi inserire il RemoteFunction .Per garantire l'Accessosia al server che al client, deve essere in un luogo in cui entrambi i lati possono vederlo, 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'esempio RemoteFunction .
  3. Rinomina l'istanza per descrivere il suo scopo.

Una volta creato un RemoteFunction , può facilitare la comunicazione a due vie tra client e server o tra server e cliente .

Cliente → Server → Cliente
>

Server → Client → Server
>

Cliente → server → cliente

Puoi usare un LocalScript per chiamare una funzione sul server chiamando il metodo InvokeServer() su un RemoteFunction .A differenza di un evento remoto remote, il LocalScript che invoca il RemoteFunction rende fino al ritorno del richiamo.Argomenti che passi a passare al callback del con alcune limitazioni .Nota che se definisci più richiami allo stesso RemoteFunction, viene eseguita solo l'ultima definizione.

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

Il seguente Script definisce la funzione di richiamo attraverso OnServerInvoke e restituisce il richiesto Part attraverso il suo valore return.L'accompagnamento LocalScript poi chiama InvokeServer() con argomenti extra che definiscono il colore e la posizione della parte richiesta.

Connessione di richiamo - Script

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Workspace = game:GetService("Workspace")
-- Ottieni il riferimento all'esempiodella funzione remota
local remoteFunction = ReplicatedStorage:FindFirstChildOfClass("RemoteFunction")
-- Funzione di richiamo
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
-- Imposta la funzione come Richiamadella funzione remota
remoteFunction.OnServerInvoke = createPart
Invocazione evento - LocalScript

local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Ottieni il riferimento all'esempiodella funzione remota
local remoteFunction = ReplicatedStorage:FindFirstChildOfClass("RemoteFunction")
-- Passa un colore e una posizione quando si invoca il Richiama
local newPart = remoteFunction:InvokeServer(Color3.fromRGB(255, 0, 0), Vector3.new(0, 25, -20))
-- Output la referenza della parte restituita
print("The server created the requested part:", newPart)

Server → cliente → server

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

  • Se il client lancia un'errore, il server lancia anche l'errore.
  • Se il client si disconnette mentre viene invocato, InvokeClient() lancia un errore.
  • Se il client non restituisce un valore, il server produce per sempre.

Per le azioni che non richiedono comunicazioni a senso unico, come l'aggiornamento di una GUI or Intefaccia grafica utente, utilizza un RemoteEvent e comunica da server a cliente .

Limitazioni degli argomenti

Quando spari un RemoteEvent o invochi un RemoteFunction , forwarda tutti gli argomenti che passi con l'evento o alla funzione di richiamo.Qualsiasi tipo di oggetto Roblox come un Enum , Instance , o altri può essere passato, così come i tipi Luau come numeri, stringhe e booleani, anche se dovresti esplorare attentamente le seguenti limitazioni.

Indici non stringhe

Se qualsiasi indice di una tabella passata è di tipo non stringa come un Instance , dati utente o funzione, Roblox converte automaticamente tali 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)) --> stringa
end
end
-- Funzione di connessione all'evento
remoteEvent.OnClientEvent:Connect(onEventFire)
Sparring eventi - 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 invia l'evento remoto a 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 saranno non replicate attraverso il confine client-server, rendendo impossibile passare le funzioni remotamente.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) --> zero
end
remoteEvent.OnClientEvent:Connect(onClientEvent)
Sparring eventi - Script

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function testFunction()
print("Hello world!")
end
-- Evento remoto di fuoco con funzione come argomento
remoteEvent:FireAllClients(testFunction)

Indicizzazione della tabella

Se passi una tabella di dati, non passare una tabella mista di chiavi numeriche e di stringhe.Invece, passa un tavolo che consiste interamente di coppie chiave-valore (dizione) 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 = Divano Dragonslayer
--> CharClass = Cattivo
end
end
-- Funzione di connessione all'evento
remoteEvent.OnServerEvent:Connect(onEventFire)
Sparo di eventi - LocalScript

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- Tabella numericamente indicizzata
local inventoryData = {
"Sword", "Bow"
}
-- Tabella dizionario
local characterData = {
CharName = "Diva Dragonslayer",
CharClass = "Rogue"
}
remoteEvent:FireServer(inventoryData)
remoteEvent:FireServer(characterData)

Identità della tabella

Le tabelle passate come argomenti a eventi remoti/ callback vengono copiate, il che significa che non saranno esattamente equivalenti a quelle fornite quando si attiva l'evento o si invoca il Richiama.Né le tabelle restituite all'invocatore saranno esattamente equivalenti a quelle fornite.Puoi dimostrarlo eseguendo il seguente script su un RemoteFunction e osservando come le identità della tabella differiscono.

Connessione di richiamo - Script

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteFunction = ReplicatedStorage:FindFirstChildOfClass("RemoteFunction")
-- Funzione di richiamo
local function returnTable(player, passedTable)
-- Identità della tabella di output durante l'invocazione
print(tostring(passedTable)) --> tabella: 0x48eb7aebook27563d9
return passedTable
end
-- Imposta la funzione come Richiamadella funzione remota
remoteFunction.OnServerInvoke = returnTable
Invocazione evento - LocalScript

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteFunction = ReplicatedStorage:FindFirstChildOfClass("RemoteFunction")
local inventoryData = {
"Sword", "Bow"
}
-- Output dell'identità della tabella originale
print(tostring(inventoryData)) --> tabella: 0x059bcmdbb2b576549
local invokeReturn = remoteFunction:InvokeServer(inventoryData)
-- Identità della tabella di output al Riportare
print(tostring(invokeReturn)) --> table: 0x9fcae7919563a0e9

Metatabele

Se una tabella ha un metatable, tutte le informazioni metatable vengono perse durante il trasferimento.Nell'esempio di codice seguente, la proprietà NumWheels è parte del Car metabile.Quando il server riceve la seguente tabella, la tabella ha la proprietà ma non la Proprietà.

Connessione evento - Script

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function onEvent(player, param)
print(param) --> { ["Nome"] = "MyTruck"]}
end
-- Funzione di connessione all'evento
remoteEvent.OnServerEvent:Connect(onEvent)
Sparo di eventi - 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 di fuoco con tavolo che include un metatable
remoteEvent:FireServer(truck)

Istenze non replicate

Se un RemoteEvent o 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.

Sparring eventi - Script

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerStorage = game:GetService("ServerStorage")
local Players = game:GetService("Players")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- Verrà ricevuto come "null" 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 tenti di passarla a un Script , il server vedrà nil perché la parte non è replicabile per il Server.

Sparo di eventi - LocalScript

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Workspace = game:GetService("Workspace")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- Verrà ricevuto come "null" perché il server non conosce questa parte
local clientPart = Instance.new("Part")
clientPart.Parent = Workspace
remoteEvent:FireServer(clientPart)