ロブロックススタジオの参考URLとダンボール

# ロブロックススタジオの参考になるURL

https://howtoroblox-ja.com/archives/category/roblox-studio

# メタルギアのスネークみたいにダンボールに隠れて移動する
動作イメージ
	1.	プレイヤーが “B” キーを押すと ダンボールを装着
	2.	プレイヤーの 移動速度が遅くなる
	3.	敵の AI はダンボールをかぶったプレイヤーを見逃す
	4.	“B” キーを押すと ダンボールを外す

#### 使用する段ボール
![段ボール.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3957418/8fb12352-43e7-410d-89b5-d5e7d9913b20.png)

# 段ボールの配置する場所
`ReplicatedStorage/`の中に移動させます
段ボールのモデルの名前を`BoxModel`に変更しました

![段ボールの設置.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3957418/893fbebb-f878-4528-a2db-a48c7ca0a6a9.png)

# BoxModelにPrimaryPartを設定
今回は段ボールの底の部分の`Part3`に設定
![プライマリー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3957418/aa2c0766-ab48-4974-8339-e9bc6ea8c4bf.png)

# 段ボールのパーツの設定変更
段ボールのパーツの当たり判定とアンカーの固定を解除します
![パーツの設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3957418/41352bc4-c2ef-4fb2-b1b5-cb6531f007b1.png)

# スクリプトの配置場所
`StarterPlayer/StarterPlayerScripts/`に`LocalScript`を作成
![スクリプトの位置.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3957418/9bcce8e7-d9aa-4c5d-a52e-290ab4a3b182.png)

### 上手くいった段ボール被るScript
#### LocalScript
```
local boxTemplate = game.ReplicatedStorage:FindFirstChild("BoxModel")
if not boxTemplate then
	warn("ReplicatedStorage に BoxModel が存在しません！")
	return
else
	print("BoxModel が見つかりました:", boxTemplate)
end

local player = game.Players.LocalPlayer
local char = player.Character or player.CharacterAdded:Wait()
local humanoid = char:FindFirstChildOfClass("Humanoid")
local uis = game:GetService("UserInputService")

-- キャラクターの Head の存在確認
local head = char:FindFirstChild("Head")
if not head then
	warn("キャラクターに Head がありません！")
	return
end

-- ダンボール（Box）の装着・解除関数
local function toggleBox()
	local existingBox = char:FindFirstChild("Box")

	if existingBox then
		-- 既にダンボールが装着されている場合は外す
		existingBox:Destroy()
		humanoid.WalkSpeed = 16  -- 通常速度に戻す
		print("Box を解除しました。WalkSpeed を 16 に戻しました。")
	else
		-- ダンボールを作成してキャラクターに装着
		local box = boxTemplate:Clone()
		box.Parent = char
		box.Name = "Box"  -- キャラクター内の識別用に名前を変更

		-- **BasePart (Part or MeshPart) を検索して PrimaryPart に設定する**
		local primaryPart = nil
		for _, child in ipairs(box:GetDescendants()) do
			if child:IsA("BasePart") then
				primaryPart = child
				break
			end
		end

		if not primaryPart then
			warn("BoxModel に BasePart が見つかりません。")
			return
		end

		box.PrimaryPart = primaryPart  -- モデルの PrimaryPart を設定
		primaryPart.Anchored = false  -- 移動できるようにする
		print("PrimaryPart が設定されました: " .. primaryPart.Name)

		-- **ボックスの位置と回転を設定 (180度 + さらに180度回転)**
		local newCFrame = head.CFrame * CFrame.new(0, 1.5, 0) * CFrame.Angles(0, math.rad(180), 0)
		newCFrame = newCFrame * CFrame.Angles(0, math.rad(180), 0)  -- 追加で180度回転させる
		box:SetPrimaryPartCFrame(newCFrame)

		print("ダンボールの CFrame が設定されました。")

		-- **WeldConstraint を作成してキャラクターに追従させる**
		local weld = Instance.new("WeldConstraint")
		weld.Part0 = primaryPart  -- Model の PrimaryPart を設定する
		weld.Part1 = head  -- プレイヤーの Head に追従
		weld.Parent = primaryPart  -- WeldConstraint は PrimaryPart に設定する

		-- 移動速度を低下（ステルス効果）
		humanoid.WalkSpeed = 8
		print("Box を装着しました。WalkSpeed を 8 に低下しました。")
	end
end

-- "B" キー入力で toggleBox 関数を実行
uis.InputBegan:Connect(function(input, gameProcessed)
	if gameProcessed then return end
	if input.KeyCode == Enum.KeyCode.B then
		print("B キーが押されました。")
		toggleBox()
	end
end)
```

### さらに改良したもの
レインボーフレンズのblueに視認させないようにしたもの
https://qiita.com/studyhiminato1107/items/5de4a209d765d050c37f

# 失敗例
こちらは段ボールの底が下にきて頭に乗せてる感じになりました
何か別のことに使えるかも
#### LocalScript
```
local boxTemplate = game.ReplicatedStorage:FindFirstChild("BoxModel")
if not boxTemplate then
	warn("ReplicatedStorage に BoxModel が存在しません！")
	return
else
	print("BoxModel が見つかりました:", boxTemplate)
end

local player = game.Players.LocalPlayer
local char = player.Character or player.CharacterAdded:Wait()
local humanoid = char:FindFirstChildOfClass("Humanoid")
local uis = game:GetService("UserInputService")

-- キャラクターの Head の存在確認
local head = char:FindFirstChild("Head")
if not head then
	warn("キャラクターに Head がありません！")
	return
end

-- ダンボール（Box）の装着・解除関数
local function toggleBox()
	local existingBox = char:FindFirstChild("Box")

	if existingBox then
		-- 既にダンボールが装着されている場合は外す
		existingBox:Destroy()
		humanoid.WalkSpeed = 16  -- 通常速度に戻す
		print("Box を解除しました。WalkSpeed を 16 に戻しました。")
	else
		-- ダンボールを作成してキャラクターに装着
		local box = boxTemplate:Clone()
		box.Parent = char
		box.Name = "Box"  -- キャラクター内の識別用に名前を変更

		-- **Part3 を PrimaryPart に設定する（底のパーツ）**
		local primaryPart = box:FindFirstChild("Part3")
		if not primaryPart then
			warn("BoxModel 内に Part3 が見つかりません。")
			return
		end

		box.PrimaryPart = primaryPart
		primaryPart.Anchored = false  -- 移動できるようにする
		print("PrimaryPart が設定されました: " .. primaryPart.Name)

		-- **高さ調整用のオフセット値（上に移動する）**
		local heightOffset = 0.05  -- この値を調整して高さを変える

		-- **ボックスの位置と回転を設定 (180度回転)**
		local newCFrame = head.CFrame * CFrame.new(0, 1.5 + heightOffset, 0) * CFrame.Angles(math.rad(180), 0, 0)
		box:SetPrimaryPartCFrame(newCFrame)

		print("ダンボールの CFrame が設定されました。")

		-- **WeldConstraint を作成してキャラクターに追従させる**
		local weld = Instance.new("WeldConstraint")
		weld.Part0 = primaryPart  -- Model の PrimaryPart を設定する
		weld.Part1 = head  -- プレイヤーの Head に追従
		weld.Parent = primaryPart  -- WeldConstraint は PrimaryPart に設定する

		-- 移動速度を低下（ステルス効果）
		humanoid.WalkSpeed = 8
		print("Box を装着しました。WalkSpeed を 8 に低下しました。")
	end
end

-- "B" キー入力で toggleBox 関数を実行
uis.InputBegan:Connect(function(input, gameProcessed)
	if gameProcessed then return end
	if input.KeyCode == Enum.KeyCode.B then
		print("B キーが押されました。")
		toggleBox()
	end
end)
```