モジュールプログラミング
複数のスクリプト間で同じ機能をコピーするのは時間がかかり、管理が大変です。例えば、通貨ゲームシステムを持つゲームでは、クエストを終えたプレイヤーに報酬を与えたり、ショップでアイテムを購入したりするなど、多くのゲームメカニクスで同じ機能を使用していることに気づくでしょう。
コードを整理して再利用するには、モジュールスクリプトを使用するのが良いでしょう。モジュールスクリプトとは、プレイヤーのお金や敵の管理など、共有の目的を満たすように設計された関数や変数のセットを格納するスクリプトの一種です。
モジュールスクリプト内のコードは、他のスクリプトで使用することができます。そうすれば、プレイヤーがクエストを終了したり、アイテムを拾ったりしたときに、複数の異なるスクリプトからコインを与える同じ関数を呼び出すことができます。
一般的に使用されるコードをモジュールスクリプトに格納することで、複数のスクリプトを更新するのではなく、1つのモジュールスクリプトに変更を加えるだけで済むため、コードのメンテナンスや整理が容易になります。
モジュールスクリプトを使うかスクリプトを使うか
通常のスクリプトは、アイテムを拾ったりするなどのゲームの基本的な部分で使用しますが、モジュールスクリプトは、ポイントの報酬など、複数の独立したスクリプトで再利用できるコードを格納するのに便利です。
モジュールスクリプトの基本
モジュールスクリプトは、ServerStorage の中に作成します。ServerStorage の右側の+をクリックすると、メニュー内に ModuleScript というものが表示されますので、それを選択してください。
モジュールスクリプトは一般的に ServerStorage の中に作成し、自動的には実行されません。その代わりに他のスクリプトが関数を実行し、必要に応じてモジュールから情報を取得することができます。
モジュールスクリプトの構造
モジュールスクリプトを作成する際は、必ず下記のコードから始めます。
local module = {}
return module
モジュールスクリプトは、local module = {} という行で始まり、return module という行で終わります。ここにモジュールの共通の関数群や変数を格納します。
module という名前は、このモジュールの目的を表す名称に変更します。例えば、お金関係のモジュールならば、MoneyManager とか、パーティクルをコントロールするモジュールならば、ParticleController のような名称にします。なお、モジュール名は頭文字を大文字にすることが推奨されています。
local MoneyManager = {}
return MoneyManager
モジュールスクリプトを追加する
他のスクリプトで使用できる関数や変数をモジュールに追加するには、TestModule.myVariable のように、モジュール名の後に「.(ドット)」を付け、変数名または関数を付けます。
local TestModule = {}
-- 「TestModule」に変数を追加
TestModule.myVariable = 100
-- 「TestModule」に関数を追加
function TestModule.doTask(player)
-- プログラムを入れる
end
return TestModule
値を返さない関数の場合は習慣的にTestModule:doTaskのように「:(コロン)」を使用することもありますので覚えておきましょう。いずれにしましても呼ぶ側と呼ばれる側が一致させる必要があります。
function TestModule:doTask(player)
-- プログラムを入れる
end
モジュール名とreturnの間に入力する
モジュールスクリプトは、local myModule = {} と return myModule の間に入力しなくてはなりません。
モジュールスクリプトのスコープ
このスクリプトの外から、モジュール関数あるいは変数を使用したい場合は、local と入力してはいけません。
変数や関数の前に local と入れると、そのスクリプトでのみ使用できることを意味します。これは、エラーやバグを減らすために、ほとんどのスクリプトでは良い習慣ですが、モジュールスクリプトの関数や変数は外部から呼ばれることを目的としますのでローカルにすることはできません。
モジュールスクリプト内でのみ使用される変数は、他のスクリプトと同様にローカル変数を使用します。例えば、以下のコードにあるローカル変数 questReward は、このモジュールスクリプトでのみ使用でき、関数 finishQuest() はモジュール外のスクリプトから使用できます。
local MoneyManager = {}
-- モジュールスクリプト内でのみ使用される変数
local questReward = 100
-- モジュールスクリプト内でのみ使用される関数
function MoneyManager:finishQuest(player)
player.Money = player.Money + questReward
end
return MoneyManager
他のスクリプトでモジュールを使用する
モジュールスクリプトは単独ではコードを実行することはできません。キーワード require() を使用して、他のスクリプトでロードする必要があります。require 関数のパラメーターでExplorer内のモジュールスクリプトの場所を指定します。
local ServerStorage = game:GetService("ServerStorage")
local MoneyManager = require(ServerStorage.ModuleScript)
MoneyManager には、ServerStorage 内にある ModuleScript のモジュールスクリプトが含まれています。
モジュールスクリプト – MoneyManager
local MoneyManager = {}
function MoneyManager.giveMoney(player, questReward)
player.Money = player.Money + questReward
return player.Money
end
return MoneyManager
通常のスクリプト – CoinPickup
モジュールスクリプト内の関数を使用するには、下記のようにrequireで取得した変数名の後にドットもしくはコロン(一致していればOK)を付け、モジュールスクリプト内の関数名を myModule:myFunction() のように入力します。スクリプトが実行されてその行に到達すると、モジュールテーブルに保存されている特定の関数や変数にアクセスします。
-- モジュールスクリプトのロード
local ServerStorage = game:GetService("ServerStorage")
local MoneyManager = require(ServerStorage.ModuleScript)
local coinValue = 100
if player then
--モジュールスクリプト内の関数を実行
local money = moneyManager.giveMoney(player, coinValue)
print(money)
end
他のスクリプトで入力する際のスペルチェック
他のスクリプトで作業する場合、モジュールスクリプト関数や変数がそのモジュール内で表示されているものとまったく同じスペルであることを確認してください。これを助けるために、モジュールから正確な関数名や変数名をコピーして、それを使用する通常のスクリプトに貼り付けることをお勧めします。
トラブルシューティング
モジュールスクリプトを使用した際に、次のようなエラーメッセージが表示された場合の解決方法を示します。
エラーメッセージ:Infinite yield possible または not a valid member
- モジュールスクリプトを配置している場所のスペルを確認してください。require() はモジュールスクリプトとまったく同じパスおよびスペルになっていなくてはなりません。
エラーメッセージ :attempt to index global
- モジュールスクリプトを使用するスクリプトでは、関数 require() を使用してロードされていることを確認してください。そうでない場合、そのスクリプトではモジュールスクリプトの関数や変数を使用することができません。
[ 【18】pairsとiPairs ]