👆

【Roblox】オブジェクトへの入力を検知する ~Detectorインスタンス~

2025/03/10に公開

はじめに

今回はRobloxで画面上に表示されているオブジェクトに対してのクリックやドラッグなどの入力を検知することができるClickDetectorDragDetectorについて紹介します。

Robloxバージョン 0.658.0.6580461

ClickDetectorとは

ClickDetectorとはBasePart、ModelまたはFolderの子に配置することでそのオブジェクトをクリックしたことを検出できるようにするものです。下記で重要なプロパティとイベントだけ抜粋して紹介します。

プロパティ

MaxActivationDistance

データ型:number 解説:ClickDetectorを検出できる距離
例:5に設定されている場合、5スタッドより離れているキャラクターはClickDetectorを検出できず、ドラッグできません。

イベント

MouseClick

プレイヤーがオブジェクトをクリックまたはタッチしたときに発生するイベント。

MouseHoverEnter

プレイヤーがオブジェクトにマウスカーソルを置いたときに発生するイベント。

MouseHoverLeave

プレイヤーがオブジェクトからマウスカーソルを離したときに発生するイベント。

RightMouseClick

プレイヤーがオブジェクトを右クリックしたときに発生するイベント。

使用例

まずClickDetectorをPartインスタンスの子に配置します。

つぎにスクリプトを書いていきます。

local part = workspace:WaitForChild("Part")
local clickDetector = part:WaitForChild("ClickDetector")

local highlight

--オブジェクトがクリックされたときにログを表示
clickDetector.MouseClick:Connect(function(clickedPlayer: Player)
    print(part.Name.." is Clicked by "..clickedPlayer.Name)
end)

--オブジェクトにカーソルを合わせたときに強調表示
clickDetector.MouseHoverEnter:Connect(function(hoveredPlayer: Player)
    if not highlight then
        highlight = Instance.new("HighLight", part)
        highlight.FillTransparency = 1
        highlight.OutlineTransparency = 0
        highlight.OutlineColor = Color3.fromRGB(255, 128, 0)
    end
end)

--オブジェクトからカーソルが離れたときに強調表示解除
clickDetector.MouseHoverLeave:Connect(function(hoveredPlayer: Player)
    if highlight then
        highlight:Destroy()
        highlight = nil
    end
end)

以上がClickDetectorの紹介になります。
つぎにDragDetectorについて紹介します。

DragDetectorとは

DragDetectorとはBasePartを継承したオブジェクトの子オブジェクトに配置することでそのオブジェクトをドラッグできるようにするものです。DragDetectorはClickDetectorを継承しているので上記で紹介したプロパティとイベントを使用することができます。下記でDragDetectorで追加された重要なプロパティとイベントだけ抜粋して紹介します。

プロパティ

DragStyle

データ型:Enum.DragDetectorDragStyle

DragDetectorDragStyle 解説
TranslateLine Axisプロパティで設定された軸に沿った直線的なオブジェクトを移動させます。 Axisが(0,1,0)の場合、Y軸方向に動かすことができます。
TranslatePlane Axisプロパティで設定された軸に対して垂直な平面に沿ってオブジェクトを移動させます。 Axisが(0,1,0)の場合、X軸とZ軸方向に動かすことができます。
TranslatePlaneOrLine 修飾キーを押していないときはTranslatePlaneと同じ挙動を、押しているときはTranslateLineと同じ挙動をします。 -
TranslateLineOrPlane 修飾キーを押していないときはTranslateLineと同じ挙動を、押しているときはTranslatePlaneと同じ挙動をします。 -
TranslateViewPlane カメラの向いている方向に対して垂直な平面に沿って挙動をします。 カメラが向いている方向に合わせて動的に移動方向が変化します。これはドラッグ中にも適用されます。
RotateAxis Axisプロパティで設定された軸を基準にオブジェクトを回転させます。 Axisが(0,1,0)の場合、Y軸を基準に回転させることができます。
RotateTrackball TrackballRadialPullFactor、TrackballRollFactorの値に応じて、トラックボールのように回転する。 -
Scriptable SetDragStyleFunctionで設定された関数に応じた動きをします。 -
BestForDevice マウスとゲームパッドの場合はTranslatePlaneOrLine 、タッチの場合はTranslatePlane、VRの場合は6DOFの挙動をします。 -

※修飾キーとはPCではLeftControl、ゲームパッドではButtonR1、VRではButtonL2を指します。

PermissionPolicy

データ型:Enum.DragDetectorPermissionPolicy

DragDetectorPermissionPolycy 解説
Nobody プレイヤーはDragDetectorを使用できません。
Everybody 全てのプレイヤーがDragDetectorを使用できます。
Scriptable SetPermissionPolicyFunctionを介して登録された関数を呼び出して関数がtrueを返した場合、プレイヤーはDragDetectorを使用できます。

ResponseStyle

データ型:Enum.DragDetectorResponseStyle

DragDetectorResponseStyle 解説
Geometric ドラッグに対してオブジェクトを正確に移動させます。Anchorが設定されていない場合、ドラッグ中オブジェクトはAnchorが設定されます。
Physical 動作によって指定された目的の位置や方向に移動しようと物理挙動を行います。Anchorが設定されている場合はGeometricと同一の動作になります。
Custom オブジェクトはまったく移動しませんが、 DragFrameは更新されるのでドラッグ操作に対して自由に挙動を実装できます。

RunLocally

データ型:boolean 解説:DragDetectorの挙動をローカルで行うかを設定します。
例:falseに設定されているときにDragDetectorを通してオブジェクトを移動させた場合、オブジェクトの移動はサーバー側にも同期されます。trueに設定されているときは同期されません。

イベント

DragStart

プレイヤーがオブジェクトのドラッグを開始したときに発生するイベント。

DragEnd

プレイヤーがオブジェクトのドラッグを終了したときに発生するイベント。

DragContinue

プレイヤーがオブジェクトのドラッグを継続したときに発生するイベント。

処理の実行順

今回はマウスでDragDetectorに対してドラッグ操作を行った場合を例として説明します。
①オブジェクトにカーソルを合わせる[MouseHoverEnter]
②左クリック押し込み[DragStart]⇒
③カーソルを移動[DragContinue(動かしている間毎フレーム呼ばれる)]⇒
④左クリック押し込み終了[MouseClick⇒DragEnd]⇒
⑤オブジェクトからカーソルを離す[MouseHoverLeave]

上記の順で処理が実行されます。

使用例

まずDragDetectorをPartインスタンスの子に配置します。

つぎにスクリプトを書いていきます。

local part = workspace:WaitForChild("Part")
local dragDetector = part:WaitForChild("DragDetector")

local cloneObj
local isDrag = false
local startTime = 0

--ドラッグ開始地点に像を生成
dragDetector.DragStart:Connect(function()
    cloneObj = part:Clone()
    cloneObj.Parent = workspace
    cloneObj.Transparency = 0.6

    startTime = DateTime.now().UnixTimestamp
end)

--ドラッグしたかどうかを判定
dragDetector.DragContinue:Connect(function()
    if not isDrag then
        isDrag = true
    end
end)

--ドラッグ終了時に像を削除し、ドラッグ判定をリセット
dragDetector.DragEnd:Connect(function()
    if cloneObj then
        cloneObj:Destroy()
        cloneObj = nil
    end
end)

--ドラッグしてなかった場合のみ処理を実行
dragDetector.MouseClick:Connect(function(clickedPlayer)
    if isDrag then
        return
    end
    print(part.Name.." is Clicked by "..clickedPlayer.Name)

    --タップしたとき
    if DateTime.now().UnixTimestamp - startTime < 0.1 then
        print(part.Name.." is Tapped by "..clickedPlayer.Name)
    end
end)

MouseClickイベントはドラッグしていても呼ばれるのでクリックだけをしたときに処理を実行したい場合は工夫が必要になります。上記は一例なのでゲームの仕様に合わせて調整してください。

まとめ

  • クリックのみを検知したい場合はClickDetectorを使用する。
  • ドラッグを検知したい場合はDragDetectorを使用する。
  • DragDetectorはDragStyleとAxisを適切に設定する。
  • DragDetectorはイベントの処理順に注意する。

今回はClickDetectorとDragDetectorについて紹介しました。
こういった機能を自作しようとすると「画面のクリック位置を取得⇒スクリーン座標からワールド座標に変換⇒カメラの向きを取得⇒取得したデータをもとにRayを作成して指定のオブジェクトに当たっているかの判定を取る」といった処理が必要になってきます。
これらの処理をすべて省略でき、実装がかなり便利になると思うので是非Detectorインスタンスを活用してみてください!
最後までお読みいただき、ありがとうございました!

参考

https://create.roblox.com/docs/reference/engine/classes/ClickDetector
https://create.roblox.com/docs/reference/engine/classes/DragDetector

ランド・ホー Roblox開発チーム

Discussion