「ゲームに剣を出して、敵を斬れるようにしたい」「剣を振っても相手の体力が減らない」
ロブロックス(Roblox)スタジオで剣の攻撃を作る方法を、実際の画像付きで誰でも簡単に分かるように解説します。ここでは、クリックすると体の前にいる相手の体力が20減る剣を作り、練習用のダミーを倒すところと、2人で斬り合うところまで確かめます。
中級ステップ12/28 前の記事:ロブロックス(Roblox)スタジオで手に持てるアイテム(ツール)を作る方法 全体の順番を見る
使うもの:Roblox Studioが起動するパソコン、マウス、キーボード。手に持てるアイテムの作り方はアイテム(ツール)を作る方法、サーバーに知らせる仕組みはRemoteEventの使い方で解説しています。
今回の完成状態:下の画像のように、剣を振ると体の前に赤い範囲が一瞬出て、その中にいるダミーの体力が減れば成功です。

剣の攻撃は3つの部品でできている
| 部品 | 置く場所 | 役目 |
|---|---|---|
| Tool「Sword」とLocalScript | StarterPack | 剣の形。クリックされたら「振った」とサーバーに知らせる |
| RemoteEvent「SwingSword」 | ReplicatedStorage | 知らせを届ける通り道 |
| Script「SwordService」 | ServerScriptService | 当たったか確かめて、相手の体力を減らす |
だれに当たって、どれだけ減らすかは、サーバーが決めます。遊ぶ人のパソコンから「20減らして」と送る作りにすると、ずるをする人が大きな数を送れてしまうからです。
1. 剣の形を作る
新しいBaseplateを開き、エクスプローラの「Workspace」にマウスを乗せて、右に出る「+」を押します。検索欄に「Tool」と入力し、一覧の「Tool」を押します。
エクスプローラでWorkspaceの中に入った「Tool」を選んだ状態でF2キーを押し、名前を「Sword」に変えます。
エクスプローラの「Sword」にマウスを乗せて「+」を押し、検索欄に「Part」と入力して、一覧の「Part」を押します。
エクスプローラでSwordの中に入った「Part」を選んだ状態でF2キーを押し、名前を「Handle」に変えます(赤い枠)。Toolのくわしい説明はアイテムを作る方法で解説しています。

Handleのプロパティは次のとおりにします。
| プロパティ | 値 |
|---|---|
| Size | 0.4, 1.2, 0.4 |
| Color | 105, 64, 40(BrickColorの欄は「Reddish brown」になる) |
| Position(▼CFrameのすぐ下) | 0, 0.6, -8 |
| Anchored | チェックなし(最初のまま) |
順にやっていきます。エクスプローラでHandleを選んだ状態で、プロパティの検索欄に「Size」と入力し、Sizeの欄を「0.4, 1.2, 0.4」にしてEnterキーを押します(赤い枠)。

続けてHandleを選んだまま、プロパティの検索欄に「Color」と入力します。BrickColorとColorの2つの欄が並ぶので、下のColorの欄の数字を「105, 64, 40」に書き換えてEnterキーを押します。柄が茶色になり、上のBrickColorの欄が「Reddish brown」に変わります(赤い枠)。

続けてHandleを選んだまま、プロパティの検索欄に「Position」と入力し、「▼CFrame」のすぐ下のPositionを「0, 0.6, -8」にしてEnterキーを押します。スポーン地点の前に置かれます(赤い枠)。

続けてHandleを選んだまま、プロパティの検索欄に「Anchored」と入力します。Anchoredのチェックは最初から外れているのでそのままにします(赤い枠)。

次は刃です。エクスプローラの「Sword」にマウスを乗せて「+」を押し、検索欄に「Part」と入力して、一覧の「Part」を押します。
エクスプローラでSwordの中に新しく入った「Part」を選んだ状態でF2キーを押し、名前を「Blade」(刃)に変えます。
Bladeのプロパティは次のとおりにします。
| プロパティ | 値 |
|---|---|
| Size | 0.3, 4, 0.8 |
| BrickColor | Medium stone grey(最初のまま) |
| Position(▼CFrameのすぐ下) | 0, 3.2, -8 |
| Anchored | チェックなし(最初のまま) |
順にやっていきます。Bladeを選んだまま、プロパティの検索欄に「Size」と入力し、Sizeの欄を「0.3, 4, 0.8」にしてEnterキーを押します(赤い枠)。

続けてBladeを選んだまま、プロパティの検索欄に「Color」と入力すると、BrickColorは最初から灰色の「Medium stone grey」になっています(赤い枠)。灰色の刃にするので、色は変えません。

続けてBladeを選んだまま、プロパティの検索欄に「Position」と入力し、「▼CFrame」のすぐ下のPositionを「0, 3.2, -8」にしてEnterキーを押します(赤い枠)。Handleの上の端(高さ1.2)にBladeの下の端がちょうど重なる高さです。Handleを別の場所に置いたときは、Handleの数より2.6だけ上にします。

続けてBladeを選んだまま、プロパティの検索欄に「Anchored」と入力します。Bladeも、Anchoredのチェックは最初から外れているのでそのままにします(赤い枠)。

続けて、エクスプローラの「Handle」にマウスを乗せて「+」を押し、検索欄に「WeldConstraint」と入力して、一覧の「WeldConstraint」を押します。エクスプローラにはBlade(画像の1)が並び、Handleの中にWeldConstraint(画像の2)が入ります。3D画面には剣の形ができています(画像の3)。

WeldConstraint(ウェルドコンストレイント)は、2つのパーツをくっつける部品です。プロパティの「Part0」を「Handle」、「Part1」を「Blade」にします(赤い枠)。これで、手に持ったときに刃も一緒に動きます。
※「Part0」「Part1」は文字を打ち込むのではなく、エクスプローラから部品を選んで入れます。WeldConstraintを選んだまま、プロパティの「Part0」の右の空欄を押し、続けてエクスプローラの「Handle」を押します。「Part1」も同じように空欄を押してから「Blade」を押します。

2. 剣をStarterPackに入れ、練習用のダミーを置く
エクスプローラでSwordをStarterPackへドラッグして移します。StarterPackの中のアイテムは、全員が最初から持っています。
練習の相手として、キャラクターを1体入れます。3D画面上部メニューの「ホーム」タブにある「キャラクター」ボタン(「地形」ボタンの右)を押します。
「リグを生成」の窓が開きます。リグタイプの「R15」を選んだまま、「ブロック型アバター(2012年)」を押します。窓の画像はNPCを作る方法の1で見られます。
エクスプローラのWorkspaceの中に「Rig」が入ります。Rigを選んだ状態でF2キーを押し、名前を「Dummy」に変えます(赤い枠)。

エクスプローラでDummyを選び、プロパティの検索欄に「Origin」と入力して、Originの下のPositionを「0, 3, -14」にしてEnterキーを押します(赤い枠)。スポーン地点の前に立ちます。画面では最初の数が「-0」と出ることがありますが、0と同じです。

エクスプローラでDummyの左の三角を押して開き、中の「Humanoid」を選びます。続けてHumanoidを選んだまま、プロパティの検索欄に「MaxHealth」と入力すると、MaxHealth(体力の上限)は100でした(赤い枠)。

エクスプローラのStarterPackの中にSword(画像の1)、3D画面にDummy(画像の2)があれば準備はできています。

3. 知らせの通り道(RemoteEvent)を入れる
エクスプローラの「ReplicatedStorage」にマウスを乗せて「+」を押し、検索欄に「RemoteEvent」と入力して、一覧の「RemoteEvent」を押します。
エクスプローラでReplicatedStorageの中に入った「RemoteEvent」を選んだ状態でF2キーを押し、名前を「SwingSword」に変えます(赤い枠)。

4. クリックを伝えるLocalScriptを入れる
エクスプローラのStarterPackの中の「Sword」にマウスを乗せて「+」を押し、検索欄に「LocalScript」と入力して、一覧の「LocalScript」を押します。
エクスプローラでSwordの中に入った「LocalScript」を選んだ状態でF2キーを押し、名前を「SwingClient」に変えます。
SwingClientの画面で、中身を全部消して、次のコードを貼り付けます。
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local swingSword = ReplicatedStorage:WaitForChild("SwingSword")
local tool = script.Parent
-- クリック(スマホはタップ)したら「振った」とだけサーバーに伝える
tool.Activated:Connect(function()
swingSword:FireServer()
end)

このコードは、クリック(スマホならタップ)されたことを、FireServerでサーバーに伝えるだけです。だれに当たったか、何点減らすかは送りません。
5. 当たり判定のScriptを入れる
エクスプローラの「ServerScriptService」にマウスを乗せて「+」を押し、検索欄に「Script」と入力して、一覧の「Script」を押します。
エクスプローラでServerScriptServiceの中に入った「Script」を選んだ状態でF2キーを押し、名前を「SwordService」に変えます。
SwordServiceを選んだまま、プロパティの検索欄に「RunContext」と入力し、「▼動作」の欄にあるRunContextの一覧から「Server」を選びます(赤い枠)。RunContext(ランコンテキスト)は、スクリプトをサーバーとプレイヤーのパソコンのどちらで動かすかを決める設定です。

SwordServiceの画面で、中身を全部消して、次のコードを貼り付けます。
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local swingSword = ReplicatedStorage:WaitForChild("SwingSword")
local TOOL_NAME = "Sword" -- 剣の Tool の名前
local DAMAGE = 20 -- 1回当たったときに減らす体力
local COOLDOWN = 0.6 -- 次に振れるまでの秒数
local BOX_SIZE = Vector3.new(5, 5, 5) -- 攻撃が届く箱の大きさ
local BOX_OFFSET = CFrame.new(0, 0, -3) -- 箱を体の前へずらす(-Z が前)
local SHOW_BOX = true -- テスト中は攻撃の範囲を赤く見せる
local lastSwing = {} -- 人ごとの、最後に振った時刻
-- 攻撃の範囲を0.2秒だけ赤く見せる(当たり判定には入らない)
local function showBox(boxCFrame)
local box = Instance.new("Part")
box.Anchored = true
box.CanCollide = false
box.CanQuery = false
box.CanTouch = false
box.Size = BOX_SIZE
box.CFrame = boxCFrame
box.Color = Color3.fromRGB(255, 0, 0)
box.Transparency = 0.7
box.Parent = workspace
task.delay(0.2, function()
box:Destroy()
end)
end
swingSword.OnServerEvent:Connect(function(player)
-- 1. 続けて振りすぎていないか
local now = os.clock()
if lastSwing[player] and now - lastSwing[player] < COOLDOWN then
return
end
-- 2. 生きていて、剣を手に持っているか(サーバーが自分で調べる)
local character = player.Character
if not character then return end
local humanoid = character:FindFirstChildOfClass("Humanoid")
local root = character:FindFirstChild("HumanoidRootPart")
local tool = character:FindFirstChild(TOOL_NAME)
if not humanoid or humanoid.Health <= 0 or not root then return end
if not tool or not tool:IsA("Tool") then return end
lastSwing[player] = now
-- 3. 体の前の箱に入っている部品を集める(自分の体と剣は外す)
local boxCFrame = root.CFrame * BOX_OFFSET
local params = OverlapParams.new()
params.FilterType = Enum.RaycastFilterType.Exclude
params.FilterDescendantsInstances = { character }
local parts = workspace:GetPartBoundsInBox(boxCFrame, BOX_SIZE, params)
if SHOW_BOX then
showBox(boxCFrame)
end
-- 4. 箱の中の相手に、1回の振りで1回だけダメージ
local alreadyHit = {}
for _, part in parts do
local model = part:FindFirstAncestorOfClass("Model")
local target = model and model:FindFirstChildOfClass("Humanoid")
if target and target.Health > 0 and not alreadyHit[target] then
alreadyHit[target] = true
if model:FindFirstChildOfClass("ForceField") then
print(model.Name, "は ForceField に守られているので減りません")
else
target:TakeDamage(DAMAGE)
print(player.Name, "の剣が", model.Name, "に当たりました。残り", target.Health)
end
end
end
end)
Players.PlayerRemoving:Connect(function(player)
lastSwing[player] = nil
end)
下の画像は、ServerScriptServiceの中のSwordService(赤い枠)にコードが入った画面です。

コードの中ほどでは、振った人が生きていて剣を手に持っているかを、サーバーが自分で確かめています(赤い枠)。

| コードの部分 | していること |
|---|---|
| lastSwing と COOLDOWN | 人ごとに最後に振った時刻を覚え、0.6秒たつまで次の振りを受けつけない |
| character:FindFirstChild(TOOL_NAME) | 剣を手に持っているか。手に持つと、剣はキャラクターの中に移る |
| GetPartBoundsInBox | BOX_OFFSETで決めた体の3スタッド前に、BOX_SIZEで決めた5×5×5の箱を置き、箱と少しでも重なっているパーツ(パーツを囲む四角で判定)を集める。自分の体は外す |
| alreadyHit | 箱の中に相手の体のパーツが何個あっても、1回の振りで1回だけ減らす |
| TakeDamage | DAMAGEで決めた20だけ体力を減らす |
| showBox | テスト中だけ、攻撃の範囲を0.2秒だけ赤く見せる |
当たり判定に「Touched(触れたとき)」を使わず、箱の中を調べる方法にしています。Touchedは物が動いて触れたときに起きるので、相手にくっついたまま振ると当たらないことがあります。
6. テストでダミーを斬る
3D画面の上の作品のタブ「Place10」を押して3D画面に戻り、F5キーでテストを始めます(タブの名前はパソコンによって違います)。数字キーの1で剣を持ち、ダミーの前でクリックします。体の前に赤い箱が一瞬出て、その中のダミーの体力が減ります(赤い枠)。

ダミーの頭の上の体力バーが減ります(画像の1)。1回当たるごとに、出力に「(アカウント名) の剣が Dummy に当たりました。残り 〜」の行が1行ずつ出ます。1回目は「残り 80」、もう1回斬ると「残り 60」です。下の画像は2回斬ったあとで、出力に「残り 80」と「残り 60」の2行が出ています(画像の2)。

続けて斬ると、80、60、40、20、0と減っていき、5回目でダミーの体力が0になり、頭が外れて倒れました(赤い枠)。

Shift + F5キーでテストを停止します。
7. 2人で斬り合う
Studioの画面左上、「ホーム」などのタブと同じ段のいちばん左にある「テスト」と書かれた欄の右の「∨」を押し、一覧から「サーバーとクライアント」を選びます(赤い枠)。

人数の上向き三角を押して「2」にし(赤い枠)、左の青い再生ボタンを押します。テストが始まり、Player1とPlayer2の窓が開きます。2人テストのくわしいやり方は文字を出す方法の2人テストで解説しています。

Player1の窓で数字キーの1を押して剣を持ちます。Player2の窓に切りかえ、W・A・S・DキーでPlayer1の前まで歩きます。Player1の窓に戻り、クリックして剣を振ります。
下の画像の左がPlayer1、右がPlayer2の画面です。Player1がPlayer2の前で剣を振ると、Player2の頭の上の緑の体力ゲージが減りました(赤い枠)。

体力が減っているかどうかは、この頭の上の緑の体力ゲージで確かめられます。数字で見たいときは、2人テストで一緒に開く「サーバー」の窓の出力を見ます。SwordServiceのprintの行(「〜の剣が〜に当たりました。残り〜」)は、サーバーの窓の出力に出ます。
プレイヤーの体力は、ダミーと違って少しずつ自然に戻ります(Robloxの公式の説明では、1秒に体力の上限の1%ずつ)。そのため2人テストでは20ずつきっちりは減りません。以下は、アソビシフト編集部が確かめた結果です。Player2の体力は80の次が61になりました。
強さや範囲を変える
数を変えるときは、エクスプローラのServerScriptServiceの中の「SwordService」をダブルクリックして開き、コードの上のほうの「local DAMAGE = 20」などの行の数を書き換えます。
| 変えたいこと | 変える数 | 例 |
|---|---|---|
| 強さ | DAMAGE | 20 → 34にすると、ダミーのように体力が戻らない相手(体力100)は3回で倒れる |
| 連打の速さ | COOLDOWN | 0.6 → 1にすると、1秒に1回まで |
| 届く距離 | BOX_OFFSETの-3とBOX_SIZEの3つめ | CFrame.new(0, 0, -4) と Vector3.new(5, 5, 7) にすると前へ長く届く |
| 赤い箱を消す | SHOW_BOX | 公開する前にfalseにする |
当たらない・体力が減らないときの確かめ方
| 症状 | 見るところ | 直し方 |
|---|---|---|
| 剣を手に持てない | Handleの名前とAnchored | Toolのすぐ下に「Handle」があり、固定が外れているか |
| 刃が持ち手からはずれる | WeldConstraint | Part0とPart1が入っているか |
| クリックしても何も起きない | RemoteEventの名前 | ReplicatedStorageの「SwingSword」と、2つのコードの名前が同じか |
| 赤い箱は出るのに減らない | 相手との距離 | 箱の中に相手が入っているか。届かなければBOX_OFFSETを変える |
| 出てすぐの相手が減らない | 相手のForceField(出てきたばかりの体を守るバリア) | エクスプローラでSpawnLocationを選び、プロパティの検索欄に「Duration」と入力して秒数を見る。0より大きいと、その秒数は守られて減らない |
| 1回でたくさん減る | alreadyHit | 1回の振りで同じ相手に1回だけにしているか |
AIに相談するときの伝え方
Roblox Studioで剣の攻撃を作っています。
StarterPackのTool「Sword」の中のLocalScriptでActivatedを受け取り、ReplicatedStorageのRemoteEvent「SwingSword」で引数なしでサーバーに伝えています。
ServerScriptServiceのScriptで、剣を手に持っているか確かめ、GetPartBoundsInBoxで体の前の相手を探して、TakeDamageで20減らしてください。
同じ相手には1回の振りで1回だけ、同じ人は0.6秒に1回までにしてください。
よくある質問
銃も同じように作れる?
銃は、狙った方向や弾の届く先を決める必要があり、剣より作ることが増えます。まずは剣のように「サーバーが当たったかを決める」形に慣れてから挑戦するのがおすすめです。
次は、クリックした場所へレーザーを撃って当てるブラスターを作ります。次のステップ(中級 13/28)
次に知りたいことを選ぶ
- 次のステップ:クリックした場所へレーザーを撃って当てるブラスターを作ります → ロブロックス(Roblox)スタジオで銃の作り方
- 手に持てるアイテムの基本を知りたい → ロブロックス(Roblox)スタジオで手に持てるアイテムを作る方法
- サーバーに知らせる仕組みを知りたい → ロブロックス(Roblox)のRemoteEventの使い方
- 斬る相手になる敵を作りたい → ロブロックス(Roblox)で追いかけてくる敵の作り方