いくつかのスクリプトを作成した後、いくつかのコードを再使用したいと思うまでは、通常はかかりません。場所によって、ModuleScripts は、クライアント/サーバー境界の異なる側面または同じ側面のスクリプト間でコードを再使用できます。
モジュールスクリプトの作成
スクリプトを置く場所はどこにでも置くことができますが、ReplicatedStorage は人気の場所です。スクリプトをここに保存すると、サーバーとクライアントの間でコードを再使用できます。
- Select ModuleScript を選択して、新しいモジュールスクリプトを追加します。
- スクリプトを右クリックして PickupManager に名前を変更します。
- スクリプトをダブルクリックして スクリプトエディター で開きます。
モジュールスクリプトの解剖
それぞれ ModuleScript は次のコードで始まります:
local module = {}return module
このコードは空の Luau テーブルを作成し、モジュールスクリプトを必要とするスクリプトに返します。
返却値は、データタイプ のいずれかを返すが、nil を除き、ほとんどのモジュールスクリプトは機能、テーブル、または機能の表を返します。その返却値を生成するには、モジュールスクリプトは任意のコードを実行できます、これには他のモジュールスクリプトの必要があります。
次の例では、 getPickupBonus という単一の関数を持つテーブルが返されます。新しいモジュールスクリプトに貼り付けてください:
-- ReplicatedStorage のモジュールスクリプト
local PickupManager = {}
local defaultMultiplier = 1.25
local rarityMultipliers = {
common = 10,
uncommon = 20,
rare = 50,
legendary = 100
}
-- PickupManager テーブルに getPickupBonus 関数を追加します
PickupManager.getPickupBonus = function(rarity)
local bonus = rarityMultipliers[rarity] * defaultMultiplier
return bonus
end
return PickupManager
テーブルに関数を追加することは必須ではありません—関数自体を返すだけです—しかし、良いパターンです—関数を別のスクリプトから呼び出すと、簡単な構文を提供します、モジュールスクリプトを時間をかけて簡単に追加できます。
モジュールスクリプトが必要
モジュールスクリプトを読み込むには、require() 関数を呼び出します。In ReplicatedStorage で、新しいスクリプトを追加し、RunContextします。然後、次のコードを追加して 2>PickupManager.getP
ReplicatedStorage のクライアントスクリプト
local ReplicatedStorage = game:GetService("ReplicatedStorage")-- ModuleScript によって返される値を取得するlocal PickupManager = require(ReplicatedStorage:WaitForChild("PickupManager"))-- ModuleScript 関数を呼び出すlocal bonus = PickupManager.getPickupBonus("legendary")print(bonus) --> 125
同じコードを使用して、スクリプトを ServerScriptService から要求することができます:
ServerScriptStorage のスクリプト
local ReplicatedStorage = game:GetService("ReplicatedStorage")-- 「PickupManager」という名前のモジュールスクリプトの返し値を取得するlocal PickupManager = require(ReplicatedStorage:WaitForChild("PickupManager"))
Global.LuaGlobals.requir必須() を ModuleScript で呼び出すと、require()
クライアント/サーバー境界の両方から ModuleScript を必要とする場合、ModuleScript はそれぞれの側に独自の参照を返します。
パターン
モジュールスクリプトには、コードを簡素化し、エクスペリエンスのサイズと複雑さが増すにつれて落とし穴を避けるために使用できるいくつかの一般的なパターンがあります。
データ共有
データを個々のオブジェクトに関連付けるには、Configuration フォルダに StringValue または IntValue などの値オブジェクトを割り当てたり、フォルダを作成したりできます。ただし、数十のオブジェクトまたはデータ値を追加または変更したい場合は、両
同じオブジェクトの複数のコピーで同じデータを変更したり、異なるオブジェクトで同じデータを再使用したい場合は、ModuleScripts にデータを保存します。他のスクリプトでデータを再使用する方が簡単で、テーブルと関数を保存できます。
Class.ReplicatedStorage|ReplicatedStorage の次の例 ReplicatedStorage は、一般的な銃の構成値を保存します:
ReplicatedStorage のモジュールスクリプト
local GunConfig = {}GunConfig.MagazineSize = 20GunConfig.AmmoCount = 100GunConfig.Firerate = 600GunConfig.Damage = {["Head"] = 50;["Torso"] = 40;["Body"] = 25;}return GunConfig
カスタムイベント
カスタムイベントにより、スクリプトは互いに通信できますが、個々の BindableEvent オブジェクトへの参照を追跡しなければならないと、コードが混乱する可能性があります。
Class.ModuleScript|ModuleScripts を使用して、BindableEvents を保存し、ModuleScript のメソッドに直接結び付けられたカスタムイベントハンドラーを提供できます。
Class.ReplicatedStorage|ReplicatedStorage の次の ReplicatedStorage には、スイッチが状態を変更すると実行されるカスタムイベントがあります:
ReplicatedStorage のモジュールスクリプト
local Switch = {}
-- スイッチが変更されたときにスクリプトが聞くことができるバインドを作成する
local bindableEvent = Instance.new("BindableEvent")
Switch.Changed = bindableEvent.Event
local state = false
function Switch.flip()
state = not state
bindableEvent:Fire(state)
end
return Switch
Class.ReplicatedStorage の次のクライアントスクリプトは、Switch.Changedイベントが発動したときに呼び出される関数を接続します。
ReplicatedStorage のスクリプト
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Switch = require(ReplicatedStorage:WaitForChild("Switch"))
Switch.Changed:Connect(function(newState)
print("Switch state is now", newState)
end
-- 数回フリップをテストしてください
task.wait(1)
Switch.flip()
task.wait(1)
Switch.flip()
カプセル化
カプセル化は、オブジェクトまたはスクリプトロジックの周りに抽象化レイヤーを作成して複雑さを隠す方法です。 ModuleScripts を使用して、Roblox オブジェクトをカスタム Lua 関数でカプセル化してコードを簡素化できます。
たとえば、カプセル化を使用して以下を行うことができます:
- 単一の RemoteEvent オブジェクトでネットワーク間通信を簡素化します。
- ラップエラー処理コードaround敏感なサービスのような DataStoreService 。
- Roblox オブジェクト機能を制御または拡張するためのカスタムメソッドを定義します。
ゲームにネットワーキングを実装するために、数十の個々の RemoteEvent オブジェクトを追跡するのは困難です。 ModuleScript を使用して、RemoteEvent をカプセル化して、この問題
下の例では、 ModuleScript という名前の NetworkManagerClient は、 Class.Remote
Class.ReplicatedFirst の次の ReplicatedFirst は、クライアントスクリプトを呼び出してネットワークメッセージを送信できるカプセル化された関数を提供します:
ネットワークモジュール
-- モジュールスクリプトを ReplicatedFirst という名前の NetworkManagerClient
local NetworkManagerClient = {}
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:WaitForChild("RemoteEvent")
-- リモートオブジェクトの FireServer 機能をカプセル化する
function NetworkManagerClient.FireServer(id, ...)
remoteEvent:FireServer(id, ...)
end
return NetworkManagerClient
Class.ServerScriptService の次の ServerScriptService は、すべてのスクリプトに BindableEvents を使用して、特定の ID に接続します。 クライアントがネットワークメッセージを送信すると、指定の ID に関連する各 1>Class.BindableEvent1> が発動します。
-- NetworkManagerServer という名前の ServerScriptService のモジュールスクリプト
local NetworkManagerServer = {}
local networkSignalList = {}
function NetworkManagerServer.GetServerEventSignal(id)
local bindableEvent = Instance.new("BindableEvent")
-- 新しいバインドイベントを id にリンク
table.insert(networkSignalList, {
id = id,
bindableEvent = bindableEvent,
})
return bindableEvent.Event
end
-- 接続中:
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:WaitForChild("RemoteEvent")
remoteEvent.OnServerEvent:Connect(function(player, id, ...)
-- 受信されたリモートイベントのID に一致するすべてのバインド可能なイベントを見つける
for _, signal in networkSignalList do
if signal.id == id then
signal.bindableEvent:Fire(player, ...)
end
end
end)
return NetworkManagerServer
次の LocalScript は、オプションの RequestA 引数で、ID Hello のメッセージを送信します。
-- ReplicatedFirst のローカルスクリプトlocal ReplicatedFirst = game:GetService("ReplicatedFirst")local NetworkManagerClient = require(ReplicatedFirst:WaitForChild("NetworkManagerClient"))NetworkManagerClient.FireServer("RequestA", "Hello")
次の Script は、ネットワークメッセージID RequestA に接続し、リクエストを受信すると、追加パラメータを含むステートメントをプリントアウトします。
-- ServerScriptService のスクリプト
local ServerScriptService = game:GetService("ServerScriptService")
local NetworkManagerServer = require(ServerScriptService:WaitForChild("NetworkManagerServer"))
NetworkManagerServer.GetServerEventSignal("RequestA"):Connect(function(player, ...)
print("Received RequestA from", player, ...)
end)