ひとりぶんの棚+1 Balloon

はじめての Roblox ゲーム作り
コードのページ

▶ 解説動画(16分)を YouTube で見る

解説動画で使うコードです。「コピー」を押して、Roblox Studio のスクリプトの画面に貼り付けます。貼り付ける前に、スクリプトの画面の中を一度クリックしてください。

2026年11月7日に Roblox Studio で動くことを確かめました。動画では途中で速さの 30 を 60 に変えています。コードは自由に使ってください。

1. 数字を出す(PlayerData)

ServerScriptService の中に Script を作り、名前を PlayerData にします。

-- プレイヤーが入ってきたら、右上に出す数字を作る
local Players = game:GetService("Players")

Players.PlayerAdded:Connect(function(player)
	local stats = Instance.new("Folder")
	stats.Name = "leaderstats"
	stats.Parent = player

	local balloons = Instance.new("IntValue")
	balloons.Name = "風船"
	balloons.Parent = stats

	local best = Instance.new("IntValue")
	best.Name = "最高の高さ"
	best.Parent = stats
end)

2. ポンプで風船を増やす(PumpScript)

Pump に ClickDetector を入れてから、Script を作り、名前を PumpScript にします。

-- ポンプを押すたびに、風船を1つ増やす
local pump = script.Parent
local click = pump.ClickDetector

click.MouseClick:Connect(function(player)
	local balloons = player.leaderstats["風船"]
	balloons.Value = balloons.Value + 1
end)

3. 空へ飛ぶ(PadScript)

LaunchPad の中に Script を作り、名前を PadScript にします。

-- 発射台に乗ったら、風船の数だけ空へ飛ぶ
local pad = script.Parent
local Players = game:GetService("Players")
local flying = {}

pad.Touched:Connect(function(hit)
	local character = hit.Parent
	local player = Players:GetPlayerFromCharacter(character)
	if player == nil or flying[player] then
		return
	end

	local balloons = player.leaderstats["風船"]
	if balloons.Value == 0 then
		return
	end

	flying[player] = true
	local count = balloons.Value
	balloons.Value = 0

	local root = character.HumanoidRootPart
	local startY = root.Position.Y

	-- 頭の上に風船を出す
	local parts = {}
	for i = 1, count do
		local ball = Instance.new("Part")
		ball.Shape = Enum.PartType.Ball
		ball.Size = Vector3.new(2, 2, 2)
		ball.Color = Color3.fromHSV(math.random(), 0.7, 1)
		ball.Massless = true
		ball.CanCollide = false
		ball.Position = root.Position + Vector3.new(math.random(-3, 3), math.random(5, 8), math.random(-3, 3))
		ball.Parent = character

		local weld = Instance.new("WeldConstraint")
		weld.Part0 = root
		weld.Part1 = ball
		weld.Parent = ball
		table.insert(parts, ball)
	end

	-- 上へ押す力をかける
	local attachment = Instance.new("Attachment")
	attachment.Parent = root

	local force = Instance.new("LinearVelocity")
	force.Attachment0 = attachment
	force.ForceLimitsEnabled = false
	force.VelocityConstraintMode = Enum.VelocityConstraintMode.Line
	force.LineDirection = Vector3.new(0, 1, 0)
	force.LineVelocity = 30
	force.RelativeTo = Enum.ActuatorRelativeTo.World
	force.Parent = root

	-- 風船1個につき1秒飛ぶ
	task.wait(count)

	local height = math.floor(root.Position.Y - startY)
	force:Destroy()
	attachment:Destroy()
	for _, ball in parts do
		ball:Destroy()
	end

	local best = player.leaderstats["最高の高さ"]
	if height > best.Value then
		best.Value = height
	end

	flying[player] = nil
end)

4. 記録を保存する(PlayerData を差し替え)

先に Roblox に保存し、バーチャル空間設定のセキュリティで「StudioのAPIサービスへのアクセスを有効化」をオンにしてから、1 のコードをこれに差し替えます。

-- プレイヤーが入ってきたら、右上に出す数字を作る。最高の高さは保存する
local Players = game:GetService("Players")
local DataStoreService = game:GetService("DataStoreService")
local store = DataStoreService:GetDataStore("BestHeight")

Players.PlayerAdded:Connect(function(player)
	local stats = Instance.new("Folder")
	stats.Name = "leaderstats"
	stats.Parent = player

	local balloons = Instance.new("IntValue")
	balloons.Name = "風船"
	balloons.Parent = stats

	local best = Instance.new("IntValue")
	best.Name = "最高の高さ"
	best.Parent = stats

	local ok, saved = pcall(function()
		return store:GetAsync("player_" .. player.UserId)
	end)
	if ok and saved then
		best.Value = saved
	end
end)

Players.PlayerRemoving:Connect(function(player)
	local best = player.leaderstats["最高の高さ"]
	pcall(function()
		store:SetAsync("player_" .. player.UserId, best.Value)
	end)
end)

-- サーバーが閉じる前に、保存が終わるのを少し待つ
game:BindToClose(function()
	task.wait(2)
end)

本物のゲーム

同じ骨組みから作ったゲームです。+1 Balloon: Float To Space