「タワーディフェンスみたいなゲームを自分で作りたい」「キットの中身が分からなくて、思いどおりに直せない」
ロブロックス(Roblox)スタジオでタワーディフェンスを作る方法を、実際の画像付きで誰でも簡単に分かるように解説します。タワーディフェンスは、道を歩いてくる敵をタワーで倒し、敵が拠点にたどり着く前に全部やっつけるゲームです。ここでは、キットを使わずに、道、敵、拠点、タワーを1から作ります。前編はタワーが敵を撃つところまで、後編はお金でタワーを買い足して好きな場所に置くところまでを作ります。
中級ステップ18/28 前の記事:ロブロックス(Roblox)のゲームが重いときの直し方 全体の順番を見る
使うもの:Roblox Studioが起動するパソコン、マウス、キーボード。敵の体はNPCの作り方、近くの相手を探すしかけは追いかけてくる敵の作り方、範囲の中の相手に当てるしかけは剣の攻撃の作り方と同じ考え方です。
今回の完成状態:下の画像のように、拠点の上にウェーブと体力が出て(画像の1)、タワーから黄色い線が敵に飛び(画像の2)、青い丸の中に入った敵が倒れていけば成功です(画像の3)。

タワーディフェンスの部品
| 名前 | 役目 |
|---|---|
| Road(茶色の道) | 敵が歩く道。見た目だけで、敵は目印をたどって歩く |
| Waypoints(黄色い目印) | 敵が「1」→「2」→「3」→「4」の順に歩く曲がり角 |
| Base(青い拠点) | 敵がたどり着くと体力が1減る。0になると負け |
| Tower(オレンジの柱) | 近くに来た敵を撃って体力を減らす |
| Enemy(敵) | ServerStorageにしまっておき、ウェーブごとに複製して出す |
| WaveService | 敵を出して歩かせ、ウェーブと拠点の体力を管理する |
| TowerService | タワーが敵を探して撃つ |
1. 部品を入れるフォルダーを作る
新しいBaseplateを開き、エクスプローラの「Workspace」にマウスを乗せて、右に出る「+」を押します(赤い枠)。

出てきた一覧の検索欄に「Folder」と入れ、一覧の「Folder」を押します(赤い枠)。

Workspaceの中にFolderが入ります。エクスプローラで選んだままF2キーを押し、名前を「TowerDefense」に変えます(赤い枠)。

同じように、今度はエクスプローラの「TowerDefense」にマウスを乗せて「+」からFolderを4つ入れ、名前を「Enemies」「Road」「Waypoints」「Towers」にします。TowerDefenseの中に4つのフォルダーが並びます(赤い枠)。

| フォルダー | 入れるもの |
|---|---|
| Enemies | テスト中に出てくる敵(今は空のまま) |
| Road | 道のパーツ3つ |
| Waypoints | 曲がり角の目印4つ |
| Towers | タワー |
2. 敵が歩く道を作る
エクスプローラの「Road」にマウスを乗せて「+」を押し、検索欄に「Part」と入れて、一覧の「Part」を押します(赤い枠)。

Roadの中にPartが入ります。エクスプローラでF2キーを押し、名前を「Road1」に変えます(赤い枠)。

プロパティの検索欄に「Size」と入れ、Sizeを「40, 0.2, 4」にします(赤い枠)。細長くて薄い板になります。

プロパティの検索欄に「Position」と入れ、「▼CFrame」のすぐ下のPositionを「0, 0.1, -20」にします(赤い枠)。

プロパティの検索欄に「BrickColor」と入れ、茶色の「Reddish brown」を選びます(赤い枠)。

プロパティの検索欄に「Anchored」と入れ、チェックを入れて固定します(赤い枠)。

エクスプローラでRoad1を選んでCtrlキーとDキーを一緒に押すと、同じ設定のパーツが複製されます。2回押して「Road1」を3つにしたら、下の「Road1」の1つを押して選び、F2キーを押して名前を「Road2」に変えます(赤い枠)。

残りのもう1つの「Road1」を押して選び、F2キーを押して名前を「Road3」に変えます。続けて、Road2とRoad3にSizeとPositionを入れます。
Road2
- エクスプローラで「Road2」を押して選びます。
- Road2を選んだまま、プロパティの検索欄に「Size」と入力し、Sizeに「4, 0.2, 24」と入れてEnterキーを押します。
- Road2を選んだまま、プロパティの検索欄に「Position」と入力し、▼CFrameのすぐ下のPositionに「18, 0.1, -30」と入れてEnterキーを押します。
Road3
- エクスプローラで「Road3」を押して選びます。
- Road3を選んだまま、プロパティの検索欄に「Size」と入力し、Sizeに「40, 0.2, 4」と入れてEnterキーを押します。
- Road3を選んだまま、プロパティの検索欄に「Position」と入力し、▼CFrameのすぐ下のPositionに「0, 0.1, -40」と入れてEnterキーを押します。
3本の道が「コ」の字につながれば完成です。入れた値は次の表のとおりです(赤い枠が Road2 と Road3)。
| 名前 | Size | Position |
|---|---|---|
| Road1 | 40, 0.2, 4 | 0, 0.1, -20 |
| Road2 | 4, 0.2, 24 | 18, 0.1, -30 |
| Road3 | 40, 0.2, 4 | 0, 0.1, -40 |

3. 敵が歩く順番の目印を置く
敵は道の上を見て歩くわけではありません。曲がり角に置いた目印を、名前の数字の順に歩きます。エクスプローラの「Waypoints」にマウスを乗せて、右に出る「+」を押します(赤い枠)。

一覧の検索欄に「Part」と入れ、一覧の「Part」を押します(赤い枠)。

エクスプローラで選んだままF2キーを押し、名前を半角の「1」に変えます(赤い枠)。

プロパティの検索欄に「CanCollide」と入れ、チェックを外します(赤い枠)。目印に敵やプレイヤーがぶつからないようにするためです。

プロパティの検索欄に「Size」と入力し、Sizeを「2, 0.2, 2」にします(赤い枠)。

プロパティの検索欄に「Position」と入力し、CFrameの下のPositionを「-18, 0.3, -20」にします(赤い枠)。道の左手前の端です。

プロパティの検索欄に「BrickColor」と入力し、黄色の「New Yeller」にします(赤い枠)。

プロパティの検索欄に「Anchored」と入力し、チェックを入れて固定します(赤い枠)。

エクスプローラで「1」を選んでCtrl+Dキーを押すと、「1」が複製されます。複製された下の「1」を選んだままF2キーを押し、名前を「2」に変えます(赤い枠)。

「2」を選んだまま、プロパティの検索欄に「Position」と入力し、▼CFrameのすぐ下のPositionに「18, 0.3, -20」と入れてEnterキーを押します。
「3」と「4」も、「1」を複製して作ります。
3
- エクスプローラで「1」を押して選び、Ctrl + Dキーを押します。複製した下の「1」が選ばれた状態になります。
- そのままF2キーを押し、名前を半角の「3」に変えます。
- 「3」を選んだまま、プロパティの検索欄に「Position」と入力し、▼CFrameのすぐ下のPositionに「18, 0.3, -40」と入れてEnterキーを押します。
4
- エクスプローラで「1」を押して選び、Ctrl + Dキーを押します。複製した下の「1」が選ばれた状態になります。
- そのままF2キーを押し、名前を半角の「4」に変えます。
- 「4」を選んだまま、プロパティの検索欄に「Position」と入力し、▼CFrameのすぐ下のPositionに「-18, 0.3, -40」と入れてEnterキーを押します。
4つの目印の値は次の表のとおりです。目印の名前は、半角の数字にします。全角の「1」だと、スクリプトが順番を読めません。
| 名前 | Position | 場所 |
|---|---|---|
| 1 | -18, 0.3, -20 | スタート(敵が出てくる) |
| 2 | 18, 0.3, -20 | 右手前の角 |
| 3 | 18, 0.3, -40 | 右奥の角 |
| 4 | -18, 0.3, -40 | ゴール(拠点の前) |
4つとも置くと、エクスプローラのWaypointsの中に「1」から「4」の4つができ(画像の1)、道の4つの角に黄色い目印が付きます(画像の2)。エクスプローラでの並び順はばらばらでもかまいません。スクリプトは名前の数字の順に目印をたどります。

4. タワーと拠点を置く
エクスプローラの「Towers」にマウスを乗せて、右に出る「+」を押します(赤い枠)。

一覧の検索欄に「Part」と入れ、一覧の「Part」を押します(赤い枠)。

エクスプローラで選んだままF2キーを押し、名前を「Tower」に変えます(赤い枠)。

Towerを選んだまま、次の4つを1つずつ変えます。どれもプロパティの検索欄に名前を入れ、数字は右の欄に入れてEnterキーを押します。
- プロパティの検索欄に「Size」と入れ、Sizeを「2, 6, 2」にします(下の1枚目)
- プロパティの検索欄に「Position」と入れ、「▼CFrame」のすぐ下のPositionを「0, 3, -30」にします(下の2枚目)
- プロパティの検索欄に「BrickColor」と入れ、右の欄を押してオレンジの「Bright orange」を選びます(下の3枚目)
- プロパティの検索欄に「Anchored」と入れ、右の四角を押してチェックを入れて固定します(下の4枚目)
4つとも入れると、道の「コ」の字の内側に、オレンジの背の高い柱が立ちます。画像の1が入れた値、画像の2が柱です。
エクスプローラの「TowerDefense」にマウスを乗せて、右に出る「+」を押します(赤い枠)。

一覧の検索欄に「Part」と入れ、一覧の「Part」を押します(赤い枠)。

エクスプローラで選んだままF2キーを押し、名前を「Base」に変えます(赤い枠)。

Baseを選んだまま、Towerと同じように次の4つを1つずつ変えます。
- プロパティの検索欄に「Size」と入れ、Sizeを「6, 6, 6」にします(下の1枚目)
- プロパティの検索欄に「Position」と入れ、「▼CFrame」のすぐ下のPositionを「-24, 3, -40」にします(下の2枚目)
- プロパティの検索欄に「BrickColor」と入れ、右の欄を押して青の「Bright blue」を選びます(下の3枚目)
- プロパティの検索欄に「Anchored」と入れ、右の四角を押してチェックを入れて固定します(下の4枚目)
4つとも入れると、道の終わりに青い箱が置かれます。画像の1が入れた値、画像の2が箱です。
| 名前 | 入れる場所 | Size | Position | 色 |
|---|---|---|---|---|
| Tower | Towers | 2, 6, 2 | 0, 3, -30 | Bright orange |
| Base | TowerDefense | 6, 6, 6 | -24, 3, -40 | Bright blue |
5. 拠点の上に体力を出す看板を付ける
エクスプローラの「Base」にマウスを乗せて「+」を押し、検索欄に「BillboardGui」と入れて、一覧の「BillboardGui」を押します(赤い枠)。BillboardGuiは、パーツの上に浮かぶ看板です。看板の作り方は看板や頭の上に文字を出す方法でも解説しています。

プロパティの検索欄に「StudsOffset」と入れ、「0, 6, 0」にします(赤い枠)。看板が拠点の6スタッド上に浮きます。Sizeは最初から「{0, 200},{0, 50}」になっているので、そのままにします。

プロパティの検索欄に「AlwaysOnTop」と入れ、チェックを入れます(赤い枠)。敵やタワーの後ろに隠れても、看板が見えるようになります。

エクスプローラの「BillboardGui」にマウスを乗せて「+」を押し、検索欄に「TextLabel」と入れて、一覧の「TextLabel」を押します(赤い枠)。

プロパティの検索欄に「Size」と入れ、TextLabelのSizeを「{1, 0},{1, 0}」にします(赤い枠)。看板いっぱいに文字の欄が広がります。

プロパティの検索欄に「TextScaled」と入れ、チェックを入れます(赤い枠)。文字が欄の大きさに合わせて大きくなります。

プロパティの検索欄に「Text」と入れ、Textを「拠点」にします(画像の1)。拠点の上に「拠点」と書かれた看板が浮かびます(画像の2)。テストを始めると、この文字はスクリプトがウェーブと体力に書きかえます。

6. 敵の体を作ってServerStorageにしまう
ホームタブの「キャラクター」を押します(画像の1)。「リグを生成」の窓が出たら、リグタイプ「R15」、体型「男子型」のまま、「ブロック型アバター(2012年)」を押します(画像の2)。

エクスプローラのWorkspaceに「Rig」が入り(画像の1)、3D画面に人の形の体が出ます(画像の2)。

エクスプローラでRigを選んだままF2キーを押し、名前を「Enemy」に変えます(赤い枠)。

リグの体は固定(Anchored)されていません。敵のパーツは固定しないでください。固定すると歩けなくなります。
エクスプローラでEnemyの左の三角を押して中を開き、「Humanoid」を選びます。プロパティの検索欄に「DisplayName」と入れ、「敵」にします(画像の1)。頭の上の名前が「敵」になります(画像の2)。

エクスプローラでEnemyをドラッグして、「ServerStorage」の上で離します。EnemyがServerStorageの中に移り、3D画面から消えます(赤い枠)。

ServerStorageの中のものは、ゲームの画面には出ません。スクリプトがこのEnemyを複製して、1体ずつ道に出します。手本を1体だけ用意しておけば、何体でも出せます。
7. 敵を歩かせるスクリプトを入れる
エクスプローラの「ServerScriptService」にマウスを乗せて「+」を押し、検索欄に「Script」と入れて、一覧の「Script」を押します(赤い枠)。

Scriptが入り、中身の画面が開きます。エクスプローラで「Script」を押して選び、F2キーを押して名前を「WaveService」に変えます(赤い枠)。

プロパティの検索欄に「RunContext」と入れて、「▼動作」の欄にあるRunContextの一覧から「Server」を選びます(赤い枠)。

開いているWaveServiceの画面で、中身を全部消して、次のコードを貼り付けます。
local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")
local td = workspace:WaitForChild("TowerDefense")
local waypointFolder = td:WaitForChild("Waypoints")
local enemies = td:WaitForChild("Enemies")
local base = td:WaitForChild("Base")
local label = base:WaitForChild("BillboardGui"):WaitForChild("TextLabel")
local enemyTemplate = ServerStorage:WaitForChild("Enemy")
local BASE_HEALTH = 10 -- 拠点の体力
local WAVES = 3 -- 全部で何ウェーブあるか
local SPAWN_SECONDS = 2 -- 敵を何秒ごとに出すか
local ENEMY_SPEED = 8 -- 敵の歩く速さ(プレイヤーは16)
local ENEMY_HEALTH = 100 -- 敵の体力
local health = BASE_HEALTH
local wave = 0
-- 敵どうしがぶつからないようにする(ぶつかると押されて道から落ちる)
local ENEMY_GROUP = "Enemies"
if not workspace:IsCollisionGroupRegistered(ENEMY_GROUP) then
workspace:RegisterCollisionGroup(ENEMY_GROUP)
end
workspace:CollisionGroupSetCollidable(ENEMY_GROUP, ENEMY_GROUP, false)
-- 目印を名前の「1」「2」「3」…の順に並べる
local waypoints = waypointFolder:GetChildren()
table.sort(waypoints, function(a, b)
return tonumber(a.Name) < tonumber(b.Name)
end)
-- 拠点の上の文字を書きかえる
local function updateLabel()
label.Text = "ウェーブ " .. wave .. "/" .. WAVES .. "\n拠点の体力 " .. health
end
-- 敵を1体出して、目印の順に歩かせる
local function spawnEnemy()
local enemy = enemyTemplate:Clone()
local humanoid = enemy:WaitForChild("Humanoid")
local root = enemy:WaitForChild("HumanoidRootPart")
humanoid.WalkSpeed = ENEMY_SPEED
humanoid.MaxHealth = ENEMY_HEALTH
humanoid.Health = ENEMY_HEALTH
for _, part in enemy:GetDescendants() do
if part:IsA("BasePart") then
part.CollisionGroup = ENEMY_GROUP
end
end
enemy:PivotTo(waypoints[1].CFrame + Vector3.new(0, 3, 0))
enemy.Parent = enemies
root:SetNetworkOwner(nil) -- 敵の動きはサーバーが計算する
-- 倒されたら1秒後に消す
humanoid.Died:Connect(function()
task.wait(1)
enemy:Destroy()
end)
task.spawn(function()
for i = 2, #waypoints do
if humanoid.Health <= 0 or health <= 0 then
return
end
humanoid:MoveTo(waypoints[i].Position)
humanoid.MoveToFinished:Wait()
end
-- 最後の目印まで歩けた=拠点にたどり着いた
if humanoid.Health > 0 and enemy.Parent == enemies then
enemy:Destroy()
health = math.max(health - 1, 0)
updateLabel()
end
end)
end
-- だれかがゲームに入るまで待ってから始める
while #Players:GetPlayers() == 0 do
task.wait(1)
end
task.wait(5)
for w = 1, WAVES do
wave = w
updateLabel()
local count = w * 2 + 1 -- 3体、5体、7体と増える
for n = 1, count do
if health <= 0 then
break
end
spawnEnemy()
task.wait(SPAWN_SECONDS)
end
-- 道の上の敵がいなくなるまで待つ
while #enemies:GetChildren() > 0 and health > 0 do
task.wait(0.5)
end
if health <= 0 then
break
end
task.wait(5) -- 次のウェーブまでのひと休み
end
if health <= 0 then
enemies:ClearAllChildren()
label.Text = "拠点がやられた…"
else
label.Text = "ぜんぶ守りきった!\n拠点の体力 " .. health
end

| コードの部分 | していること |
|---|---|
| table.sort | 目印を名前の「1」「2」「3」「4」の順に並べる |
| RegisterCollisionGroup | 敵どうしがぶつからないグループを作る。ぶつかると押し合って道から落ちる |
| spawnEnemy | ServerStorageのEnemyを複製して目印「1」に置き、「2」「3」「4」の順に歩かせる |
| MoveToFinished:Wait() | 次の目印に着くまで待つ |
| health – 1 | 最後の目印まで歩けた敵を消して、拠点の体力を1減らす |
| w * 2 + 1 | ウェーブ1は3体、2は5体、3は7体と、だんだん敵を増やす |
敵を歩かせるのも、拠点の体力を減らすのも、サーバーで動くこのScriptだけです。
8. タワーなしでテストする
3D画面の上の作品のタブ「Place2」を押して3D画面に戻り、F5キーでテストを始めます(タブの名前はパソコンによって違います)。5秒ほどで目印「1」から敵が出てきて、道を歩き始めます(画像の2)。拠点の上には「ウェーブ 1/3 拠点の体力 10」と出ます(画像の1)。
画像は、道全体が見えるようにカメラを上に引いて写しています。テスト中にマウスのホイールを手前に回すと、カメラを引けます。

まだタワーは撃たないので、敵は「2」「3」「4」の角を曲がって拠点にたどり着きます。たどり着いた敵が消えるたびに、体力が1ずつ減ります。ウェーブ1の途中で、体力が9になりました(赤い枠)。

ウェーブ1の3体がすべてたどり着いて体力は7になり、敵が5体に増えたウェーブ2で2まで減りました。7体が出てくるウェーブ3で体力が0になり、「拠点がやられた…」と出ました(赤い枠)。

確かめたら、停止ボタンでテストを終わります。
9. タワーが敵を撃つスクリプトを入れる
Shift + F5キーでテストを停止します。エクスプローラの「ServerScriptService」にマウスを乗せて「+」を押し、検索欄に「Script」と入れて、一覧の「Script」を押します(赤い枠)。

エクスプローラで新しい「Script」を押して選び、F2キーを押して名前を「TowerService」に変えます(赤い枠)。

プロパティの検索欄に「RunContext」と入れて、RunContextの一覧から「Server」を選びます(赤い枠)。

開いているTowerServiceの画面で、中身を全部消して、次のコードを貼り付けます。貼り付けたら、エクスプローラのServerScriptServiceの中にTowerServiceとWaveServiceの2つが並んでいるかを確かめます(赤い枠)。
local td = workspace:WaitForChild("TowerDefense")
local towers = td:WaitForChild("Towers")
local enemies = td:WaitForChild("Enemies")
local RANGE = 16 -- 弾が届く距離(スタッド)
local DAMAGE = 25 -- 1発で減らす体力
local COOLDOWN = 1 -- 次に撃つまでの秒数
local SHOW_RANGE = true -- 届く範囲を床に丸く見せる
local lastShot = {} -- タワーごとの、最後に撃った時刻
-- 「敵」フォルダーの中の部品だけを探す
local params = OverlapParams.new()
params.FilterType = Enum.RaycastFilterType.Include
params.FilterDescendantsInstances = { enemies }
-- タワーのまわりの丸い範囲で、いちばん近い生きている敵を探す
local function findTarget(tower)
local parts = workspace:GetPartBoundsInRadius(tower.Position, RANGE, params)
local nearest = nil
local nearestDistance = math.huge
for _, part in parts do
local enemy = part:FindFirstAncestorOfClass("Model")
local humanoid = enemy and enemy:FindFirstChildOfClass("Humanoid")
local root = enemy and enemy:FindFirstChild("HumanoidRootPart")
if humanoid and root and humanoid.Health > 0 then
local distance = (root.Position - tower.Position).Magnitude
if distance < nearestDistance then
nearest = enemy
nearestDistance = distance
end
end
end
return nearest
end
-- タワーの上から敵まで、黄色い線を0.2秒だけ見せる
local function showShot(from, to)
local distance = (to - from).Magnitude
local shot = Instance.new("Part")
shot.Anchored = true
shot.CanCollide = false
shot.CanQuery = false
shot.CanTouch = false
shot.Material = Enum.Material.Neon
shot.Color = Color3.fromRGB(255, 220, 0)
shot.Size = Vector3.new(0.3, 0.3, distance)
shot.CFrame = CFrame.lookAt(from, to) * CFrame.new(0, 0, -distance / 2)
shot.Parent = workspace
task.delay(0.2, function()
shot:Destroy()
end)
end
-- 届く範囲を、タワーの足元に半透明の丸で見せる
local function showRange(tower)
local ring = Instance.new("Part")
ring.Name = "Range"
ring.Shape = Enum.PartType.Cylinder
ring.Anchored = true
ring.CanCollide = false
ring.CanQuery = false
ring.CanTouch = false
ring.Material = Enum.Material.SmoothPlastic
ring.Color = Color3.fromRGB(0, 170, 255)
ring.Transparency = 0.8
ring.Size = Vector3.new(0.2, RANGE * 2, RANGE * 2)
ring.CFrame = CFrame.new(tower.Position.X, 0.15, tower.Position.Z) * CFrame.Angles(0, 0, math.rad(90))
ring.Parent = tower
end
if SHOW_RANGE then
for _, tower in towers:GetChildren() do
showRange(tower)
end
towers.ChildAdded:Connect(showRange)
end
-- 0.1秒ごとに、撃てるタワーが敵を撃つ
while true do
local now = os.clock()
for _, tower in towers:GetChildren() do
local ready = not lastShot[tower] or now - lastShot[tower] >= COOLDOWN
if tower:IsA("BasePart") and ready then
local target = findTarget(tower)
if target then
lastShot[tower] = now
local top = tower.Position + Vector3.new(0, tower.Size.Y / 2, 0)
showShot(top, target.HumanoidRootPart.Position)
target:FindFirstChildOfClass("Humanoid"):TakeDamage(DAMAGE)
end
end
end
task.wait(0.1)
end

| コードの部分 | していること |
|---|---|
| GetPartBoundsInRadius | タワーを中心にした丸い範囲(RANGEで決めた半径16スタッド)に入っている部品を集める |
| FilterType Include | 「Enemies」フォルダーの中の部品だけを数える。道やタワー、プレイヤーは数えない |
| findTarget | 範囲の中で、いちばん近い生きている敵を選ぶ |
| TakeDamage | 選んだ敵の体力を、DAMAGEで決めた25だけ減らす。WaveServiceのENEMY_HEALTHで体力を100にした敵は、4発で倒れる |
| COOLDOWN | 1発撃ったら、1秒待ってから次を撃つ |
| showShot・showRange | 弾の線と届く範囲を見せる。当たり判定には入らない |
剣の攻撃では、体の前の箱の中を調べました。タワーは、自分のまわりの丸い範囲の中を調べます。調べる形が箱か丸かが違うだけで、しくみは同じです。
10. タワーありでテストする
3D画面の上の作品のタブ「Place2」を押して3D画面に戻り、F5キーでテストを始めます(タブの名前はパソコンによって違います)。タワーのまわりに青い丸(届く範囲)が出ます(画像の3)。敵が丸に入ると、タワーから黄色い線が飛び(画像の2)、敵の頭の上の体力の棒が減っていきます。ウェーブ1の敵は全部倒れて、拠点の体力は10のままでした(画像の1)。

ウェーブ3まで終わると、「ぜんぶ守りきった! 拠点の体力 2」と出ました(赤い枠)。2回試して、2回とも体力2で守りきりました。敵の歩き方が毎回少しずつ違うので、残る体力は試すたびに変わることがあります。

| 試したこと | 結果 |
|---|---|
| タワーなし | ウェーブ1で体力7、ウェーブ2で2、ウェーブ3で「拠点がやられた…」 |
| タワー1つ | ウェーブ1は体力10のまま、最後は体力2で守りきった |
タワー1つでも守りきれましたが、敵が5体、7体と増えると、何体かは拠点までたどり着いてしまいます。タワーを増やせば、もっと楽に守れます。後編では、敵を倒すとお金がもらえて、そのお金でタワーを買い、好きな場所に置けるようにします。
数字を変えて遊びを調整する
| 変えたいこと | 変える数 | 例 |
|---|---|---|
| 拠点の体力 | WaveServiceのBASE_HEALTH | 10 → 20にすると負けにくい |
| ウェーブの数 | WaveServiceのWAVES | 3 → 5 |
| 敵の速さ | WaveServiceのENEMY_SPEED | 8 → 12にすると、タワーが撃てる回数が減って難しくなる |
| 敵の体力 | WaveServiceのENEMY_HEALTH | 100 → 150 |
| タワーの届く距離 | TowerServiceのRANGE | 16 → 20 |
| タワーの強さ | TowerServiceのDAMAGE | 25 → 50にすると2発で倒れる |
| 撃つ間隔 | TowerServiceのCOOLDOWN | 1 → 0.5にすると2倍の速さで撃つ |
数字は1つずつ変えて、そのたびにテストするのがコツです。いくつも一度に変えると、どれが効いたのか分からなくなります。
敵が歩かない・タワーが撃たないときの確かめ方
| 症状 | 見るところ | 直し方 |
|---|---|---|
| 敵が出てこない | ServerStorage | 「Enemy」という名前でServerStorageの中にあるか |
| 敵が出てすぐ止まる | Waypoints | 目印の名前が半角の数字「1」「2」「3」「4」か |
| 敵が変な方向へ歩く | 目印のPosition | 表の値と同じか。数字の順番が道の順番になっているか |
| 敵が目印の上で止まってしまう | 目印のCanCollide | チェックを外したか |
| 看板の文字が変わらない | Baseの中 | BillboardGuiの中にTextLabelがあるか、名前を変えていないか |
| タワーが撃たない | Towers | Towerが「Towers」フォルダーの中にあるか |
| 青い丸が出ない | TowerService | RunContextが「Server」か、出力に赤い文字が出ていないか |
AIに相談するときの伝え方
Roblox Studioで、キットを使わずにタワーディフェンスを作っています。
ServerScriptServiceのScript「WaveService」で、ServerStorageのEnemy(R15のリグ)を複製し、Workspace.TowerDefense.Waypointsの「1」「2」「3」「4」の順にHumanoid:MoveToで歩かせています。
Script「TowerService」では、Towersの中のパーツがGetPartBoundsInRadiusで半径16の中のいちばん近い敵に、1秒ごとに25のダメージを与えています。
足が速くて体力の少ない敵を、ウェーブ2から混ぜたいです。
よくある質問
敵の歩く道を長くしたい
道のパーツを足して、曲がり角に目印を置き、名前を「5」「6」…と続けます。最後の数字の目印が、拠点の前になるようにします。コードは目印の数を数えて歩かせるので、書きかえなくて大丈夫です。
タワーを増やしたい
エクスプローラでTowerを選んでCtrl+Dで複製し、プロパティでPositionを変えて「Towers」フォルダーの中に置きます。TowerServiceは「Towers」の中のパーツを全部タワーとして動かすので、コードを変えなくても撃ち始めます。
敵がプレイヤーを攻撃してくる?
このコードの敵は、道を歩くだけでプレイヤーを攻撃しません。触れると体力が減る敵は、追いかけてくる敵の作り方で作れます。
次は、お金でタワーを買って、好きな場所に置けるようにします。次のステップ(中級 19/28)
次に知りたいことを選ぶ
- 次のステップ:お金でタワーを買って、好きな場所に置けるようにします → ロブロックス(Roblox)スタジオでタワーディフェンスを作る方法【後編】
- 近くの相手を探すしかけを知りたい → ロブロックス(Roblox)で追いかけてくる敵の作り方
- 範囲の中の相手に当てるしかけを知りたい → ロブロックス(Roblox)スタジオで剣の攻撃を作る方法
- お金をためて買い足すゲームを作りたい → ロブロックス(Roblox)スタジオでタイクーンを作る方法







