Get part in center of screen

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

1 Like
-- 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.

8 Likes

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.

1 Like

Okay, I finally managed to make it work somehow!

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.

1 Like

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.

1 Like