遠端事件和回潮

*此內容是使用 AI(Beta 測試版)翻譯,可能含有錯誤。若要以英文檢視此頁面,請按一下這裡

Roblox 體驗是多人遊戲的預設,因此所有體驗都會在預設的方式中與服務器和玩家的連接客戶端通信。 在最簡單的情況下,當玩家移動其角色時,某些 Humanoid 屬性,例如狀態,會傳輸至服務器,並傳達此資訊給其他連接的客戶端。

遠端事件和回報讓您通過 通過 客戶端-伺服器界限:

  • RemoteEvents 啟用單向通信 (發送請求並 輸出回應)。
  • UnreliableRemoteEvents 啟用一方通訊為不間斷或不危險的資料,這些事件交易順序和可靠性以提高網路履約。
  • RemoteFunctions 啟用兩向通信 (發送請求並等待從接收收件人收到回應)。

可綁定事件 不同,其使用案例對於遠端事件和功能來說太多了,以便列出:

  • 遊戲玩法 - 基本遊遊玩法,例如玩家到達等級底部時,可能需要遠端事件。客戶端指令向伺服器發送通知,伺服器重設玩家位置。
  • 伺服器驗證 - 如果玩家試著喝一個藥水,他們是否真的 那個藥水?為了確保公平,伺服器必須是真實的來源。客戶端指令碼可以使用遠程事件通知伺服器,玩家正在喝藥水,並且可以決定是否有此藥水,並且是否
  • 使用者界面更新 - 隨著遊戲狀態變更,伺服器指令碼可以使用遠端事件通知客戶端變更分數、目標等。
  • 在體驗中購買市場產品 - 對於使用遠程功能的示例實現,請參閱 提示訂閱購買

快速參考

下表為快速參考使用 RemoteEventsRemoteFunctions 來通信的方法。

> > >
客戶端 → 伺服器 >
客戶RemoteEvent:FireServer(args)
伺服器RemoteEvent.OnServerEvent:Connect(function(player, args))
伺服器 → 客戶端 >
伺服器RemoteEvent:FireClient(player, args)
客戶RemoteEvent.OnClientEvent:Connect(function(args))
伺服器 → 所有客戶端 >
伺服器RemoteEvent:FireAllClients(args)
客戶RemoteEvent.OnClientEvent:Connect(function(args))

遠端事件

一個 RemoteEvent 對象可以在客戶端-伺服器界線上進行一次異步、單向通信,而不需要提供回應。

要在 Studio 中的 RemoteEvent 窗口創建新 Class.RemoteEvent:

  1. 將鼠標指针擺動到你想要插入 RemoteEvent 的容器上。為了確保服務器和客戶端的使用權 通行權 存取,它必須位於 ReplicatedStorageWorkspace 中,雙方都能看到它。在某些情況下,您可以將它存儲在 1>Class.Workspace1> 或
  2. 點擊容器名稱右侧的 按鈕,並插入一個 RemoteEvent 個體、實例。
  3. 重新命名實例來描述其目的。

一旦您創建了 RemoteEvent,它可以從 客戶端到伺服器,從 伺服器到客戶端 或從 2>伺服器到所有客戶端2> 來進行單向通信。

客戶端 → 服務器
伺服器 → 客戶端
服務器 → 所有客戶

客戶端→伺服器

您可以使用 LocalScript 來觸發服務器上的事件,並且在 Class.RemoteEvent:FireServer()|FireServer() 方法上的 Class

客戶RemoteEvent:FireServer(args)
伺服器RemoteEvent.OnServerEvent:Connect(function(player, args))

下列 Script 連接一個伺服器件處理器到 OnServerEvent ,這創建新

事件連接 - 指令碼

local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- 取得遠端事件實個體、實例的引用
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
-- 連接功能到事件
remoteEvent.OnServerEvent:Connect(onCreatePart)
事件發射 - 本地腳本

local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- 取得遠端事件實個體、實例的引用
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- 發射遠端事件並傳送額外參數
remoteEvent:FireServer(Color3.fromRGB(255, 0, 0), Vector3.new(0, 25, -20))

服務器 → 客戶

您可以使用 Script

伺服器RemoteEvent:FireClient(player, args)
客戶RemoteEvent.OnClientEvent:Connect(function(args))

下列 LocalScript 連接一個事件處理器到 OnClientEvent 事件。附加的 Script 然後聆聽來自服務器的玩家,並呼叫 2>Class.RemoteEvent:FireClient()|FireClient()2> 為每個包含任意資料的玩家。

事件連接 - 本地指令碼

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
-- 取得遠端事件實個體、實例的引用
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
-- 連接功能到事件
remoteEvent.OnClientEvent:Connect(onNotifyPlayer)
事件發射 - 指令碼

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
-- 取得遠端事件實個體、實例的引用
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- 聆聽來自玩家的來電,並將遠端事件分配給每個
local function onPlayerAdded(player)
print("[Server] Firing event to player", player.Name)
remoteEvent:FireClient(player, Players.MaxPlayers, Players.RespawnTime)
end
Players.PlayerAdded:Connect(onPlayerAdded)

服務器 → 所有客戶

您可以使用 Script 來觸發所有客戶端的事件,並且在 FireAllClients() 上使用 Class.RemoteEvent:FireAllClients()|Fire

伺服器RemoteEvent:FireAllClients(args)
客戶RemoteEvent.OnClientEvent:Connect(function(args))

下列 LocalScript 連接一個事件處理器到 OnClientEvent 事件,其輸出剩餘倒數時間。接下來的 Script 然後每秒鐘呼叫 1> Class.RemoteEvent:FireAllClients()|

事件連接 - 本地指令碼

local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- 取得遠端事件實個體、實例的引用
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function onTimerUpdate(seconds)
print(seconds)
end
-- 連接功能到事件
remoteEvent.OnClientEvent:Connect(onTimerUpdate)
事件發射 - 指令碼

local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- 取得遠端事件實個體、實例的引用
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local countdown = 5
-- 在時間到達時間為止發射遠端事件
for timeRemaining = -1, countdown do
remoteEvent:FireAllClients(countdown - timeRemaining)
task.wait(1)
end

遠端回撥

Class.RemoteFunction 對象可以在客戶端-伺服器界限上進行同步兩向通信。發送遠端功能的發件將會至少獲得一個回應,直到從收件人獲得回應為止。

要在 Studio 中的 RemoteFunction 窗口創建新 Class.RemoteFunction:

  1. 將鼠標指针擺動到你想要插入 RemoteFunction 的容器上。為了確保服務器和客戶端的使用權 通行權 存取,它必須在兩個方面都能看到的地方,例如 ReplicatedStorageWorkspace 內。在某些情況下,您可以將它存儲在 1>Class.Workspace
  2. 點擊容器名稱右侧的 按鈕,並插入一個 遠程函數 個體、實例。
  3. 重新命名實例來描述其目的。

一旦你創建了 RemoteFunction,它就可以在 客戶端和伺服器 之間或在 服務器和客戶端 之間進行兩向通信。

客戶端 → 伺服器 → 客戶端
伺服器 → 客戶端 → 伺服器

客戶→伺服器→客戶

您可以使用 LocalScript 來在 服務器 上呼叫一個函數,並且在 Class.RemoteFunction:ExecuteServer()|ExecuteServer() 的回

客戶RemoteFunction:InvokeServer(args)
伺服器RemoteFunction.OnServerInvoke = function(player, args)

下列 Script 定義了回潮函數通過 OnServerInvoke 和返回要求的 Part 通過其 1> return1> 值。 附加的 4> Class.LocalScript4> 然

回調連接 - 指令碼

local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- 取得遠端功能實個體、實例的引用
local remoteFunction = ReplicatedStorage:FindFirstChildOfClass("RemoteFunction")
-- 回調函數
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
-- 將函數設為遠端函數的回調
remoteFunction.OnServerInvoke = createPart
事件邀請 - 本地腳本

local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- 取得遠端功能實個體、實例的引用
local remoteFunction = ReplicatedStorage:FindFirstChildOfClass("RemoteFunction")
-- 在呼叫回調時傳送顏色和位置
local newPart = remoteFunction:InvokeServer(Color3.fromRGB(255, 0, 0), Vector3.new(0, 25, -20))
-- 輸出回來的零件參考
print("The server created the requested part:", newPart)

服務器 → 客戶 → 服務器

您可以使用 Script 來在客戶端呼叫功能,但它有以下嚴重風險:

  • 如果客戶端發生錯誤,伺服器也會發生錯誤。
  • 如果客戶端在被邀請時斷開,InvokeClient() 會發生錯誤。
  • 如果客戶端沒有返回值,服務器將永久生成。

對於不需要兩向通訊的操作,例如更新 GUI,請使用 RemoteEvent 並從 服務器到客戶端 通訊。

參數限制

當你發射 RemoteEvent 或呼叫 RemoteFunction 時,它會向任何你與事件或回潮函數通過的參數傳送。任何 Roblox 對象,例如 Enum 、 1> Class.Instance1> 或其他類型的對象都

非字串指數

如果傳送的表中的任何 索引 為非字串類型,例如 Instanceuserdata 或 1> 函數1>,Roblox 會自動將這些索引轉換為字串。

事件連接 - 本地指令碼

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function onEventFire(passedTable)
for k, v in passedTable do
print(typeof(k)) --> 字串
end
end
-- 連接功能到事件
remoteEvent.OnClientEvent:Connect(onEventFire)
事件發射 - 指令碼

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- 聆聽來自玩家的來電,並將遠端事件分配給每個
local function onPlayerAdded(player)
remoteEvent:FireClient(player,
{
[workspace.Baseplate] = true
}
)
end
Players.PlayerAdded:Connect(onPlayerAdded)

已通過的功能

包含在 RemoteEventRemoteFunction 作為參數的函數將不會在 客戶端-伺服器 界線上複製,因此無法遠程傳送功能。相反,在接收端的結果將為 1>nil1> 。

事件連接 - 本地指令碼

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function onClientEvent(func)
print(func) --> 零
end
remoteEvent.OnClientEvent:Connect(onClientEvent)
事件發射 - 指令碼

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function testFunction()
print("Hello world!")
end
-- 作為參引數使用遠端事件
remoteEvent:FireAllClients(testFunction)

桌子索引

如果您通過一個數據表,通過混合表的數字和字串鑰匙,不要通過包含 完整值 的鑰匙值對 (字典) 或包含 完整值 的數據索引。 相反,通過包含 完整值 的鑰匙值對 (字典) 或包含 1> 完整值1> 的數據索引。

事件連接 - 指令碼

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 = 劍
--> 2 = 弓
--> CharName = 女神拖onslayer
--> CharClass = 惡棍
end
end
-- 連接功能到事件
remoteEvent.OnServerEvent:Connect(onEventFire)
事件發射 - 本地腳本

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- 數量化桌子
local inventoryData = {
"Sword", "Bow"
}
-- 字典桌
local characterData = {
CharName = "Diva Dragonslayer",
CharClass = "Rogue"
}
remoteEvent:FireServer(inventoryData)
remoteEvent:FireServer(characterData)

桌子身份

遠端事件/回潮呼叫為參數傳送的桌子將複製,這意味著它們不會正確相等於在發生事件或呼叫回潮時提供的桌子。 也會在發生事件或呼叫回潮時返回的桌子被準確相等。 您可以使用以下脚本在 RemoteFunction 上執行以觀察桌子的差異。

回調連接 - 指令碼

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteFunction = ReplicatedStorage:FindFirstChildOfClass("RemoteFunction")
-- 回調函數
local function returnTable(player, passedTable)
-- 輸入表時輸出表身份
print(tostring(passedTable)) --> 桌子: 0x48eb7aead27563d9
return passedTable
end
-- 將函數設為遠端函數的回調
remoteFunction.OnServerInvoke = returnTable
事件邀請 - 本地腳本

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteFunction = ReplicatedStorage:FindFirstChildOfClass("RemoteFunction")
local inventoryData = {
"Sword", "Bow"
}
-- 輸出原始桌子身份
print(tostring(inventoryData)) --> 桌子: 0x059bcdbb2b576549
local invokeReturn = remoteFunction:InvokeServer(inventoryData)
-- 輸出表傳回號碼
print(tostring(invokeReturn)) --> table: 0x9fcae7919563a0e9

金屬表

如果桌子有 metatable,所有的 metatable 資訊都會在轉移中丟失。 在下一個代碼示例中, NumWheels 屬性是 Car 的一部分。當服務器收到下一個表時, truck 桌子包含 2>Name

事件連接 - 指令碼

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function onEvent(player, param)
print(param) --> { ["Name"] = "MyTruck"
end
-- 連接功能到事件
remoteEvent.OnServerEvent:Connect(onEvent)
事件發射 - 本地腳本

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)
-- 包含 metable 的火焰事件
remoteEvent:FireServer(truck)

非複製的實例

如果 RemoteEventRemoteFunction 傳輸值只有發件人可以看到,Roblox 不會在客戶端-伺服器界線上重複它,而是會傳輸 nil

事件發射 - 指令碼

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerStorage = game:GetService("ServerStorage")
local Players = game:GetService("Players")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- 會被視為 "nil",因為客戶端無法存取 ServerStorage
local storedPart = Instance.new("Part")
storedPart.Parent = ServerStorage
local function onPlayerAdded(player)
remoteEvent:FireClient(player, storedPart)
end
Players.PlayerAdded:Connect(onPlayerAdded)

同樣地,如果您在 LocalScript 中創建了零件,並且嘗試將它傳到 Script ,服務器會看到 nil 因為零件對於服務伺服器來說不可重複。

事件發射 - 本地腳本

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- 會被視為 "nil" 因為伺服器不知道這個部分
local clientPart = Instance.new("Part")
clientPart.Parent = workspace
remoteEvent:FireServer(clientPart)