원격 이벤트 및 콜백

*이 콘텐츠는 AI(베타)를 사용해 번역되었으며, 오류가 있을 수 있습니다. 이 페이지를 영어로 보려면 여기를 클릭하세요.

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))

원격 이벤트

A RemoteEvent 개체는 응답을 포기하지 않고 클라이언트-서버 경계에서 비동기, 일방향 통신을 용이하게 합니다.

Studio의 RemoteEvent 창을 통해 새로운 를 만들려면:

  1. RemoteEvent를 삽입하려는 컨테이너에 마우스를 이동합니다.서버와 클라이언트 액세스를 모두 보장하려면 서로 볼 수 있는 장소에 있어야 하며, ReplicatedStorage , 어떤 경우에는 Workspace 또는 내부의 Tool 에 저장하는 것이 적절합니다.
  2. 컨테이너의 이름 오른쪽에 나타나는 버튼을 클릭하고 원격 이벤트 인스턴스를 삽입합니다.
  3. 목적을 설명하기 위해 인스턴스 이름을 바꿉니다.

를 만든 후에는 클라이언트에서 서버로의 일방 통신, 서버에서 클라이언트로의 일방 통신 또는 서버에서 모든 클라이언트로의 일방 통신을 용이하게 할 수 있습니다.

클라이언트 → 서버
>

서버 → 클라이언트
>

서버 → 모든 클라이언트
>

클라이언트 → 서버

서버에서 이벤트를 트리거하기 위해 메서드를 호출하여 방법을 사용하여 서버에서 이벤트를 트리거할 수 있습니다.FireServer() 에 인수를 전달하면 특정 제한 을 가진 서버의 이벤트 처리기로 전달됩니다.서버의 이벤트 처리기의 첫 번째 매개 변수는 항상 호출하는 클라이언트의 Player 개체이며, 추가 매개 팔로우따릅니다.

클라이ентRemoteEvent:FireServer(args)
서버RemoteEvent.OnServerEvent:Connect(function(player, args))

다음 는 서버에서 새로운 를 생성하는 이벤트 처리기에 연결합니다.그런 다음 동반 는 원하는 및 부품에 대한 을 호출합니다.

이벤트 연결 - 스크립트

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Workspace = game:GetService("Workspace")
-- 원격 이벤트 인스턴스에 대한 참조 가져오기
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
-- 연결 함수를 이벤트에 연결 Connect function to event
remoteEvent.OnServerEvent:Connect(onCreatePart)
이벤트 발사 - LocalScript

local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- 원격 이벤트 인스턴스에 대한 참조 가져오기
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- 원격 이벤트 발사 및 추가 인수 전달
remoteEvent:FireServer(Color3.fromRGB(255, 0, 0), Vector3.new(0, 25, -20))

서버 → 클라이언트

클라이언트에서 이벤트를 트리거하기 위해 메서드를 호출하여 클라이언트 에서 이벤트를 트리거할 수 있습니다.FireClient() 의 첫 번째 인수는 이벤트에 응답하려는 클라이언트의 객체 Player 이며, 추가 인수는 특정 제한 으로 클라이언트에 전달됩니다.이벤트 처리기는 Player 개체를 첫 번째 인수로 포함할 필요가 없으므로 클라이언트에서 플레이어를 결정할 수 있기 때문에 첫 번째 인수로 Players.LocalPlayer 개체를 포함할 필요가 없습니다.

서버RemoteEvent:FireClient(player, args)
클라이ентRemoteEvent.OnClientEvent:Connect(function(args))

다음 LocalScript 이벤트 처리기를 OnClientEvent 이벤트에 연결합니다.그런 다음 동반 Script 서버에 들어오는 플레이어를 수신하고 각각에 임의의 데이터로 FireClient() 호출합니다.

이벤트 연결 - LocalScript

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
-- 연결 함수를 이벤트에 연결 Connect function to event
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() 메서드를 사용하여 RemoteEvent에서 이벤트를 트리거할 수 있습니다.FireClient() 과는 달리, FireAllClients() 메서드는 모든 클라이언트에게 Player 을 발사하기 때문에 RemoteEvent 개체가 필요하지 않습니다.

서버RemoteEvent:FireAllClients(args)
클라이ентRemoteEvent.OnClientEvent:Connect(function(args))

다음 LocalScript 는 남은 카운트다운 시간을 출력하는 OnClientEvent 이벤트에 이벤트 처리기를 연결합니다.그런 다음 동반 는 매 초마다 루프에서 호출하여 모든 클라이언트에 대해 을 발사합니다.

이벤트 연결 - LocalScript

local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- 원격 이벤트 인스턴스에 대한 참조 가져오기
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function onTimerUpdate(seconds)
print(seconds)
end
-- 연결 함수를 이벤트에 연결 Connect function to event
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

원격 콜백

A RemoteFunction 개체는 클라이언트-서버 경계에서 동기적인 양방향 통신을 용이하게 합니다.원격 함수의 발신자는 수신자로부터 응답을 받을 때까지 생성될 것입니다.

Studio의 RemoteFunction 창을 통해 새로운 를 만들려면:

  1. RemoteFunction를 삽입하려는 컨테이너에 마우스를 이동합니다.서버와 클라이언트 액세스를 모두 보장하려면 서로 볼 수 있는 장소에 있어야 하며, ReplicatedStorage , 어떤 경우에는 Workspace 또는 내부의 Tool 에 저장하는 것이 적절합니다.
  2. 컨테이너의 이름 오른쪽에 나타나는 버튼을 클릭하고 원격 함수 인스턴스를 삽입합니다.
  3. 목적을 설명하기 위해 인스턴스 이름을 바꿉니다.

를 만든 후에는 클라이언트와 서버 간의 양방향 통신이나 서버와 클라이언트 간의 통신을 용이하게 할 수 있습니다.

클라이언트 → 서버 → 클라이언트
>

서버 → 클라이언트 → 서버
>

클라이언트 → 서버 → 클라이언트

서버에서 함수를 호출하기 위해 메서드를 호출하여 메서드를 사용하여 서버에서 함수를 호출할 수 있습니다.원격 이벤트와는 달리, 콜백이 반환될 때까지 호출하는 원격 이벤트 는 를 생성합니다. 에 전달하는 인수는 특정 제한으로 인해 의 콜백에 전달됩니다. Arguments that you pass to pass to the callback of the with certain limitations .동일한 RemoteFunction 에 대한 여러 콜백을 정의하는 경우 마지막 정의만 실행됩니다.

클라이ентRemoteFunction:InvokeServer(args)
서버RemoteFunction.OnServerInvoke = function(player, args)

다음 는 콜백 함수를 정의하고 를 통해 요청된 을 그 값을 통해 반환합니다.그런 다음 동반 LocalScript 는 요청된 부품 색상과 위치를 정의하는 추가 인수를 사용하여 InvokeServer() 를 호출합니다.

콜백 연결 - 스크립트

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Workspace = game:GetService("Workspace")
-- 원격 함수 인스턴스에 대한 참조 가져오기
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
이벤트 호출 - LocalScript

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)

서버 → 클라이언트 → 서버

를 사용하여 클라이언트에서 함수를 호출할 수 있지만, 다음과 같은 심각한 위험이 있습니다:

  • 클라이언트가 오류를 발생시키면 서버도 오류를 발생시킵니다.
  • 클라이언트가 호출되는 동안 연결을 끊으면 InvokeClient() 오류가 발생합니다.
  • 클라이언트가 값을 반환하지 않으면 서버는 영원히 유지됩니다.

GUI 업데이트와 같이 양방향 통신이 필요하지 않은 작업의 경우 RemoteEvent 를 사용하고 서버에서 클라이언트로 통신합니다.

인수 제한

를 발사하거나 콜백 함수에 전달하는 모든 인수를 전달하면 이벤트나 콜백 함수에서 전달하는 모든 인수를 전달합니다.When you fire a or invoke a , it forwards any arguments that you pass with the event or to the callback function.Enum, Instance 또는 기타 유형의 Roblox 개체와 Luau 유형(숫자, 문자열 및 부울)은 전달할 수 있지만, 다음 제한 사항을 신중하게 조사해야 합니다.

문자열이 아닌 인덱스

패스된 테이블의 모든 인덱스Instance사용자 데이터 또는 함수와 같은 비문자열 형식이면 Roblox가 자동으로 해당 인덱스를 문자열로 변환합니다.

이벤트 연결 - LocalScript

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
-- 연결 함수를 이벤트에 연결 Connect function to event
remoteEvent.OnClientEvent:Connect(onEventFire)
이벤트 발사 - 스크립트

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local Workspace = game:GetService("Workspace")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- 들어오는 플레이어를 감지하고 각각에 원격 이벤트 전송
local function onPlayerAdded(player)
remoteEvent:FireClient(player,
{
[Workspace.Baseplate] = true
}
)
end
Players.PlayerAdded:Connect(onPlayerAdded)

패스된 함수

함수가 클라이언트-서버 경계에서 또는 의 인수로 포함되면 클라이언트-서버 경계 전체에서 복제할 수 없으므로 함수를 원격으로 전달할 수 없습니다.대신, 수신 측의 결과 인수는 nil가 됩니다.

이벤트 연결 - LocalScript

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)

테이블 인덱싱

데이터 테이블을 전달하는 경우 숫자와 문자열 키의 혼합 테이블을 전달하지 마십시오.대신, 키-값 쌍(사전) 또는 숫자 인덱스의 전체( 전체 )로 구성된 테이블을 전달하거나 전체( 전체 )의 숫자 인덱스를 전달합니다.

이벤트 연결 - 스크립트

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 = 디바 드래곤슬레이어
--> CharClass = 도둑
end
end
-- 연결 함수를 이벤트에 연결 Connect function to event
remoteEvent.OnServerEvent:Connect(onEventFire)
이벤트 발사 - LocalScript

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)

테이블 식별자

원격 이벤트/콜백에 전달된 테이블이 복사되어 이벤트를 발사하거나 콜백을 호출할 때 제공된 것과 정확히 동일하지 않게 됩니다.Tables passed as arguments to remote events/callbacks are copied, meaning they will not be exactly equivalent to those provided when firing the event or invoking the callback.반환된 테이블은 제공된 것과 정확히 동일하지 않을 수도 있습니다.다음 스크립트를 실행하여 RemoteFunction 에서 테이블 식별자가 어떻게 다른지 확인할 수 있습니다.

콜백 연결 - 스크립트

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteFunction = ReplicatedStorage:FindFirstChildOfClass("RemoteFunction")
-- 콜백 함수
local function returnTable(player, passedTable)
-- 호출 시 테이블 식별자 출력 Output table identity on invocation
print(tostring(passedTable)) --> 테이블: 0x48eb7aead27563d9
return passedTable
end
-- 함수를 원격 함수의 콜백으로 설정
remoteFunction.OnServerInvoke = returnTable
이벤트 호출 - LocalScript

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

메타테이블

테이블에 메타테이블이 있으면 모든 메타테이블 정보가 전송 중에 손실됩니다.다음 코드 샘플에서 NumWheels 속성은 Car 메타블에 속합니다.서버가 다음 테이블을 받을 때, 테이블에는 속성이 있지만 속성은 없습니다.

이벤트 연결 - 스크립트

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function onEvent(player, param)
print(param) --> {["이름"] = "MyTruck()}
end
-- 연결 함수를 이벤트에 연결 Connect function to event
remoteEvent.OnServerEvent:Connect(onEvent)
이벤트 발사 - 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)
-- 메타테이블을 포함하는 테이블로 화재 이벤트 발생 Fire event with table including a metatable
remoteEvent:FireServer(truck)

복제되지 않은 인스턴스

또는 가 발신자에게만 표시되는 값을 전달하면 Roblox는 클라이언트-서버 경계에서 복제하지 않고 대신 값을 전달합니다.예를 들어, 가 후손을 전달하면 이벤트를 수신하는 클라이언트는 해당 개체가 클라이언트에 복제할 수 없기 때문에 값을 받습니다.

이벤트 발사 - 스크립트

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerStorage = game:GetService("ServerStorage")
local Players = game:GetService("Players")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- 클라이언트가 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 을 볼 것입니다.

이벤트 발사 - LocalScript

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Workspace = game:GetService("Workspace")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- 서버가 이 부분에 대해 알지 못하기 때문에 "무효"로 받게 됩니다
local clientPart = Instance.new("Part")
clientPart.Parent = Workspace
remoteEvent:FireServer(clientPart)