Roblox 게임은 기본적으로 멀티플레이어이므로 모든 게임은 본질적으로 서버와 플레이어의 연결된 클라이언트 간에 통신합니다. 가장 간단한 경우로, 플레이어가 캐릭터를 이동시키면 Humanoid 속성 중 일부, 예를 들어 상태가 서버에 전달되고, 서버는 이 정보를 다른 연결된 클라이언트에게 전달합니다.
원격 이벤트 및 콜백을 사용하면 클라이언트-서버 경계를 넘어 통신할 수 있습니다:
- RemoteEvents는 일방향 통신(요청을 보내고 **응답을 기다리지 않음)을 가능하게 합니다.
- UnreliableRemoteEvents는 지속적으로 변경되거나 게임 상태에 중요하지 않은 데이터에 대한 일방향 통신을 가능하게 합니다. 이러한 이벤트는 순서와 신뢰성을 희생하여 네트워크 성능을 향상시킵니다.
- RemoteFunctions는 양방향 통신(요청을 보내고 수신자로부터 응답을 받을 때까지 대기)을 가능하게 합니다.
보다 제한된 유용성을 가진 바인더블 이벤트와는 달리, 원격 이벤트 및 함수의 사용 사례는 너무 많아 나열할 수 없습니다:
- 게임 플레이 - 플레이어가 레벨의 끝에 도달하는 것과 같은 기본 게임 플레이는 원격 이벤트가 필요할 수 있습니다. 클라이언트 스크립트가 서버에 알리고, 서버 스크립트가 플레이어의 위치를 재설정합니다.
- 서버 검증 - 플레이어가 포션을 마시려고 할 때, 실제로 그 포션을 가지고 있는가? 공정성을 보장하기 위해 서버는 게임의 진실의 출처가 되어야 합니다. 클라이언트 스크립트는 원격 이벤트를 사용하여 서버에 플레이어가 포션을 마시고 있다고 알릴 수 있으며, 서버 스크립트는 플레이어가 실제로 그 포션을 가지고 있는지, 그리고 어떤 이점을 부여할지를 결정할 수 있습니다.
- 사용자 인터페이스 업데이트 - 게임의 상태가 변경됨에 따라 서버 스크립트는 원격 이벤트를 사용하여 클라이언트에게 점수, 목표 등의 변경 사항을 알릴 수 있습니다.
- 게임 내 마켓플레이스 구매 - 원격 함수를 사용하는 구현 예시는 프롬프트 구독 구매를 참조하세요.
빠른 참조
다음 표는 RemoteEvents 및 RemoteFunctions를 사용하여 클라이언트와 서버 간에 통신하는 방법에 대한 빠른 참조로 사용됩니다.
| 클라이언트 → 서버 | |
|---|---|
| 클라이언트 | 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를 생성하려면:
- RemoteEvent를 삽입할 컨테이너 위에 마우스를 올립니다. 서버와 클라이언트 모두 접근할 수 있도록 하려면, ReplicatedStorage와 같이 양쪽에서 볼 수 있는 장소에 있어야 하며, 경우에 따라 Workspace 또는 Tool 내부에 저장하는 것이 적절할 수 있습니다.
- 컨테이너 이름 오른쪽에 나타나는 ⊕ 버튼을 클릭하고 RemoteEvent 인스턴스를 삽입합니다.
- 인스턴스의 이름을 목적에 맞게 변경합니다.
RemoteEvent를 생성한 후에는 클라이언트에서 서버로, 서버에서 클라이언트로, 또는 서버에서 모든 클라이언트로 일방향 통신을 촉진할 수 있습니다.



클라이언트 → 서버
LocalScript를 사용하여 FireServer() 메서드를 호출하여 서버에서 이벤트를 트리거할 수 있습니다. FireServer()에 인수를 전달하면, 특정 제한 사항과 함께 서버의 이벤트 핸들러로 전달됩니다. 서버의 이벤트 핸들러의 첫 번째 매개변수는 항상 호출하는 클라이언트의 Player 객체이며, 추가 매개변수가 뒤따릅니다.
| 클라이언트 | RemoteEvent:FireServer(args) |
| 서버 | RemoteEvent.OnServerEvent:Connect(function(player, args)) |
다음 Script는 OnServerEvent에 이벤트 핸들러를 연결하여 서버에서 새로운 Part를 생성합니다. 동반하는 LocalScript는 원하는 Color 및 Position을 가진 RemoteEvent 인스턴스에서 FireServer()를 호출합니다.
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Workspace = game:GetService("Workspace")
-- 원격 이벤트 인스턴스에 대한 참조 가져오기
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function onCreatePart(player, partColor, partPosition)
print(player.Name .. "가 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를 사용하여 FireClient() 메서드를 호출하여 클라이언트에서 이벤트를 트리거할 수 있습니다. FireClient()의 첫 번째 인수는 이벤트에 응답할 클라이언트의 Player 객체이며, 추가 인수는 특정 제한 사항과 함께 클라이언트로 전달됩니다. 이벤트 핸들러는 클라이언트에서 Players.LocalPlayer를 사용하여 플레이어를 결정할 수 있으므로, 이벤트 핸들러의 첫 번째 인수로 Player 객체를 포함할 필요는 없습니다.
| 서버 | RemoteEvent:FireClient(player, args) |
| 클라이언트 | RemoteEvent.OnClientEvent:Connect(function(args)) |
다음 LocalScript는 OnClientEvent 이벤트에 이벤트 핸들러를 연결합니다. 동반하는 Script는 서버에 들어오는 플레이어를 수신하고 각 플레이어에게 임의의 데이터를 사용하여 FireClient()를 호출합니다.
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("[클라이언트] 플레이어에게 이벤트 수신됨", 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("[서버] 플레이어에게 이벤트 발생", player.Name)
remoteEvent:FireClient(player, Players.MaxPlayers, Players.RespawnTime)
end
Players.PlayerAdded:Connect(onPlayerAdded)서버 → 모든 클라이언트
Script를 사용하여 FireAllClients() 메서드를 호출하여 모든 클라이언트에서 이벤트를 트리거할 수 있습니다. FireClient()와 달리, FireAllClients() 메서드는 모든 클라이언트에게 RemoteEvent를 발생시키므로 Player 객체가 필요하지 않습니다.
| 서버 | RemoteEvent:FireAllClients(args) |
| 클라이언트 | RemoteEvent.OnClientEvent:Connect(function(args)) |
다음 LocalScript는 남은 카운트다운 시간을 출력하는 OnClientEvent 이벤트에 이벤트 핸들러를 연결합니다. 동반하는 Script는 매초마다 루프에서 FireAllClients()를 호출하여 모든 클라이언트에 대해 RemoteEvent를 발생시킵니다.
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
-- 시간이 만료될 때까지 매초마다 RemoteEvent 발생
for timeRemaining = -1, countdown do
remoteEvent:FireAllClients(countdown - timeRemaining)
task.wait(1)
end원격 콜백
RemoteFunction 객체는 클라이언트-서버 경계를 넘어 동기식 양방향 통신을 가능하게 합니다. 원격 함수의 발신자는 수신자로부터 응답을 받을 때까지 대기합니다.
Studio의 탐색기 창을 통해 새로운 RemoteFunction을 생성하려면:
- RemoteFunction을 삽입할 컨테이너 위에 마우스를 올립니다. 서버와 클라이언트 모두 접근할 수 있도록 하려면, ReplicatedStorage와 같이 양쪽에서 볼 수 있는 장소에 있어야 하며, 경우에 따라 Workspace 또는 Tool 내부에 저장하는 것이 적절할 수 있습니다.
- 컨테이너 이름 오른쪽에 나타나는 ⊕ 버튼을 클릭하고 RemoteFunction 인스턴스를 삽입합니다.
- 인스턴스의 이름을 목적에 맞게 변경합니다.
RemoteFunction을 생성한 후에는 클라이언트와 서버 간 또는 서버와 클라이언트 간 양방향 통신을 촉진할 수 있습니다.


클라이언트 → 서버 → 클라이언트
LocalScript를 사용하여 InvokeServer() 메서드를 호출하여 서버에서 함수를 호출할 수 있습니다. 원격 이벤트와는 달리, RemoteFunction을 호출하는 LocalScript는 콜백이 반환될 때까지 대기합니다. InvokeServer()에 전달하는 인수는 특정 제한 사항과 함께 OnServerInvoke 콜백으로 전달됩니다. 동일한 RemoteFunction에 대해 여러 콜백을 정의하면 마지막 정의만 실행됩니다.
| 클라이언트 | RemoteFunction:InvokeServer(args) |
| 서버 | RemoteFunction.OnServerInvoke = function(player, args) |
다음 Script는 OnServerInvoke를 통해 콜백 함수를 정의하고 요청된 Part를 반환 값으로 전달합니다. 동반하는 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 .. "가 새로운 파트를 요청했습니다.")
local newPart = Instance.new("Part")
newPart.Color = partColor
newPart.Position = partPosition
newPart.Parent = Workspace
return newPart
end
-- 함수를 원격 함수의 콜백으로 설정
remoteFunction.OnServerInvoke = createPartlocal ReplicatedStorage = game:GetService("ReplicatedStorage")
-- 원격 함수 인스턴스에 대한 참조 가져오기
local remoteFunction = ReplicatedStorage:FindFirstChildOfClass("RemoteFunction")
-- 콜백 호출 시 색상 및 위치 전달
local newPart = remoteFunction:InvokeServer(Color3.fromRGB(255, 0, 0), Vector3.new(0, 25, -20))
-- 반환된 파트 참조 출력
print("서버가 요청된 파트를 생성했습니다:", newPart)서버 → 클라이언트 → 서버
Script를 사용하여 InvokeClient() 메서드를 호출하여 클라이언트에서 함수를 호출할 수 있지만, 다음과 같은 심각한 위험이 있습니다:
- 클라이언트에서 오류가 발생하면 서버에서도 오류가 발생합니다.
- 클라이언트가 호출되는 동안 연결이 끊기면 InvokeClient()가 오류를 발생시킵니다.
- 클라이언트가 값을 반환하지 않으면 서버는 영원히 대기합니다.
GUI 업데이트와 같이 양방향 통신이 필요하지 않은 작업의 경우, RemoteEvent를 사용하고 서버에서 클라이언트로 통신하세요.
전달 보장
각 원격 유형은 메시지가 도착하는지 및 어떤 순서로 도착하는지에 대한 서로 다른 약속을 합니다. 이러한 약속은 단일 연결의 단일 방향에만 적용되며, 즉 서버에서 특정 클라이언트로 또는 특정 클라이언트에서 서버로의 통신에만 해당됩니다.
RemoteEvents
RemoteEvents는 신뢰할 수 있고 순서가 보장됩니다:
- 메시지가 전송 중에 손실되면, Roblox는 수신자가 연결된 상태인 한 메시지를 도착할 때까지 재전송합니다.
- 메시지는 발송한 순서대로 도착합니다. 다른 RemoteEvent 인스턴스 간에도 마찬가지입니다. 예를 들어, 서버가 이벤트 A를 발생시키고, 그 다음 B를 발생시키고, 다시 A를 같은 클라이언트에게 발생시키면, 해당 클라이언트는 A, B, A를 수신합니다. 이는 FireClient() 또는 FireAllClients()를 사용할 때 모두 적용됩니다.
- 클라이언트가 스로틀링 한도를 초과하여 이벤트를 발생시키면, 서버는 초과 이벤트를 삭제하는 대신 나중에 처리합니다. 이 경우에도 순서는 유지됩니다.
신뢰할 수 있고 순서가 보장된 메시지가 다음과 같은 경우에 여전히 코드에 도달하지 못할 수 있습니다:
- 핸들러가 연결되어 있지 않음. 메시지가 도착할 때 OnServerEvent 또는 OnClientEvent에 아무것도 연결되어 있지 않으면, Roblox는 메시지를 대기열에 추가하고 핸들러가 연결되는 즉시 순서대로 전달합니다. 대기열은 수량과 메모리 모두에 제한이 있습니다. 대기열이 가득 차면 Roblox는 추가 메시지를 폐기하고 출력 창에 Remote event invocation 오류를 기록합니다.
- 수신자가 연결이 끊김. 클라이언트가 나갈 때 전달되지 않은 메시지는 손실됩니다.
순서는 각 핸들러가 시작하는 시점에 적용되며, 완료되는 시점에는 적용되지 않습니다. 핸들러가 task.wait() 또는 WaitForChild()를 호출하여 대기하는 경우, Roblox는 이전 핸들러가 재개되기 전에 다음 메시지를 처리할 수 있습니다.
RemoteFunctions
RemoteFunctions는 호출 및 응답을 신뢰할 수 있게 전송하므로, Roblox는 양쪽이 연결된 상태인 한 손실된 메시지를 재전송합니다. InvokeServer() 및 InvokeClient()는 응답이 도착할 때까지 대기하므로, 단일 스레드는 한 번에 하나의 호출만 진행할 수 있습니다. 그러나 별도의 스레드는 동시에 호출할 수 있으며, 콜백이 대기하는 경우 응답이 전송된 호출과 다른 순서로 도착할 수 있습니다.
OnServerInvoke 또는 OnClientInvoke에 콜백이 할당되지 않으면, Roblox는 하나가 할당될 때까지 호출을 대기열에 추가합니다. 이 대기열은 RemoteEvent 대기열과 동일한 종류의 제한이 있습니다.
UnreliableRemoteEvents
UnreliableRemoteEvents는 전달이나 순서를 보장하지 않습니다. 또한 RemoteEvents 또는 RemoteFunctions와 순서 관계가 없습니다. Roblox는 다음과 같은 경우에 메시지를 삭제할 수 있으며, 재전송하지 않습니다:
- 메시지가 전송 중에 손실됨.
- 네트워크가 혼잡하여 메시지가 전송되기까지 너무 오랜 시간이 걸림.
- 페이로드가 1,000바이트를 초과함.
- 클라이언트가 스로틀링 한도보다 빠르게 발생시킴. RemoteEvent와는 달리, 서버는 초과 메시지를 지연시키는 대신 삭제합니다.
- 메시지가 도착할 때 OnServerEvent 또는 OnClientEvent에 아무것도 연결되어 있지 않음. RemoteEvent와는 달리, Roblox는 메시지를 대기열에 추가하는 대신 즉시 폐기합니다.
Roblox는 이전 메시지가 도착할 때까지 기다리지 않고 나중의 메시지를 처리할 수 있으므로, 메시지가 순서대로 도착하지 않을 수 있습니다. 순서가 중요하다면 각 메시지에 타임스탬프나 시퀀스 번호를 포함하고, 처리한 최신 메시지보다 오래된 메시지는 무시하세요.
스로틀링 및 크기 제한
클라이언트에서 서버로의 메시지는 모든 원격 유형이 모든 인스턴스에서 공유하는 속도 제한의 적용을 받습니다. 현재 제한에 대한 정보는 RemoteEvent의 스로틀링 섹션과 UnreliableRemoteEvent의 페이로드 제한을 참조하세요.
인수 제한
RemoteEvent를 발생시키거나 RemoteFunction을 호출할 때, 전달하는 모든 인수를 이벤트 또는 콜백 함수와 함께 전달합니다. Enum, Instance와 같은 Roblox 객체 유형이나 숫자, 문자열, 불리언과 같은 Luau 유형을 전달할 수 있지만, 다음 제한 사항을 주의 깊게 살펴보아야 합니다.
비문자열 인덱스
전달된 테이블의 인덱스가 Instance, userdata 또는 function과 같은 비문자열 유형인 경우, Roblox는 자동으로 해당 인덱스를 문자열로 변환합니다.
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
-- 이벤트에 함수 연결
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)전달된 함수
RemoteEvent 또는 RemoteFunction의 인수로 포함된 함수는 클라이언트-서버 경계를 넘어 복제되지 않으므로, 원격으로 함수를 전달할 수 없습니다. 대신 수신 측의 결과 인수는 nil이 됩니다.
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function onClientEvent(func)
print(func) --> nil
end
remoteEvent.OnClientEvent:Connect(onClientEvent)local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function testFunction()
print("안녕하세요!")
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
-- 이벤트에 함수 연결
remoteEvent.OnServerEvent:Connect(onEventFire)local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- 숫자 인덱스 테이블
local inventoryData = {
"검", "활"
}
-- 사전 테이블
local characterData = {
CharName = "디바 드래곤슬레이어",
CharClass = "로그"
}
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)) --> table: 0x48eb7aead27563d9
return passedTable
end
-- 함수를 원격 함수의 콜백으로 설정
remoteFunction.OnServerInvoke = returnTablelocal ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteFunction = ReplicatedStorage:FindFirstChildOfClass("RemoteFunction")
local inventoryData = {
"검", "활"
}
-- 원본 테이블 정체성 출력
print(tostring(inventoryData)) --> table: 0x059bcdbb2b576549
local invokeReturn = remoteFunction:InvokeServer(inventoryData)
-- 반환된 테이블 정체성 출력
print(tostring(invokeReturn)) --> table: 0x9fcae7919563a0e9메타테이블
테이블에 메타테이블이 있는 경우, 모든 메타테이블 정보가 전송 중에 손실됩니다. 다음 코드 샘플에서 NumWheels 속성은 Car 메타테이블의 일부입니다. 서버가 다음 테이블을 수신할 때, truck 테이블은 Name 속성은 있지만 NumWheels 속성은 없습니다.
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function onEvent(player, param)
print(param) --> {["Name"] = "내 트럭"}
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 = "내 트럭"
setmetatable(truck, Car)
-- 메타테이블이 포함된 테이블로 이벤트 발생
remoteEvent:FireServer(truck)복제되지 않는 인스턴스
RemoteEvent 또는 RemoteFunction이 발신자에게만 보이는 값을 전달하면, Roblox는 이를 클라이언트-서버 경계를 넘어 복제하지 않으며, 대신 nil을 전달합니다. 예를 들어, Script가 ServerStorage의 자손을 전달하면, 이벤트를 수신하는 클라이언트는 해당 객체에 접근할 수 없기 때문에 nil 값을 수신합니다.
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerStorage = game:GetService("ServerStorage")
local Players = game:GetService("Players")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- 클라이언트가 ServerStorage에 접근할 수 없기 때문에 "nil"로 수신됨
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 Workspace = game:GetService("Workspace")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- 서버가 이 파트를 알지 못하기 때문에 "nil"로 수신됨
local clientPart = Instance.new("Part")
clientPart.Parent = Workspace
remoteEvent:FireServer(clientPart)