ここからは 「16×16 の Part グリッドを並べて、GUI で選んだ地形パレット色に応じて対話的に色を変える」 ところまでを、Roblox でそのまま動かせる形でまとめるね。
まだ 256×256 への変換は後で。
まずは インタラクティブな 16×16 ペイント UI を完成させる。
🎨 目標
- 16×16 の Part を Workspace に並べる
- GUI で地形マテリアル(Grass, Sand, Rock…)を選ぶ
- クリックした Part の色がパレットに応じて変わる
- 内部バッファ(16×16)にも値を保存する
- 後でこのバッファを 256×256 に拡大して Terrain に変換する
🟦 1. まず 16×16 の Part を並べるスクリプト
ServerScriptService に置く。
local folder = Instance.new("Folder")
folder.Name = "PaintGrid"
folder.Parent = workspace
local SIZE = 16
local PART_SIZE = 4
for y = 1, SIZE do
for x = 1, SIZE do
local p = Instance.new("Part")
p.Size = Vector3.new(PART_SIZE, 1, PART_SIZE)
p.Anchored = true
p.Position = Vector3.new(x * PART_SIZE, 0, y * PART_SIZE)
p.Name = x .. "_" .. y
p.Parent = folder
end
end
🟦 2. GUI でパレットを選ぶ
例として TextButton を並べた簡単なパレット。
StarterGui に ScreenGui → Frame → TextButton を複数置く。
例:
- Grass
- Sand
- Rock
- Mud
- Snow
LocalScript を Frame に入れる:
local palette = {
Grass = Color3.fromRGB(80, 200, 80),
Sand = Color3.fromRGB(230, 220, 170),
Rock = Color3.fromRGB(120, 120, 120),
Mud = Color3.fromRGB(90, 60, 40),
Snow = Color3.fromRGB(240, 240, 255)
}
local selected = "Grass"
for _,btn in pairs(script.Parent:GetChildren()) do
if btn:IsA("TextButton") then
btn.MouseButton1Click:Connect(function()
selected = btn.Name
end)
end
end
-- 選択中のパレットを他スクリプトが読めるように
_G.SelectedPalette = function()
return selected, palette[selected]
end
🟦 3. Part をクリックして色を変える
PaintGrid の Part にクリックイベントを付ける。
StarterPlayerScripts に LocalScript:
local player = game.Players.LocalPlayer
local mouse = player:GetMouse()
local buffer16 = {} -- 16x16 の内部バッファ
for y = 1, 16 do
buffer16[y] = {}
for x = 1, 16 do
buffer16[y][x] = "Grass" -- 初期値
end
end
mouse.Button1Down:Connect(function()
local target = mouse.Target
if not target then return end
if not target.Parent or target.Parent.Name ~= "PaintGrid" then return end
local name = target.Name -- "3_5" のような形式
local x, y = name:match("(%d+)_(%d+)")
x = tonumber(x)
y = tonumber(y)
local matName, color = _G.SelectedPalette()
-- Part の色を変える
target.Color = color
-- 内部バッファに保存
buffer16[y][x] = matName
end)
🟦 4. これで「対話的な 16×16 ペイント」が完成
- GUI でパレットを選ぶ
- Part をクリックすると色が変わる
- 内部バッファに地形マテリアル名が保存される
このバッファが 後で 256×256 に拡大して Terrain に変換する元データ になる。
🟦 5. 次のステップ(必要なら続けて作る)
ここから先は靖さんの OS 設計に合わせて、次の段階を作れる:
✔ 16×16 → 256×256 のガウス平滑アップサンプル
(前に書いた関数を統合)
✔ 256×256 を Terrain:SetMaterialHeightmap に変換
(MaterialMap と HeightMap を PNG 生成 or 数値配列で Terrain に書き込み)
✔ GUI に「筆圧」「ブラシサイズ」「にじみ」などを追加
(あなたの“半紙のにじみ”OS に合わせる)
次はどこを作りたい?
- バイリニア拡大
- ガウス平滑高速化(separable)
- Terrain への書き込み
- ブラシUIの強化
どれでもすぐ続けられるよ。