Robloxで1メッシュ鍵盤のクリック位置取得
ピアノ鍵盤を1つのMeshPart(1メッシュ)で作った場合でも、画面上のクリックからワールド座標をレイキャストで取得し、メッシュ上の衝突点を位置として使えます。クリック位置からメッシュのローカル座標に変換すれば、どの鍵を押したかの判定まで可能です Zenn。
できることと基本方針
- クリック位置の取得: カメラからクリック方向にレイを飛ばし、MeshPartに当たった地点の
RaycastResult.Positionを得る Zenn。 - 鍵判定: 当たった位置をメッシュ(モデル)のローカル座標に変換して、X方向の範囲から鍵番号を割り出す。
- 注意点: ClickDetectorは「クリックされた」というイベントは取れるが、正確なヒット位置は返さないため鍵番号判定には不向き。位置が必要ならレイキャストを使う Zenn。
実装ステップ
-
レイキャストでクリックヒット情報を取得
- ポイント:
UserInputService:GetMouseLocation()→Camera:ViewportPointToRay()→workspace:Raycast()の流れ。 - フィルタ: 自分のキャラクターは除外。距離は適宜(例: 1000) Zenn。
- サンプル(LocalScript, StarterPlayerScripts)
local UIS = game:GetService("UserInputService") local camera = workspace.CurrentCamera local player = game.Players.LocalPlayer local function raycastFromMouse() local pos = UIS:GetMouseLocation() local ray = camera:ViewportPointToRay(pos.X, pos.Y) local params = RaycastParams.new() params.FilterType = Enum.RaycastFilterType.Exclude params.FilterDescendantsInstances = { player.Character } return workspace:Raycast(ray.Origin, ray.Direction * 1000, params) end UIS.InputBegan:Connect(function(input, gp) if gp or input.UserInputType ~= Enum.UserInputType.MouseButton1 then return end local result = raycastFromMouse() if not result then return end local hitPart = result.Instance local hitWorld = result.Position -- ここから鍵判定へ end)Sources: Zenn
- ポイント:
-
ワールド座標をローカル座標へ変換
- ポイント: 1メッシュならそのMeshPartの
CFrame:ToObjectSpace()を使う。モデルならPrimaryPart基準で。 - サンプル
local mesh = hitPart -- 1メッシュの場合 local localCF = mesh.CFrame:ToObjectSpace(CFrame.new(hitWorld)) local localPos = localCF.Position -- メッシュ原点基準のXYZ
- ポイント: 1メッシュならそのMeshPartの
-
ローカルX位置から鍵番号を算出
- 前提: 鍵がX方向に並んでいるとする。白鍵幅
whiteWidth、白鍵数numWhiteKeysなどを決める。 - サンプル(単純化)
local originX = - (numWhiteKeys * whiteWidth) / 2 -- 左端X local x = localPos.X local keyIndex = math.floor((x - originX) / whiteWidth) + 1 if keyIndex >= 1 and keyIndex <= numWhiteKeys then print("White key pressed:", keyIndex) end -- 黒鍵はX範囲+Z(奥行き)で別判定を重ねる
- 前提: 鍵がX方向に並んでいるとする。白鍵幅
精度を上げるための設計ヒント
- 衝突精度: MeshPartのCollisionFidelityを「Precise」に、
CanQueryを有効にしておくと当たり判定が正確になりやすい。 - ヒット領域の補助: 完全1メッシュでの黒鍵・白鍵判定は境界がシビア。透明な薄いPartを各鍵位置に配置してレイキャスト対象を鍵ごとに分けると堅牢。ClickDetectorを各Partに付ければクリック検出は簡単だが、位置情報は不要な場合のみ有効 Zenn Qiita。
- UIとの併用: ラベル表示やハイライトはBillboardGuiやSurfaceGuiで視覚フィードバックを追加すると分かりやすい。
ClickDetectorを使う場合の補足
- 用途: 「押された」事実だけ取れれば十分なケースでは簡便。
MouseClick,MouseHoverEnter/Leave,RightMouseClickなどのイベントを提供 Zenn。 - 限界: ヒット座標は返らないため、1メッシュで鍵番号を厳密に決める用途には不向き。鍵ごとにPartを分ける設計なら適合 Zenn Qiita。