Acara dan panggilan balasan jarak jauh

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

Pengalaman Roblox secara default adalah multiplayer, jadi semua pengalaman secara inheren berkomunikasi antara server dan klien terhubung pemain.Dalam kasus paling sederhana, saat pemain memindahkan karakter mereka, beberapa properti Humanoid khusus, seperti negara, dikomunikasikan ke server, yang mengirimkan informasi ini ke klien terhubung lainnya.

Acara dan panggilan jarak jauh memungkinkan Anda berkomunikasi melintasi batas klien-server:

  • RemoteEvents aktifkan komunikasi satu arah (mengirim permintaan dan tidak menyerahkan untuk respons).
  • UnreliableRemoteEvents aktifkan komunikasi satu arah untuk data yang berubah terus menerus atau tidak kritis untuk status permainan.Peristiwa ini memesan perdagangan dan keandalan untuk meningkatkan pelaksanaanjaringan.
  • RemoteFunctions aktifkan komunikasi dua arah (mengirim permintaan dan menyerah sampai respons diterima dari penerima).

Tidak seperti peristiwa yang dapat diikat , yang memiliki utilitas yang lebih terbatas, kasus penggunaan untuk acara dan fungsi jarak jauh terlalu banyak untuk dicantumkan:

  • Permainan - gameplaydasar, seperti pemain mencapai akhir level, dapat memerlukan acara remote.Skrip klien memberi tahu server, dan skrip server mengatur ulang posisi pemain.
  • Verifikasi server - Jika seorang pemain mencoba minum ramuan, apakah mereka benar-benar memiliki ramuan itu? Untuk memastikan keadilan, server harus menjadi sumber kebenaran untuk pengalaman.Skrip klien dapat menggunakan acara remote untuk memberi tahu server bahwa pemain minum ramuan, dan kemudian skrip server dapat memutuskan apakah pemain benar-benar memiliki ramuan itu dan apakah akan memberikan manfaat.
  • Pembaruan antarmuka pengguna - Saat status permainan berubah, skrip server dapat menggunakan peristiwa remote untuk memberi tahu klien tentang perubahan skor, tujuan, dll
  • Pembelian Pasar Pengalaman dalam pengalaman - Untuk contoh implementasi yang menggunakan fungsi remote, lihat Pembelian langganan segera.

Referensi cepat

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

>
Klien → Server >
PelangganRemoteEvent:FireServer(args)
PelayanRemoteEvent.OnServerEvent:Connect(function(player, args))
Server → Klien >
PelayanRemoteEvent:FireClient(player, args)
PelangganRemoteEvent.OnClientEvent:Connect(function(args))
Server → Semua Klien >
PelayanRemoteEvent:FireAllClients(args)
PelangganRemoteEvent.OnClientEvent:Connect(function(args))

Acara jarak jauh

Sebuah objek RemoteEvent memudahkan komunikasi asinkron, satu arah melintasi batas klien-server tanpa menghasilkan respons.

Untuk membuat baru RemoteEvent melalui jendela Explorer di Studio:

  1. Pasang di atas wadah ke dalam mana Anda ingin menyisipkan RemoteEvent .Untuk memastikan akses server dan klien, itu harus berada di tempat di mana kedua belah pihak dapat melihatnya, seperti ReplicatedStorage , meskipun dalam beberapa kasus tepat untuk menyimpannya di Workspace atau di dalam Tool .
  2. Klik tombol yang muncul di sebelah kanan nama kontainer dan masukkan instansi RemoteEvent .
  3. Ganti nama instansi untuk menggambarkan tujuannya.

Setelah Anda membuat RemoteEvent , itu dapat memudahkan 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 untuk memicu peristiwa di server dengan memanggil metode pada .Jika Anda memberikan argumen ke , mereka dikirim ke penangan acara di server dengan batasan tertentu .Perhatikan bahwa parameter pertama dari penangani acara di server selalu objek Player klien yang memanggilnya, dan parameter tambahan mengikuti.

PelangganRemoteEvent:FireServer(args)
PelayanRemoteEvent.OnServerEvent:Connect(function(player, args))

Berikut adalah Script yang menghubungkan pengelola acara ke OnServerEvent yang membuat baru Part di server.The accompanying LocalScript kemudian memanggil FireServer() pada instance RemoteEvent dengan Color dan Position untuk bagiannya.

Koneksi Acara - Skrip

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Workspace = game:GetService("Workspace")
-- Dapatkan referensi ke instansi acara kejadian
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
-- Hubungkan fungsi ke acara
remoteEvent.OnServerEvent:Connect(onCreatePart)
Pembakaran Acara - Skrip Lokal

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

Server → klien

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

PelayanRemoteEvent:FireClient(player, args)
PelangganRemoteEvent.OnClientEvent:Connect(function(args))

Berikut adalah LocalScript yang menghubungkan pengelola acara ke acara OnClientEvent.The accompanying Script kemudian mendengarkan pemain yang masuk ke server dan memanggil FireClient() untuk masing-masing dengan data acak.

Koneksi Acara - Skrip Lokal

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
-- Dapatkan referensi ke instansi acara kejadian
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
-- Hubungkan fungsi ke acara
remoteEvent.OnClientEvent:Connect(onNotifyPlayer)
Pembakaran Acara - Skrip

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
-- Dapatkan referensi ke instansi acara kejadian
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- Dengarkan pemain yang masuk dan kirimkan acara remote ke masing-masing
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 → semua klien

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

PelayanRemoteEvent:FireAllClients(args)
PelangganRemoteEvent.OnClientEvent:Connect(function(args))

Berikut adalah LocalScript yang menghubungkan pengelola acara ke acara OnClientEvent yang menghasilkan waktu hitung mundur yang tersisa.The accompanying Script kemudian memanggil FireAllClients() dalam loop setiap detik untuk menembakkan RemoteEvent untuk semua klien.

Koneksi Acara - Skrip Lokal

local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Dapatkan referensi ke instansi acara kejadian
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function onTimerUpdate(seconds)
print(seconds)
end
-- Hubungkan fungsi ke acara
remoteEvent.OnClientEvent:Connect(onTimerUpdate)
Pembakaran Acara - Skrip

local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Dapatkan referensi ke instansi acara kejadian
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local countdown = 5
-- Mematikan Acara Jarak Jauh setiap detik sampai waktu habis
for timeRemaining = -1, countdown do
remoteEvent:FireAllClients(countdown - timeRemaining)
task.wait(1)
end

Panggilan balasan remote

Sebuah objek RemoteFunction memudahkan komunikasi sinkron dua arah melintasi batas klien-server.Pengirim fungsi remote akan menghasilkan sampai menerima respons dari penerima.

Untuk membuat baru RemoteFunction melalui jendela Explorer di Studio:

  1. Pasang di atas wadah ke dalam mana Anda ingin menyisipkan RemoteFunction .Untuk memastikan akses server dan klien, itu harus berada di tempat di mana kedua belah pihak dapat melihatnya, seperti ReplicatedStorage , meskipun dalam beberapa kasus tepat untuk menyimpannya di Workspace atau di dalam Tool .
  2. Klik tombol yang muncul di sebelah kanan nama kontainer dan masukkan instansi Fungsi Jarak Jauh .
  3. Ganti nama instansi untuk menggambarkan tujuannya.

Setelah Anda membuat RemoteFunction , itu dapat memudahkan komunikasi dua arah antara klien dan server atau antara server dan klien .

Klien → Server → Klien
>

Server → Klien → Server
>

Client → server → klien

Anda dapat menggunakan untuk memanggil fungsi di server dengan memanggil metode di .Tidak seperti acara remote , LocalScript yang memanggil RemoteFunction sampai callback kembali.Argumen yang Anda berikan ke dikirim ke panggil balik dari dengan batasan tertentu .Perhatikan bahwa jika Anda mendefinisikan banyak panggilan balasan ke RemoteFunction yang sama, hanya definisi terakhir yang dieksekusi.

PelangganRemoteFunction:InvokeServer(args)
PelayanRemoteFunction.OnServerInvoke = function(player, args)

Berikut adalah Script definisikan fungsi panggil balas melalui OnServerInvoke dan kembalikan permintaan Part melalui nilainya return.The accompanying LocalScript kemudian memanggil InvokeServer() dengan argumen tambahan yang mendefinisikan warna dan posisi bagian yang diminta.

Koneksi Panggil Balik - Skrip

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Workspace = game:GetService("Workspace")
-- Dapatkan referensi ke kejadianfungsi remote
local remoteFunction = ReplicatedStorage:FindFirstChildOfClass("RemoteFunction")
-- Fungsi panggil kembali
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
-- Tetapkan fungsi sebagai panggil balik fungsi remote
remoteFunction.OnServerInvoke = createPart
Panggilan Acara - LocalScript

local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Dapatkan referensi ke kejadianfungsi remote
local remoteFunction = ReplicatedStorage:FindFirstChildOfClass("RemoteFunction")
-- Lewati warna dan posisi saat memanggil kembali
local newPart = remoteFunction:InvokeServer(Color3.fromRGB(255, 0, 0), Vector3.new(0, 25, -20))
-- Output referensi bagian yang dikembalikan
print("The server created the requested part:", newPart)

Server → klien → server

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

  • Jika klien membuang kesalahan, server juga membuang kesalahan.
  • Jika klien terputus saat sedang diaktifkan, InvokeClient() membuang kesalahan.
  • Jika klien tidak mengembalikan nilai, server menghasilkan selamanya.

Untuk tindakan yang tidak memerlukan komunikasi dua arah, seperti memperbarui GUI, gunakan RemoteEvent dan berkomunikasi dari server ke klien .

Keterbatasan argumen

Ketika Anda menembakkan RemoteEvent atau memanggil RemoteFunction , ia mengirimkan argumen apa pun yang Anda berikan dengan peristiwa atau ke fungsi panggil balik.Setiap jenis objek Roblox seperti Enum , Instance , atau lainnya dapat dilewati, serta jenis Luau seperti angka, string, dan boolean, meskipun Anda harus hati-hati mengeksplorasi batasan berikut.

Indeks non-teks

Jika ada indeks dari tabel yang lewat tidak berjenis string seperti Instance , data pengguna , atau fungsi , Roblox secara otomatis mengubah indeks tersebut menjadi string.

Koneksi Acara - Skrip Lokal

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 acara
remoteEvent.OnClientEvent:Connect(onEventFire)
Pembakaran Acara - Skrip

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 kirimkan acara remote ke masing-masing
local function onPlayerAdded(player)
remoteEvent:FireClient(player,
{
[Workspace.Baseplate] = true
}
)
end
Players.PlayerAdded:Connect(onPlayerAdded)

Fungsi yang dilewati

Fungsi yang termasuk sebagai argumen untuk RemoteEvent atau RemoteFunction akan tidak direplikasi di luar batas klien-server, sehingga tidak mungkin untuk mengirim fungsi secara remote.Sebagai gantinya, argumen yang dihasilkan di sisi penerima akan menjadi nil .

Koneksi Acara - Skrip Lokal

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function onClientEvent(func)
print(func) --> tidak ada
end
remoteEvent.OnClientEvent:Connect(onClientEvent)
Pembakaran Acara - Skrip

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

Pengindeksan meja

Jika Anda melewati tabel data, jangan lewati tabel campuran kunci numerik dan string.Sebagai gantinya, lewati tabel yang terdiri dari seluruhnya pasangan nilai-kunci (diction) atau seluruhnya indeks numerik.

Koneksi Acara - Skrip

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 = Lengkung
--> Nama Karakter = Diva Dragonslayer
--> CharClass = Penipu
end
end
-- Hubungkan fungsi ke acara
remoteEvent.OnServerEvent:Connect(onEventFire)
Pembakaran Acara - Skrip Lokal

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

Identitas tabel

Tabel yang ditransmisikan sebagai argumen ke acara jarak jauh/panggilan balasan disalin, artinya mereka tidak akan persis sama dengan yang disediakan saat menembakkan acara atau memanggil balasan.Juga, tabel tidak akan dikembalikan ke invoker persis sama dengan yang disediakan.Anda dapat menunjukkan ini dengan menjalankan skrip berikut di RemoteFunction dan mengamati bagaimana identitas tabel berbeda.

Koneksi Panggil Balik - Skrip

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteFunction = ReplicatedStorage:FindFirstChildOfClass("RemoteFunction")
-- Fungsi panggil kembali
local function returnTable(player, passedTable)
-- Identitas tabel output pada panggilan
print(tostring(passedTable)) --> tabel: 0x48eb7aead27563d9
return passedTable
end
-- Tetapkan fungsi sebagai panggil balik fungsi remote
remoteFunction.OnServerInvoke = returnTable
Panggilan Acara - LocalScript

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

Metabel

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

Koneksi Acara - Skrip

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function onEvent(player, param)
print(param) --> { ["Nama"] = "MyTruck"]
end
-- Hubungkan fungsi ke acara
remoteEvent.OnServerEvent:Connect(onEvent)
Pembakaran Acara - Skrip Lokal

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)
-- Acara api dengan meja termasuk metabel
remoteEvent:FireServer(truck)

Instansi tidak direplikasi

Jika RemoteEvent atau RemoteFunction melewati nilai yang hanya terlihat oleh pengirim, Roblox tidak menyalinnya melintasi batas klien-server dan melewati nil nilai sebagai gantinya.Sebagai contoh, jika sebuah Script melewati keturunan dari ServerStorage , klien yang mendengarkan acara akan menerima nilai nil karena objek itu tidak dapat direplikasi untuk klien.

Pembakaran Acara - Skrip

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerStorage = game:GetService("ServerStorage")
local Players = game:GetService("Players")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- Akan diterima sebagai "nol" 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 bagian di LocalScript dan mencoba mengirimkannya ke Script , server akan melihat nil karena bagian tidak dapat direplikasi untuk server.

Pembakaran Acara - Skrip Lokal

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Workspace = game:GetService("Workspace")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- Akan diterima sebagai "nol" karena server tidak tahu tentang bagian ini
local clientPart = Instance.new("Part")
clientPart.Parent = Workspace
remoteEvent:FireServer(clientPart)