パーツをドラッグして移動したい場合、以前はローカルで GetMouse を使ったりと少々不便でした。さらにサーバーで動作させるとなるとさらに面倒なプログラムが必要になりました。新たに DragDetector というイベントが追加されたことにより、誰でも簡単にドラッグ処理を組み込むことが可能になりました。
DragDetector の基本
- パーツを1つ追加し、Anchored をONにします。
- その中に DragDetector を追加します。
- これだけでもドラッグできるようになりますが、イベントのテストをしたいので、その中にさらに Script を入れ、以下のプログラムを入力します。
local dragDetector = script.Parent
dragDetector.DragStart:Connect(function(player,cursorRay,viewFrame,hitFrame,clickedPart,vrInputFrame,isModeSwitchKeyDown)
print("DragStart")
end)
dragDetector.DragEnd:Connect(function(player)
print("DragEnd")
end)
dragDetector.DragContinue:Connect(function(player,cursorRay,viewFrame,vrInputFrame,isModeSwitchKeyDown)
print("DragContinue")
end)
どのようなタイミングで各イベントが呼ばれるのかを確認できます。さらに各パラメーターを簡単に解説をしておきます。詳しくは下記URLをご覧ください。
https://create.roblox.com/docs/ja-jp/reference/engine/classes/DragDetector
パラメータ | 型 | 解説 |
---|---|---|
player | Player | ドラッグを開始したプレイヤー |
cursorRay | Ray | カーソルからシーンに向けて発せられるRay |
viewFrame | CFrame | ユーザーカメラのCFrame |
hitFrame | CFrame | ドラッグを開始したカーソル位置のレイキャストのCFrame |
clickedPart | BasePart | ドラッグしたパーツ |
vrInputFrame | CFrame | VRデバイス使用時のコントローラのCFrame |
isModeSwitchKeyDown | boolean | DragDetectorの DragStyleの設定により変わりますが、デフォルトでは、Ctrlキーを押しながらドラッグするとTrueになります。 |
スナップを効かせる方法
チェスゲームなどのようにマス目単位にしかドラッグできないようにする方法です。
- パーツを1つ追加し、Anchored をONにします。
- その中に DragDetector と Script を追加します。
- Script には以下のプログラムを入力します。
local part = script.Parent
local dragDetector = part.DragDetector
local startPartPosition = nil
local SNAP_INCREMENT = 4
dragDetector.DragStart:Connect(function()
startPartPosition = part.Position
end)
dragDetector.DragEnd:Connect(function()
startPartPosition = nil
end)
local function snapToWorldGrid(proposedMotion)
if startPartPosition == nil then
return proposedMotion
end
local snapIncrement = math.floor(SNAP_INCREMENT)
if (snapIncrement < 1) then
return proposedMotion
end
local newWorldPosition = startPartPosition + proposedMotion.Position
local roundedX = math.floor(newWorldPosition.X / snapIncrement + 0.5) * snapIncrement
local roundedY = math.floor(newWorldPosition.Y / snapIncrement + 0.5) * snapIncrement
local roundedZ = math.floor(newWorldPosition.Z / snapIncrement + 0.5) * snapIncrement
local newRoundedWorldPosition = Vector3.new(roundedX, roundedY, roundedZ)
return proposedMotion.Rotation + (newRoundedWorldPosition - startPartPosition)
end
local connection = dragDetector:AddConstraintFunction(2, snapToWorldGrid)
-- 必要な場合はタイミングに応じて、connection:Disconnect()を呼び出しイベントを解除します
DragDetector を使うと、プログラムなしで以下の動画のようなことが実現できるようです。詳しくは下記URLをご覧ください。
https://create.roblox.com/docs/ja-jp/ui/drag-detectors