RobloxStudioでブロックを地面に設置するのを作成してみます。マインクラフト風にブロックを地面に設置してみます。
はじめに
下記記事では初めてRobloxゲームを作成する人向けのチュートリアル的なRobloxStudioでゲーム作成を書いています。今回はマインクラフト風にブロックを地面に設置する基本的な機能を作成してみます。
作成の流れとしては、ローカルスクリプトでブロックの生成位置を決める(クライアント側のみ)→スクリプトで設置(サーバー)という流れです。
製作開始
まずは設置するブロックを用意します。「Part」を追加して名前を「Block」に変更、サイズも変更します。色やマテリアルも自由に変更して良いです。

Collisionのチェックを外して、Anchoredにチェックを入れます。(後のスクリプトで制御することもできます)

作成したブロックを「ReplicatedStorage」に移動します。

ローカルスクリプトの作成
「StarterPlayer」→「StarterPlayerScripts」の配下に「LocalScript」を追加します。

LocalScriptの中身を下記に変更します。まずはローカル上にブロックが生成されるか確認です。
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Block = ReplicatedStorage:WaitForChild("Block")
newBlock = nil
local function BlockSpawn()
newBlock = Block:Clone()
newBlock.Parent = workspace
end
BlockSpawn()
実行して、下記の様にブロックが出現したらOKです。

次にマウス位置に追従するようにブロックを動くようにしてみます。スクリプトを下記に変更します。
local RunService = game:GetService("RunService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Block = ReplicatedStorage:WaitForChild("Block")
local UserInputService = game:GetService("UserInputService")
local camera = workspace.CurrentCamera
local newBlock = nil
local function BlockSpawn()
newBlock = Block:Clone()
newBlock.Parent = workspace
end
local function updateBlockPos()
if newBlock then
local mouseLocation = UserInputService:getMouseLocation()
local mouseRay = camera:ViewportPointToRay(mouseLocation.X, mouseLocation.Y)
local raycastResult = workspace:Raycast(mouseRay.Origin, mouseRay.Direction * 1000)
if raycastResult then
newBlock.Position = raycastResult.Position
end
end
end
BlockSpawn()
RunService:BindToRenderStep("MovingBlock",Enum.RenderPriority.Camera.Value+1,updateBlockPos)
「RunService:BindToRenderStep」毎フレーム関数を実行。関数内ではマウスの位置を取得してレイを飛ばしてぶつかった位置をブロック位置にしています。
「RunService:BindToRenderStep」は下記記事のカメラ制御でも利用しています。
「Raycast」は下記記事で詳しく書いています。
実行してみると下記の様な感じにマウス位置にブロックが移動しますが、真ん中が基準なのでブロックが半分沈んだ感じになります。

ブロックの位置を下記の様に変更して位置を調整します。
newBlock.Position = CFrame.new(raycastResult.Position):PointToWorldSpace(Block.Size/2)
スクリプトの作成
次に実際にスクリプトでブロックを設置していきます。「ReplicatedStorage」に「RemoteEvent」を追加します。

「ServerScriptService」に「Script」を追加します。

「LocalScript」を下記に変更します。マウスをクリックしたときにリモートイベントを通してサーバー側に通知します。
local RunService = game:GetService("RunService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Block = ReplicatedStorage:WaitForChild("Block")
local UserInputService = game:GetService("UserInputService")
local RemoteEvent = ReplicatedStorage:WaitForChild("RemoteEvent")
local camera = workspace.CurrentCamera
local newBlock = nil
local function BlockSpawn()
newBlock = Block:Clone()
newBlock.Parent = workspace
end
local function updateBlockPos()
if newBlock then
local mouseLocation = UserInputService:getMouseLocation()
local mouseRay = camera:ViewportPointToRay(mouseLocation.X, mouseLocation.Y)
local raycastResult = workspace:Raycast(mouseRay.Origin, mouseRay.Direction * 1000)
if raycastResult then
newBlock.Position = CFrame.new(raycastResult.Position):PointToWorldSpace(Block.Size/2)
end
end
end
BlockSpawn()
RunService:BindToRenderStep("MovingBlock",Enum.RenderPriority.Camera.Value+1,updateBlockPos)
UserInputService.InputBegan:Connect(function(input, gameProcessedEvent)
if gameProcessedEvent then return end
if input.UserInputType == Enum.UserInputType.MouseButton1 then
RemoteEvent:FireServer(newBlock.Position)
end
end)
「Script」の中身を下記に変更します。イベントを受信したらブロックを設置しています。
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RemoteEvent = ReplicatedStorage:WaitForChild("RemoteEvent")
local Block = ReplicatedStorage:WaitForChild("Block")
local function BlockPlace(player,BlockPos)
local block = Block:Clone()
block.Position = BlockPos
block.CanCollide = true
block.CanQuery = true
block.Parent = workspace
end
RemoteEvent.OnServerEvent:Connect(BlockPlace)
下記の様にマウスを動かしたらブロックが移動、クリックで確定すればOK



