🛰️

Roblox: クライアント-サーバー間の通信方法②(RemoteEvent)

2024/07/27に公開

前回に引き続き、Robloxでクライアント側のLocalScriptとサーバー側のScriptで情報をやり取りする際の方法についてご紹介していこうと思います!

全3回のアウトラインは以下のようになります。

  1. Client-Serverモデル: そもそものRobloxにおけるクライアントとサーバー間のルール
  2. RemoteEvent: クライアントとサーバー間の一方向の通信について←今回のテーマ
  3. RemoteFunction: クライアントとサーバー間の双方向の通信方法について

前回はRobloxでは基本的にクライアントとサーバーで直接通信できないという話をしました(Client-Serverモデル)。

第2回の今回は、クライアントとサーバー間で一方向通信するためのイベントRemoteEventを紹介していきます。

なお今回も前回に引き続き、以下のドキュメントの内容を元にまとめていこうと思います。

https://create.roblox.com/docs/scripting/events/remote

RemoteEvent

前回のおさらいですが、RemoteEventとは、サーバーとクライアントの一方向の通信に使用され、非同期で実行されるイベントのことでした。

RemoteEventを使用するときは通常、以下のようにReplicatedStorageというクライアント側もサーバー側も両方から参照できるディレクトリにRemoteEventクラスを用意し、両者このクラスを介して通信を実現します。

ドキュメントでは一方向の通信として以下の3通りの例が挙げられています。

これらそれぞれに対してのRemoteEventの使い方を簡単にご紹介します。

Client→Server

クライアントからサーバーへの通信は、RemoteEventFireServer()メソッドを呼び出すことで、クライアント側にあるLocalScriptを使用してサーバー上のイベントをトリガーできます。

  • Client: RemoteEvent:FireServer(args)
  • Server: RemoteEvent.OnServerEvent:Connect(function(player, args))

ドキュメントにあるクライアントから送られてきたColorとPositionの情報から、サーバー側で新たなPartを作成する通信の例について紹介します。

トリガーとなるクライアント側のLocalScriptは以下のように書きます。

  • Client側
local ReplicatedStorage = game:GetService("ReplicatedStorage")

-- リモートイベントインスタンスを取得
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")

-- サーバー側に渡す引数とともにリモートイベントを実行
-- ドキュメントではPartのColorとPositionを引数としてサーバー側に渡しています
remoteEvent:FireServer(Color3.fromRGB(255, 0, 0), Vector3.new(0, 25, -20))

続いてこれを受け取るサーバー側のScriptは以下のように書きます。

  • Server側
local ReplicatedStorage = game:GetService("ReplicatedStorage")

-- リモートイベントインスタンスを取得
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")

local function onCreatePart(player, x, partPosition)
	print(player.Name .. " fired the RemoteEvent") -- 実行したプレイヤーの名前を表示
	local newPart = Instance.new("Part")
	newPart.Color = partColor -- 受け取ったColor
	newPart.Position = partPosition -- 受け取ったPosition
	newPart.Parent = workspace -- 作成したPartの保存ディレクトリ
end

-- onCreatePartという関数をリモートイベントに接続
-- これによってクライアントからのリモートイベント実行と情報を受信して引数の関数を実行できる
remoteEvent.OnServerEvent:Connect(onCreatePart)

Server→Client

続いてサーバーからクライアントへ通信をする場合、先ほどの逆でRemoteEventFireClient()メソッドを呼び出すと、Scriptを使用してクライアントのイベントをトリガできます。

  • Server: RemoteEvent:FireClient(player, args)
  • Client: RemoteEvent.OnClientEvent:Connect(function(args))

ドキュメントにあるサンプルコードを見てみます。このサンプルは、プレイヤーがゲームに参加したときに、参加プレイヤーに対してMaxPlayers(サーバーに参加できるプレイヤーの最大数)とRespawnTime(プレイヤーがリスポーンするまでの時間)の情報を送信するスクリプトです。

トリガーとなるサーバー側のScriptは以下のように書きます。

  • Server側
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

-- プレイヤー参加時にonPlayerAddedを実行する
Players.PlayerAdded:Connect(onPlayerAdded)

続いて、これを受けるクライアント側(参加したプレイヤー)の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) -- 取得したmaxPlayersとrespawnTimeを表示
end

-- onNotifyPlayerという関数をリモートイベントに接続
remoteEvent.OnClientEvent:Connect(onNotifyPlayer)

Server→All Clients

RemoteEvent最後はサーバーからアクセスしている全クライアントに対する通信です。RemoteEventのFireAllClients()メソッドを呼び出すと、スクリプトを使用してすべてのクライアントにイベントをトリガできます。

クライアント側は前回と同じですが、サーバー側のメソッドがAllClient's'になり、引数にplayerを指定していないことに注意してください。

  • Server: RemoteEvent:FireAllClients(args)
  • Client: RemoteEvent.OnClientEvent:Connect(function(args))

ドキュメントでは、全プレイヤーに対して5秒のカウントダウンを1秒経過ごとに一斉送信するサンプルコードを例にしています。

トリガーとなるサーバー側のScriptは以下のように書きます。

  • Server側
local ReplicatedStorage = game:GetService("ReplicatedStorage")

-- リモートイベントインスタンスを取得
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")

local countdown = 5

-- 制限時間まで1秒経過ごとにリモートイベントを実行
for timeRemaining = -1, countdown do
	remoteEvent:FireAllClients(countdown - timeRemaining)
	task.wait(1)
end

これを受け取るクライアント側のLocalScriptは以下のとおりです。

local ReplicatedStorage = game:GetService("ReplicatedStorage")

-- リモートイベントインスタンスを取得
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")

local function onTimerUpdate(seconds)
	print(seconds) -- 取得したsecondsを表示
end

-- onTimerUpdateという関数をリモートイベントに接続
remoteEvent.OnClientEvent:Connect(onTimerUpdate)

まとめ

今回は、クライアントとサーバー間で一方向通信するためのイベントRemoteEventを紹介しました。

次の記事では双方向通信を実現するためのRemoteFunctionの解説と、シチュエーションごとのサンプルコードを紹介します!

Discussion