原文では「Dictionaries」と呼ばれていますので、直訳で「辞書」としました。他のプログラミング言語では、連想配列と呼ばれているものもあります。つまり配列の延長線上に位置するものになります。配列にはインデックスという順番がありましたが、辞書にはそれがありません。その代わりにキーと呼ばれるものがあります。キーは名札のようなものです。そのキーを使って、要素にアクセスするということになります。
辞書の構文
配列と同様に、辞書は中括弧{}で作成されます。最初にキーを指定し、次に「=」、その後ろに値が続きます。配列と同じように複数の要素を入れることができます。その場合は最後にカンマを付けます。
下記のように文字列をキーにすることもできます。その場合は、角カッコを付け、ダブルコーテーションで文字列を囲みます。値は、配列と同じように様々なデータを指定することができます。
この辞書は文字列をキーとして使用します。こちらの方法では、スペースを含めたり、全角文字を使用することもできます。
local inventory = {
["GoldBars"] = 4,
["Healing Potions"] = 1,
["Cups of Coffee"] = 3000,
["コーヒー"] = 300,
}
こちらは、 value = inventory[“Healing Potions”] のようにアクセスできます。
もう1つは、キー名(変数名)を指定する方法です。キー名は変数の名称と同等仕様になりますので、スペースや全角文字は使用できません。キー名を指定し、「=」、そして値が続きます。
local inventory = {
GoldBars = 4,
HealingPotions = 1,
CupsOfCoffee = 3000,
}
こちらは、辞書名の後ろに「.」ドットを付け、キー名が続きます。つまり「value = inventory.GoldBars」のようになります。
一貫性を持たせたキーの形式にしましょう。例えば、キーが文字列の場合は、常に文字列を使用します。1つの辞書のキーに文字列と変数の両方を使用と、予期せぬ不具合が発生しやすくなりますので注意しましょう。
辞書の作成
ゲームでの辞書の一般的な使用法は、プレイヤー情報を整理することです。実際の例として、プレイヤーの名前とHP(体力)を整理するプログラムを作成します。テストは、出力ウィンドウを使用して行います。
辞書のコーディング
hero という名前の辞書を作成します。作成したら、プレーヤーがゲームに入ってきた際に呼ばれるイベントに接続し、この辞書に情報を保管します。
- ServerScriptService に任意のスクリプトを追加し、heroという名前の辞書を作成します。
local hero = {
}
- 「name」というキーを追加します。
local hero = {
name
}
1つの辞書内に同名のキーは指定できません。
- キーの値を文字列に設定して、ヒーローに名前を付けます。カンマで行を終了します。これは、ディクショナリにさらに追加するつもりであることを意味します。
キー「name」に「Jin」という文字列を代入します。カンマで行を終了します。これは、さらに辞書に追加するつもりであることを意味します。
local hero = {
name = "Jin",
}
- 2つ目のキーは「health」です。1000という数値を代入します。
local hero = {
name = "Jin",
health = 1000,
}
辞書の値の使用
辞書の値を使用するには、辞書名の後にキーを角カッコを付け、文字列を指定するようにダブルコーテーションで囲みます。こちらの指定方法では、どのようなキーでも対応できます。
もう1つ、上記の様にキーを変数で指定した場合、「hero.name」という書き方もできます。
local hero = {
name = "Jin",
health = 1000,
}
print ("The hero's name is " .. hero["name"])
-- もしくは
print ("The hero's name is " .. hero.name)
ディクショナリ値の変更
多くのゲームでは、辞書の内容を変更します。値の変更は、変数と変わりありません。
- 辞書 hero の name を変更してみましょう。
local hero = {
name = "Jin",
health = 1000,
}
hero["name"] = "Rana"
print ("The hero's name is " .. hero["name"])
-- もしくは
hero.name = "Rana"
print ("The hero's name is " .. hero.name)
- プロジェクトを実行し、name がどのように変更されたかを確認します。
実際のゲームでの使用
さらに一歩進み、実際のゲームに役立つような辞書の使い方を解説します。
例として、プレーヤーがゲームに入った来た時に、そのプレイヤーのポイントを初期設定するというものです。
- ServerScriptService に PlayerPoints という名前のスクリプトを追加します。Players サービスを取得し、playerPoints という名前の空の辞書を作成します。
Players = game:GetService("Players")
local playerPoints = {
}
- プレイヤーが入室してきたときに呼び出す setPoints() という関数を作成します。パラメータは入室してきた Player になります。その関数を Players.PlayerAdded のイベントに接続します。
local playerPoints = {
}
local function setPoints(newPlayer)
end
Players.PlayerAdded:Connect(setPoints)
- setPoints のパラメータは、Player オブジェクトになります。そのプロパティである Name には Roblox のプレイヤー名が入っています。まずは、本当に入っているかどうかテストしてみましょう。
local function setPoints(newPlayer)
local name = newPlayer.Name -- プレイヤー名を取得
print("hello " .. name)
end
- 現在、変数 name には、プレイヤー名が入っています。そのプレイヤー名をそのままキーとして利用し、辞書 playerPoints に、ポイントの初期値0を代入します。
local function setPoints(newPlayer)
local name = newPlayer.Name
print("hello " .. name)
playerPoints[name] = 0
end
- 変数 name を使用してプレイヤー名を表示し、playerPoints[name] とし、一致するキーの値を表示します。
local function setPoints(newPlayer)
local name = newPlayer.Name
print("hello " .. name)
playerPoints[name] = 0
print( name .. " has " ..playerPoints[name] .. " points.")
end
- プロジェクトを実行して確認してください。
hello Player
Player has 0 points.
プレイヤーデータの管理
辞書の中に、さらに辞書を入れることができますので、管理しなくてはならないプレイヤーデータが複数ある場合は、下記のようなプログラムを実現可能です。なお、このプログラムは一般的に、次の第6章で学ぶ「モジュールスクリプト」にしてどこからでも呼べるようにすると良いでしょう。
下記の initData() はプレイヤー入室時に呼びます。initData() 内の 辞書 data の要素を増やすことで、複数のデータを管理することが可能です。
local playerData = {} -- キーはユーザID
function initData(player)
local data = {
Point = 0,
Hp = 100,
}
local userId = player.UserId
playerData[userId] = data
end
function setData(player,variable,value)
local userId = player.UserId
local data = playerData[userId]
data[variable] = value
end
function getData(player,variable)
local userId = player.UserId
local data = playerData[userId]
return data[variable]
end
setData() でデータが保存でき、getData() で取得できます。
local point = getData(player,"Point") + 1
setData(player,"Point",point)
setData(player,"Hp",200)
print( getData(player,"Point") )
local hp = getData(player,"Hp")
1つの辞書にプレイヤーデータをすべて入れると、DataStoreService を使用してのサーバーへのデータのロードやセーブが一度にできます。SetAsync/GetAsync は辞書データもサポートしています。
[ 5-3 配列の変更 ]