【Roblox】UGC機能の実装(2)~ステージの生成~
はじめに
今回は前回の記事で紹介したUGC機能を使って作成したステージデータから実際にステージを生成する方法について紹介します。
今回使用するデータの構造は前回の記事で作成したものになるので、読んでいない方はそちらを読んでからご覧いただきますようお願いします。
前回の記事
Robloxバージョン 0.658.0.6580461
ステージの生成
前回保存したデータはDataStoreで使用できるようにCFrameを配列に変換して保存を行っていました。
まずは配列をもう一度CFrameに変換する処理について紹介します。
tableからCFrameに変換する
前回CFrameをtable型に変換しましたが、そのときの配列の中身は
cframe = {0, 10, 20, 0.49995946884155273, 0, 0.8660488128662109, 0, 1, 0, -0.8660488128662109, 0, 0.49995946884155273}
このようになっています。
これをもう一度CFrameに変換するにはtable型に用意されているunpack
メソッドを使用します。
このメソッドはtableの要素をタプル型として返します。
local part = Instance.new("Part")
part.CFrame = CFrame.new(table.unpack(cframe))
こうすることで複雑なコードを組まずともtable型からCFrameに変換することができます。
DataStoreからデータを取得し、ステージを作成する
実際にステージデータをDataStoreから取得し、生成してみましょう。
命令情報に関してはMoveを例に紹介します。
local DataStoreService = game:GetService("DataStoreService")
local StageDataStore = DataStoreService:GetDataStore("StageDataStore")
--生成したステージオブジェクトの親になるModelインスタンス
local StageBase = workspace:WaitForChild("BaseModel")
--ステージを生成する際の基準位置となるBasePartインスタンス
local BasePosPart = workspace:WaitForChild("BasePos")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
--プレハブフォルダ
local prefabFolder = ReplicatedStorage:WaitForChild("Prefab")
--配置するオブジェクトを格納しているフォルダ
local objectFolder = prefabFolder:WaitForChild("Object")
local TweenService = game:GetService("TweenService")
local StageLoadManager = {}
function StageLoadManager:CreateStage(stageId)
-- ステージデータの取得
local data = StageDataStore:GetAsync(stageId)
local directiveTweens = {}
for i,v in ipairs(data) do
local object = prefabFolder:WaitForChild("Object_"..v.objectId):Clone()
object.CFrame = CFrame.new(table.unpack(v.cframe))
object.Position = object.Position + BasePosPart.Position
if v.directive.Move.IsActive then
local currentPos = object.Position
local targetPos = Vector3.new(v.directive.Move.TargetPos[1],v.directive.Move.TargetPos[2],v.directive.Move.TargetPos[3])
local mag = (targetPos + BasePosPart.Position - currentPos).Magnitude
local tweenInfo = mag / v.directive.Move.Speed
local moveForward = TweenService:Create(object, tweenInfo, {Position = targetPos + BasePosPart.Position})
local moveBackward = TweenService:Create(object, tweenInfo, {Position = currentPos})
moveForward.Completed:Connect(function()
moveBackward:Play()
end)
moveBackward.Complited:Connect(function()
moveForward:Play()
end)
--作成したTweenのうち最初に再生されるものをテーブルに格納する
table.insert(directiveTweens, moveForward)
end
end
return directiveTweens
end
return StageLoadManager
これでステージを生成することができました。
returnしているdirectiveTweensにはオブジェクトに対する命令のTweenが入っているので、ステージ開始タイミングでfor文でまとめてPlayすることでオブジェクトを動かすことができます。
UGC機能でステージを生成する際の注意点
DataStoreを使ってステージデータを扱う際にはDataStoreの制限に気を付ける必要があります。
UGC機能では多くのデータをやり取りする必要があるので、設計をしっかりと行わないと制限に引っ掛かりDataStoreの使用が一時的にできなくなる可能性があります。
リクエスト回数制限
リクエストタイプごとに1分間にリクエストできる回数に制限が設定されています。
リクエストタイプ | 機能 | 1分あたりのリクエスト数 |
---|---|---|
Get | GetAsync() | 60 + サーバー上のプレイヤー数 * 10 |
Set | SetAsync() IncrementAsync() UpdateAsync() RemoveAsync() |
60 + サーバー上のプレイヤー数 * 10 |
Get Sorted | GetSortedAsync() | 5 + サーバー上のプレイヤー数 * 2 |
Get Version | GetVersionAsync() GetVersionAtTimeAsync() |
5 + サーバー上のプレイヤー数 * 2 |
List | ListDataStoreAsync() ListKeysAsync() ListVersionAsync() |
5 + サーバー上のプレイヤー数 * 2 |
Remove | RemoveVersionAsync() | 5 + サーバー上のプレイヤー数 * 2 |
データ量制限
一つにエントリに対して4MBのデータしか保存することができません。
スループット制限
サーバー全体でリクエストでやり取りできるデータ量に制限があります。
またこの時のデータ量はキロバイト単位にすべて切り上げられます。
リクエストタイプ | 制限 |
---|---|
Read | 1分あたり25MB |
Write | 1分あたり4MB |
まとめ
- tableからCFrameに変換するときは
unpack
メソッドを使用する - DataStoreの制限に注意する
- リクエスト回数制限
- エントリのデータ量制限
- スループット制限
今回はUGC機能で作成したステージデータをDataStoreから呼び出し、ステージを生成する方法について紹介しました。
UGC機能を作る上ではDataStoreの制限に気を使って実装を行わないと制限に引っ掛かったときにDataStoreの使用が一時的にできなくなってしまうことがあるので、どのタイミングでDataStoreにリクエストが送信されるのか、重複してデータの取得を行っていないか注意する必要があります。
UGC機能はゲームでできることの幅を大きく広げてくれますが、DataStoreの制限やさまざまな状況を考慮した設計が必要になってきます。サービスの制限に関しての知見を深めた上で、余裕のある設計ができるように心がけましょう。
最後までお読みいただき、ありがとうございました!
参考

当社ではRobloxを活用したゲームの開発、 また企業の商品やサービスの認知度拡大に寄与する3Dワールドの制作など、 Robloxにおける様々な活用支援を行っております。 Robloxのコンテンツ開発をご検討されている企業様は、お気軽にご相談ください。 landho.co.jp/
Discussion