Peristiwa remote dan callback

*Konten ini diterjemahkan menggunakan AI (Beta) dan mungkin mengandung kesalahan. Untuk melihat halaman ini dalam bahasa Inggris, klik di sini.

Game Roblox adalah permainan multipemain secara default, sehingga semua permainan secara inheren berkomunikasi antara server dan klien yang terhubung dengan pemain. Dalam kasus yang paling sederhana, ketika pemain menggerakkan karakter mereka, properti tertentu dari Humanoid, seperti status, dikomunikasikan ke server, yang kemudian meneruskan informasi ini ke klien lain yang terhubung.

Peristiwa remote dan callback memungkinkan Anda untuk berkomunikasi melalui batasan klien-server:

  • RemoteEvents memungkinkan komunikasi satu arah (mengirim permintaan dan tidak menunggu respons).
  • UnreliableRemoteEvents memungkinkan komunikasi satu arah untuk data yang terus-menerus berubah atau tidak kritis terhadap status permainan. Peristiwa ini mengorbankan urutan dan keandalan demi meningkatkan kinerja jaringan.
  • RemoteFunctions memungkinkan komunikasi dua arah (mengirim permintaan dan menunggu hingga respons diterima dari penerima).

Berbeda dengan peristiwa yang dapat diikat, yang memiliki utilitas yang lebih terbatas, kasus penggunaan untuk peristiwa remote dan fungsi terlalu banyak untuk dicantumkan:

  • Gameplay - Gameplay dasar, seperti seorang pemain mencapai akhir level, dapat memerlukan peristiwa remote. Sebuah skrip klien memberi tahu server, dan skrip server mereset posisi pemain.
  • Verifikasi server - Jika seorang pemain mencoba meminum ramuan, apakah mereka benar-benar memiliki ramuan itu? Untuk memastikan keadilan, server harus menjadi sumber kebenaran untuk sebuah permainan. Skrip klien dapat menggunakan peristiwa remote untuk memberi tahu server bahwa pemain sedang meminum ramuan, dan kemudian skrip server dapat memutuskan apakah pemain benar-benar memiliki ramuan tersebut dan apakah akan memberikan manfaat.
  • Pembaruan antarmuka pengguna - Ketika status permainan berubah, skrip server dapat menggunakan peristiwa remote untuk memberi tahu klien tentang perubahan skor, tujuan, dll.
  • Pembelian marketplace dalam permainan - Untuk implementasi contoh yang menggunakan fungsi remote, lihat Pembelian langganan prompt.

Referensi Cepat

Tabel berikut berfungsi sebagai referensi cepat untuk cara menggunakan RemoteEvents dan RemoteFunctions untuk berkomunikasi antara klien dan server.

Klien → Server
KlienRemoteEvent:FireServer(args)
ServerRemoteEvent.OnServerEvent:Connect(function(player, args))
Server → Klien
ServerRemoteEvent:FireClient(player, args)
KlienRemoteEvent.OnClientEvent:Connect(function(args))
Server → Semua Klien
ServerRemoteEvent:FireAllClients(args)
KlienRemoteEvent.OnClientEvent:Connect(function(args))

Peristiwa Remote

Objek RemoteEvent memfasilitasi komunikasi asinkron, satu arah di antara batasan klien-server tanpa menunggu respons.

Untuk membuat RemoteEvent baru melalui jendela Explorer di Studio:

  1. Arahkan kursor ke wadah tempat Anda ingin memasukkan RemoteEvent. Untuk memastikan akses baik dari server maupun klien, ia harus berada di tempat di mana kedua sisi dapat melihatnya, seperti di ReplicatedStorage, meskipun dalam beberapa kasus adalah hal yang tepat untuk menyimpannya di Workspace atau di dalam Tool.
  2. Klik tombol yang muncul di sebelah kanan nama wadah dan masukkan instance RemoteEvent.
  3. Ubah nama instance untuk menjelaskan tujuannya.

Setelah Anda membuat RemoteEvent, ia dapat memfasilitasi komunikasi satu arah dari klien ke server, dari server ke klien, atau dari server ke semua klien.

Klien → Server
Server → Klien
Server → Semua Klien

Klien → server

Anda dapat menggunakan LocalScript untuk memicu peristiwa di server dengan memanggil metode FireServer() pada RemoteEvent. Jika Anda meneruskan argumen ke FireServer(), argumen tersebut diteruskan ke pengendali peristiwa di server dengan batasan tertentu batasan argumen. Perhatikan bahwa parameter pertama dari pengendali peristiwa di server selalu merupakan objek Player dari klien yang memanggilnya, dan parameter tambahan mengikuti.

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

Script Script berikut menghubungkan pengendali peristiwa ke OnServerEvent yang membuat Part baru di server. LocalScript yang menyertainya kemudian memanggil FireServer() pada instance RemoteEvent dengan Color dan Position yang diinginkan untuk bagian tersebut.

Koneksi Peristiwa - Script

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Workspace = game:GetService("Workspace")
-- Dapatkan referensi ke instance peristiwa remote
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function onCreatePart(player, partColor, partPosition)
print(player.Name .. " memicu RemoteEvent")
local newPart = Instance.new("Part")
newPart.Color = partColor
newPart.Position = partPosition
newPart.Parent = Workspace
end
-- Hubungkan fungsi ke peristiwa
remoteEvent.OnServerEvent:Connect(onCreatePart)
Pemicu Peristiwa - LocalScript

local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Dapatkan referensi ke instance peristiwa remote
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- Memicu peristiwa remote dan meneruskan argumen tambahan
remoteEvent:FireServer(Color3.fromRGB(255, 0, 0), Vector3.new(0, 25, -20))

Server → klien

Anda dapat menggunakan Script untuk memicu peristiwa di klien dengan memanggil metode FireClient() pada RemoteEvent. Argumen pertama untuk FireClient() adalah objek Player dari klien yang ingin Anda tanggapi peristiwa tersebut, dan argumen tambahan diteruskan ke klien dengan batasan tertentu batasan argumen. Perhatikan bahwa pengendali peristiwa tidak perlu menyertakan objek Player sebagai argumen pertamanya karena Anda dapat menentukan pemain di klien dengan Players.LocalPlayer.

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

Script LocalScript berikut menghubungkan pengendali peristiwa ke peristiwa OnClientEvent. Skrip Script yang menyertainya kemudian mendengarkan pemain yang masuk ke server dan memanggil FireClient() untuk setiap pemain dengan data acak.

Koneksi Peristiwa - LocalScript

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
-- Dapatkan referensi ke instance peristiwa remote
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local player = Players.LocalPlayer
local function onNotifyPlayer(maxPlayers, respawnTime)
print("[Klien] Peristiwa diterima oleh pemain", player.Name)
print(maxPlayers, respawnTime)
end
-- Hubungkan fungsi ke peristiwa
remoteEvent.OnClientEvent:Connect(onNotifyPlayer)
Pemicu Peristiwa - Script

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
-- Dapatkan referensi ke instance peristiwa remote
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- Dengarkan pemain yang masuk dan kirim peristiwa remote ke masing-masing
local function onPlayerAdded(player)
print("[Server] Memicu peristiwa untuk pemain", player.Name)
remoteEvent:FireClient(player, Players.MaxPlayers, Players.RespawnTime)
end
Players.PlayerAdded:Connect(onPlayerAdded)

Server → semua klien

Anda dapat menggunakan Script untuk memicu peristiwa di semua klien dengan memanggil metode FireAllClients() pada RemoteEvent. Berbeda dengan FireClient(), metode FireAllClients() tidak memerlukan objek Player karena itu memicu RemoteEvent ke semua klien.

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

Script LocalScript berikut menghubungkan pengendali peristiwa ke peristiwa OnClientEvent yang menampilkan waktu hitung mundur yang tersisa. Skrip Script yang menyertainya kemudian memanggil FireAllClients() dalam loop setiap detik untuk memicu RemoteEvent untuk semua klien.

Koneksi Peristiwa - LocalScript

local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Dapatkan referensi ke instance peristiwa remote
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function onTimerUpdate(seconds)
print(seconds)
end
-- Hubungkan fungsi ke peristiwa
remoteEvent.OnClientEvent:Connect(onTimerUpdate)
Pemicu Peristiwa - Script

local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Dapatkan referensi ke instance peristiwa remote
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local countdown = 5
-- Memicu RemoteEvent setiap detik hingga waktu habis
for timeRemaining = -1, countdown do
remoteEvent:FireAllClients(countdown - timeRemaining)
task.wait(1)
end

Callback Remote

Objek RemoteFunction memfasilitasi komunikasi sinkron, dua arah di antara batasan klien-server. Pengirim fungsi remote akan menunggu hingga menerima respons dari penerima.

Untuk membuat RemoteFunction baru melalui jendela Explorer di Studio:

  1. Arahkan kursor ke wadah tempat Anda ingin memasukkan RemoteFunction. Untuk memastikan akses baik dari server maupun klien, ia harus berada di tempat di mana kedua sisi dapat melihatnya, seperti di ReplicatedStorage, meskipun dalam beberapa kasus adalah hal yang tepat untuk menyimpannya di Workspace atau di dalam Tool.
  2. Klik tombol yang muncul di sebelah kanan nama wadah dan masukkan instance RemoteFunction.
  3. Ubah nama instance untuk menjelaskan tujuannya.

Setelah Anda membuat RemoteFunction, ia dapat memfasilitasi komunikasi dua arah antara klien dan server atau antara server dan klien.

Klien → Server → Klien
Server → Klien → Server

Klien → server → klien

Anda dapat menggunakan LocalScript untuk memanggil fungsi di server dengan memanggil metode InvokeServer() pada RemoteFunction. Berbeda dengan peristiwa remote, LocalScript yang memanggil RemoteFunction menunggu hingga callback mengembalikan hasil. Argumen yang Anda teruskan ke InvokeServer() diteruskan ke callback OnServerInvoke dari RemoteFunction dengan batasan tertentu batasan argumen. Perhatikan bahwa jika Anda mendefinisikan beberapa callback untuk RemoteFunction yang sama, hanya definisi terakhir yang akan dieksekusi.

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

Script Script berikut mendefinisikan fungsi callback melalui OnServerInvoke dan mengembalikan Part yang diminta melalui nilai return-nya. Skrip LocalScript yang menyertainya kemudian memanggil InvokeServer() dengan argumen tambahan yang mendefinisikan warna dan posisi bagian yang diminta.

Koneksi Callback - Script

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Workspace = game:GetService("Workspace")
-- Dapatkan referensi ke instance fungsi remote
local remoteFunction = ReplicatedStorage:FindFirstChildOfClass("RemoteFunction")
-- Fungsi callback
local function createPart(player, partColor, partPosition)
print(player.Name .. " meminta sebuah bagian baru")
local newPart = Instance.new("Part")
newPart.Color = partColor
newPart.Position = partPosition
newPart.Parent = Workspace
return newPart
end
-- Atur fungsi sebagai callback untuk fungsi remote
remoteFunction.OnServerInvoke = createPart
Pemanggilan Peristiwa - LocalScript

local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Dapatkan referensi ke instance fungsi remote
local remoteFunction = ReplicatedStorage:FindFirstChildOfClass("RemoteFunction")
-- Meneruskan warna dan posisi saat memanggil callback
local newPart = remoteFunction:InvokeServer(Color3.fromRGB(255, 0, 0), Vector3.new(0, 25, -20))
-- Output referensi bagian yang dikembalikan
print("Server membuat bagian yang diminta:", newPart)

Server → klien → server

Anda dapat menggunakan Script untuk memanggil fungsi di klien dengan memanggil metode InvokeClient() pada RemoteFunction, tetapi ini memiliki risiko serius sebagai berikut:

  • Jika klien mengeluarkan kesalahan, server juga akan menghasilkan kesalahan.
  • Jika klien terputus saat dipanggil, InvokeClient() mengeluarkan kesalahan.
  • Jika klien tidak mengembalikan nilai, server akan menunggu selamanya.

Untuk aksi yang tidak memerlukan komunikasi dua arah, seperti memperbarui antarmuka pengguna, gunakan RemoteEvent dan berkomunikasi dari server ke klien.

Batasan Argumen

Ketika Anda memicu RemoteEvent atau memanggil RemoteFunction, ia meneruskan argumen apa pun yang Anda teruskan dengan peristiwa atau fungsi callback. Jenis objek Roblox apa pun seperti Enum, Instance, atau lainnya dapat diteruskan, serta tipe-tipe Luau seperti angka, string, dan boolean, meskipun Anda harus mencermati batasan berikut.

Indeks non-string

Jika ada indeks dari tabel yang diteruskan adalah tipe non-string seperti Instance, userdata, atau fungsi, Roblox secara otomatis mengkonversi indeks tersebut menjadi string.

Koneksi Peristiwa - 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
-- Hubungkan fungsi ke peristiwa
remoteEvent.OnClientEvent:Connect(onEventFire)
Pemicu Peristiwa - Script

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local Workspace = game:GetService("Workspace")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- Dengarkan pemain yang masuk dan kirim peristiwa remote ke masing-masing
local function onPlayerAdded(player)
remoteEvent:FireClient(player,
{
[Workspace.Baseplate] = true
}
)
end
Players.PlayerAdded:Connect(onPlayerAdded)

Fungsi yang diteruskan

Fungsi yang disertakan sebagai argumen untuk RemoteEvent atau RemoteFunction tidak akan direplikasi melintasi batasan klien-server, sehingga tidak mungkin untuk meneruskan fungsi secara remote. Sebaliknya, argumen yang dihasilkan di sisi penerima akan menjadi nil.

Koneksi Peristiwa - LocalScript

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

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function testFunction()
print("Hallo dunia!")
end
-- Memicu peristiwa remote dengan fungsi sebagai argumen
remoteEvent:FireAllClients(testFunction)

Indeks Tabel

Jika Anda meneruskan tabel data, jangan meneruskan tabel campuran dari kunci numerik dan string. Sebagai gantinya, kirimkan tabel yang terdiri sepenuhnya dari pasangan kunci-nilai (kamus) atau sepenuhnya dari indeks numerik.

Koneksi Peristiwa - 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 = Pedang
--> 2 = Busur
--> CharName = Diva Dragonslayer
--> CharClass = Rogue
end
end
-- Hubungkan fungsi ke peristiwa
remoteEvent.OnServerEvent:Connect(onEventFire)
Pemicu Peristiwa - LocalScript

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- Tabel yang diindeks secara numerik
local inventoryData = {
"Pedang", "Busur"
}
-- Tabel kamus
local characterData = {
CharName = "Diva Dragonslayer",
CharClass = "Rogue"
}
remoteEvent:FireServer(inventoryData)
remoteEvent:FireServer(characterData)

Identitas Tabel

Tabel yang diteruskan sebagai argumen untuk peristiwa remote/callback disalin, artinya mereka tidak akan identik persis dengan yang diberikan saat memicu peristiwa atau memanggil callback. Tabel yang dikembalikan kepada pemanggil juga tidak akan identik persis dengan yang diberikan. Anda dapat menunjukkan hal ini dengan menjalankan skrip berikut pada RemoteFunction dan mengamati bagaimana identitas tabel berbeda.

Koneksi Callback - Script

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteFunction = ReplicatedStorage:FindFirstChildOfClass("RemoteFunction")
-- Fungsi callback
local function returnTable(player, passedTable)
-- Output identitas tabel saat pemanggilan
print(tostring(passedTable)) --> table: 0x48eb7aead27563d9
return passedTable
end
-- Atur fungsi sebagai callback untuk fungsi remote
remoteFunction.OnServerInvoke = returnTable
Pemanggilan Peristiwa - LocalScript

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteFunction = ReplicatedStorage:FindFirstChildOfClass("RemoteFunction")
local inventoryData = {
"Pedang", "Busur"
}
-- Output identitas tabel asli
print(tostring(inventoryData)) --> table: 0x059bcdbb2b576549
local invokeReturn = remoteFunction:InvokeServer(inventoryData)
-- Output identitas tabel saat kembali
print(tostring(invokeReturn)) --> table: 0x9fcae7919563a0e9

Metatables

Jika sebuah tabel memiliki metatable, semua informasi metatable hilang dalam transfer. Dalam contoh kode berikut, properti NumWheels adalah bagian dari metatable Car. Ketika server menerima tabel berikut, tabel truck memiliki properti Name tetapi tidak memiliki properti NumWheels.

Koneksi Peristiwa - Script

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function onEvent(player, param)
print(param) --> {["Name"] = "MyTruck"}
end
-- Hubungkan fungsi ke peristiwa
remoteEvent.OnServerEvent:Connect(onEvent)
Pemicu Peristiwa - 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)
-- Memicu peristiwa dengan tabel yang menyertakan metatable
remoteEvent:FireServer(truck)

Instance yang tidak direplikasi

Jika sebuah RemoteEvent atau RemoteFunction meneruskan nilai yang hanya terlihat oleh pengirim, Roblox tidak mereplikasinya melintasi batasan klien-server dan meneruskan nil sebagai ganti nilai tersebut. Sebagai contoh, jika sebuah Script meneruskan keturunan dari ServerStorage, maka klien yang mendengarkan peristiwa tersebut akan menerima nilai nil karena objek tersebut tidak dapat direplikasi untuk klien.

Pemicu Peristiwa - Script

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerStorage = game:GetService("ServerStorage")
local Players = game:GetService("Players")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- Akan diterima sebagai "nil" karena klien tidak dapat mengakses ServerStorage
local storedPart = Instance.new("Part")
storedPart.Parent = ServerStorage
local function onPlayerAdded(player)
remoteEvent:FireClient(player, storedPart)
end
Players.PlayerAdded:Connect(onPlayerAdded)

Demikian pula, jika Anda membuat sebuah bagian dalam LocalScript dan mencoba meneruskannya ke Script, server akan melihat nil karena bagian tersebut tidak dapat direplikasi untuk server.

Pemicu Peristiwa - LocalScript

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Workspace = game:GetService("Workspace")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- Akan diterima sebagai "nil" karena server tidak mengetahui bagian ini
local clientPart = Instance.new("Part")
clientPart.Parent = Workspace
remoteEvent:FireServer(clientPart)
©2026 Roblox Corporation. Roblox, logo Roblox, dan Powering Imagination termasuk dalam merek dagang kami yang terdaftar dan tidak terdaftar di AS dan negara lainnya.