I am creating a block sort of game, and it is locked in first person. I am trying to make it compatible on mobile.
The game detects the targeted block by detecting what part is hitting the mouse, which is in the middle of the screen. However, on mobile the mouse location seems to be indicated by where the person is placing their finger, making it difficult to target parts easily on mobile.
So how would I detect what part is currently in the middle of the persons screen, instead of what the mouse is hitting?
This is the game where it currently uses the mouse in the center of the screen to detect parts: Voxel game - Roblox
-- distance in studs to use (higher numbers will give bad performance)
local length = 500
local camera = workspace.CurrentCamera
local viewportPoint = camera.ViewportSize / 2
local unitRay = camera:ViewportPointToRay(viewportPoint.X, viewportPoint.Y, 0)
local ray = Ray.new(unitRay.Origin, unitRay.Direction * length)
local part = workspace:FindPartOnRay(ray)
Haven’t tested it, but it probably works since it’s lifted from the example under this entry on the wiki.
I am probably doing this wrong, but I haven’t gotten it to work yet.
This is one of my scripts utilizing the mouse.Hit to get the part in the center of the screen:
local mouse = game:GetService("Players").LocalPlayer:GetMouse()
local REACH = 20
game:GetService("Players").LocalPlayer.CharacterAdded:wait()
while wait() do
if mouse.Target then
local part = mouse.Target
local distance = (game:GetService("Players").LocalPlayer.Character.HumanoidRootPart.Position - part.Position).Magnitude
if distance <= REACH then
local sel = game:GetService("ReplicatedStorage").SelectionBox:Clone()
sel.Parent = part
sel.Adornee = part
repeat wait() until mouse.Target ~= part
sel:Destroy()
end
end
end
This is how I modified it to try and get it to work:
local uis = game:GetService("UserInputService")
uis.MouseIconEnabled = false
local camera = workspace.CurrentCamera
local REACH = 20
game:GetService("Players").LocalPlayer.CharacterAdded:wait()
while wait() do
local unitRay = camera:ScreenPointToRay(100, 100)
local ray = Ray.new(unitRay.Origin, unitRay.Direction * REACH)
print(workspace:FindPartOnRayWithIgnoreList(ray,game:GetService("Players").LocalPlayer.Character:GetChildren()))
if workspace:FindPartOnRayWithIgnoreList(ray,game:GetService("Players").LocalPlayer.Character:GetChildren()) then
local part = workspace:FindPartOnRayWithIgnoreList(ray,game:GetService("Players").LocalPlayer.Character:GetChildren())
local distance = (game:GetService("Players").LocalPlayer.Character.HumanoidRootPart.Position - part.Position).Magnitude
if distance <= REACH then
local sel = game:GetService("ReplicatedStorage").SelectionBox:Clone()
sel.Parent = part
sel.Adornee = part
repeat wait() until workspace:FindPartOnRayWithIgnoreList(ray,game:GetService("Players").LocalPlayer.Character:GetChildren()) ~= part
sel:Destroy()
end
end
end
I used FindPartOnRayWithIgnoreList because it was originally hitting the character parts. Now it doesn’t seem to work at all.
There are no errors either.
local camera = workspace.CurrentCamera
while wait() do
local unitRay = camera:ScreenPointToRay(game:GetService("Players").LocalPlayer.PlayerGui.Main.crosshair.AbsolutePosition.X,game:GetService("Players").LocalPlayer.PlayerGui.Main.crosshair.AbsolutePosition.Y)
local ray = Ray.new(unitRay.Origin, unitRay.Direction * 20)
local hit = workspace:FindPartOnRayWithIgnoreList(ray,game:GetService("Players").LocalPlayer.Character:GetChildren())
if hit then
script.Pos.Value = hit.Position
end
end
The script above constantly updates a Vector3 value to the current hit position, then I use another script to compare to that value, detecting if they are different and updating the visuals when needed.
You could just use workspace.CurrentCamera.CFrame to get the middle position of the camera and the direction it’s facing, fire a ray from that point to say, Camera.CFrame * Camera.CFrame.lookVector * 4 (not actual code) and then find part on the ray.