春までRoblox — 第2回ブログ

Cubeデータをゲーム内のPartに同期させる方法

前回は「ユーザー毎にCubeデータを持たせる方法」を整理しました。今回はそのCubeデータを Robloxのゲーム内オブジェクト(Part)に同期させる方法 を解説します。CubeとPartの対応関係を明示的に管理する仕組みを加えます。


🔹 基本の考え方

  • Cubeデータは数値情報(x, y, z, stateなど)を持つ論理的なテーブル。
  • PartはRobloxの3D空間に存在する物理オブジェクト。
  • 同期とは「Cubeテーブルの値をPartの位置や属性に反映し、逆にPartの操作をCubeに反映する」こと。

👉 データの正本はCube配列。Partはその写像(表示)にすぎません。


🔹 1. CubeデータからPartを生成する(ID対応)

CubeとPartを対応付けるため、Cubeに id を持たせ、Partの名前やマップで管理します。

local CubePartsMap = {} -- Cube.id → Part参照

local function SpawnCubePart(cube, parent)
    local part = Instance.new("Part")
    part.Size = Vector3.new(4,4,4) -- Cubeの基本サイズ
    part.Position = Vector3.new(cube.x * 4, cube.y * 4, cube.z * 4)
    part.Anchored = true
    part.Name = "Cube_"..cube.id
    part.Parent = parent

    CubePartsMap[cube.id] = part
    return part
end

👉 これで「どのCubeがどのPartか」を一意に追跡できます。


🔹 2. プレイヤー毎のCubeを同期する

ユーザー毎に持っているCube配列をWorkspaceに反映します。

local function SyncPlayerCubes(player)
    local pd = PlayerData[player.UserId]
    if not pd then return end

    -- 既存のフォルダをクリア
    local folder = workspace:FindFirstChild("Player_"..player.UserId)
    if folder then folder:Destroy() end

    -- 新しいフォルダを作成
    folder = Instance.new("Folder")
    folder.Name = "Player_"..player.UserId
    folder.Parent = workspace

    -- Cube配列をPartに変換
    for _, cube in ipairs(pd.Cubes) do
        SpawnCubePart(cube, folder)
    end
end

🔹 3. イベントで同期を呼び出す

プレイヤーが参加したときやCubeを追加したときに同期を呼び出します。

game.Players.PlayerAdded:Connect(function(player)
    PlayerData[player.UserId] = { Cubes = {}, CubeUndo = {} }

    -- 初期Cubeを追加(idを必ず付与)
    local c = Cube(1, player.UserId, 2,3,10,0,1,0)
    table.insert(PlayerData[player.UserId].Cubes, c)

    -- 同期
    SyncPlayerCubes(player)
end)

game.Players.PlayerRemoving:Connect(function(player)
    PlayerData[player.UserId] = nil
    local folder = workspace:FindFirstChild("Player_"..player.UserId)
    if folder then folder:Destroy() end
end)

🔹 4. Cube更新時の同期

Cubeを追加・削除したら、その都度同期を呼び出します。

local function AddCubeForPlayer(player, cube)
    table.insert(PlayerData[player.UserId].Cubes, cube)
    SyncPlayerCubes(player)
end

local function UpdatePartFromCube(cube)
    local part = CubePartsMap[cube.id]
    if not part then return end
    part.Position = Vector3.new(cube.x*4, cube.y*4, cube.z*4)
end

🔹 整合性のポイント

  • Cubeが正本:OwnerIdやidはCubeに必ず持たせる。
  • Partは従属:Cubeの情報を反映するだけ。
  • 対応マップ:Cube.id → Part参照を持つことで双方向更新が可能。

🔹 まとめ

  • Cubeデータは数値情報+id+ownerIdを持つ論理テーブル。
  • PartはCubeから生成され、CubePartsMapで対応関係を管理する。
  • プレイヤー毎に専用フォルダを作り、CubePartをまとめる。
  • イベント(参加・退出・追加)に応じて同期を呼び出す。
  • 整合性を保つため、Cubeが主体、Partは従属という原則を守る。

📖 これを第2回目のブログ「春までRoblox(データをゲーム内のPartに同期させる方法)」としました。