Getting the Center of the screen with Vector2?

Hey,

I’ve tried looking for the answer in forums but didn’t get anything. I’m trying to make a weapon shoot only at the center of the screen and It shoots based off of the mouse position on the screen, It works well on PC’s, however when it comes to mobile there is no mouse position to detect so I’ve decided to make the weapon shoot from the center of the screen when a button on the screen is pressed.
All I need is a proper Vector2 Value which would act as the center of the screen?

Would really appreciate any help. Thank you in advance

7 Likes

I believe you could just divide the ViewportSize of the camera by 2 on both axis’ to get your center, in pixels.

example:

local vector = Vector2.new(viewport.X / 2, viewport.Y / 2)
5 Likes

In more simple terms:
Allows this code to be used stand-alone

local vector = Vector2.new(workspace.CurrentCamera.ViewportSize.X / 2, workspace.CurrentCamera.ViewportSize.Y / 2)
3 Likes

You can get the position of the camera with workspace.CurrentCamera.CFrame.

Also, mobile users do have a Mouse object you just can’t see the mouse icon.

Thanks for the answer! It does kind of solve my issue however the shooting position doesn’t match the cursor, I’m probably doing something wrong, should I play around with the numbers?

The topbar at the top of the screen will take up about 36 pixels, so if you want to get an accurate position, you will want to subtract pixels from the Y like so:

local vector = Vector2.new(workspace.CurrentCamera.ViewportSize.X / 2, workspace.CurrentCamera.ViewportSize.Y / 2 - 36)
2 Likes

To get an accurate size of the Topbar it’d be best to use GetGuiInset.

2 Likes
local Vector = Vector2.new(workspace.CurrentCamera.ViewportSize.X / 2, workspace.CurrentCamera.ViewportSize.Y / 2 - game:GetService("GuiService"):GetGuiInset().Y)

I tried this but it’s still off, this time, though, it’s a bit too high compared to the cursor? I’m pretty sure the cursor is centered correctly at this position {0.5, 0},{0.5, 0}

Untitled

Nevermind!
Got it to shoot exactly in the center by just dividing 36(GuiInset.Y) by 2.
Really appreciate the help, thank you!

Here’s the complete code for those who are interested:

local Vector = Vector2.new(workspace.CurrentCamera.ViewportSize.X / 2, workspace.CurrentCamera.ViewportSize.Y / 2  - (game:GetService("GuiService"):GetGuiInset().Y/2))

12 Likes

FYI: On screen GUIs you can also set the IgnoreGuiInset property to true so you don’t need to account for the inset amount on any axis.

https://developer.roblox.com/api-reference/property/ScreenGui/IgnoreGuiInset

5 Likes

Sorry for bringing this back up, but right now I’m having the same problem that you had even after I applied your solution.
The Crosshair UI has it’s Anchor Point 0.5,0.5 and Position on 0.5,0,0.5,0 which means absolute center of the screen. I also turned off it’s IgnorGuiInset. When I applied your solution to deduct the GuiInset.Y, it still happens.
https://gyazo.com/b562178858e114462227cbb805981466

			local function ViewportPointToWorldCoordinates(x, y)

				local ray = cam:ViewportPointToRay(x, y)
				local partHit, endPosition = workspace:FindPartOnRay(Ray.new(ray.Origin, ray.Direction*500))
				
				return endPosition

			end

				local Vector = Vector2.new(workspace.CurrentCamera.ViewportSize.X / 2, workspace.CurrentCamera.ViewportSize.Y / 2  - (game:GetService("GuiService"):GetGuiInset().Y/2))
				rayEndPoint = ViewportPointToWorldCoordinates(Vector.X, Vector.Y)
1 Like

Weird, try dividing UIInset by 4, see if that gives you any results. If that won’t work I suggest you clear the anchor point values and make it based on the position.

Now, I also want to make this clear that this method works only if you have the Ignore UI Inset on false. Otherwise you can remove the subtraction part of the code.

I figured out that you need to add it instead of subtract it, no idea why, but with this approach, I can finally use this instead of Mouse.Hit.Position.

I also want to make an advice here, to those who are scripting guns, DO NOT use mouse hit P as your RayCasting end point. Instead, you should use this method along with Mouse.X and Mouse.Y (With subtracted/Added(?) GuiInset), and use RayCasting to get the ultimate Vector3 Position. This ray should include the invisible parts or parts that you’d like to ignore. I recommend using CollectionService along with workspace:FindPartOnRayWithIgnoreList to find it. I do that in my own RayCasting Module.

Here’s the final code:

local MouseHitP = ViewportPointToWorldCoordinates(mouse.X, mouse.Y + (game:GetService("GuiService"):GetGuiInset().Y) )

function RayCastModule.CastRayMouse(cam, x,y)
	local Viewport = cam:ViewportPointToRay(x, y)
	local ray = Ray.new(Viewport.Origin, Viewport.Direction * 1000)
	
	local partHit, endPosition = workspace:FindPartOnRayWithIgnoreList(ray, ignored)
	return endPosition	
end

This is what happen if you use MouseHitP
https://gyazo.com/174b23526074b33c9062fcaa2e46f7aa

4 Likes

You can use ScreenPointToRay and it will ignore the top bar. The AbsoluteSize of Guis that dont ignore the inset is also useful. The inset for me is a constant like 26 pixels. I think mouse coordinates on screen are not viewport based.

Hi Sir, can i pls see ur whole code on this one. i tried to apply it on mine i cant make it work. pls.

1 Like

Hey, Ragnar

I’ll guide you through. Could you send the snippet of your code?

1 Like

this is currently my working code.this is only based on mouse position on the screen. i would like to make it like yours, but idk how to apply it. ty for replying

local fireball = game.ServerStorage:WaitForChild(“Fireball”)

game.ReplicatedStorage.Fireball.OnServerEvent:Connect(function(player, mouseaim)
local character = player.Character
local newFireball = fireball:Clone()
newFireball.CFrame = character.HumanoidRootPart.CFrame:ToWorldSpace(CFrame.new(0, 0, -2))

local bodyVelocity = Instance.new("BodyVelocity")
bodyVelocity.MaxForce = Vector3.new(5000, 5000, 5000)
bodyVelocity.Velocity = CFrame.new(character.HumanoidRootPart.Position, mouseaim).lookVector*80
bodyVelocity.Parent = newFireball

newFireball.Parent = workspace

local touchConn
touchConn = newFireball.Touched:Connect(function(hit)
	if hit.Parent:FindFirstChild("Humanoid") then
		if hit.Parent.Name ~= player.Name then
			hit.Parent:BreakJoints()
			if touchConn ~= nil then touchConn:Disconnect() end
			newFireball:Destroy()
		end
	end
end)

wait(0.8)

if touchConn ~= nil then touchConn:Disconnect() end
newFireball:Destroy()

end)

1 Like

What do you mean by making it look like mine? Do you want to have that side camera effect or are you having issues trying to point to the centre of the screen?

yes, im having issues trying to point to the center of the screen

1 Like

Here’s my problem with your question. Is your system also constrained to the centre of the screen (like so:
image

or can you freely move your mouse around (like that: https://i.gyazo.com/174b23526074b33c9062fcaa2e46f7aa.mp4) ?

If you can freely move your mouse (without it being locked to the centre) then I also suppose that your mouseaim is the mouse coordinates on the screen. You don’t really want to use Mouse object to do that kind of stuff, as it does not offer as much functionality as UIS(User input service) or Context actions service (Mouse).

This sort of leaves you wondering… “What’s the alternative method of finding the mouse coordinates?”. Well, fortunately, UserInputService has a parameter that returns the Input information. With that in mind we can easily find the position of the mouse input. Like so:

---// Print input position of the mousebutton1 whenever a player has clicked his left mouse button (MouseButton1)
local UserInputService = game:GetService("UserInputService")

UserInputService.InputBegan:Connect(function(Input, gameProcessed) --//In this case Input is the Vector2(X, Y) coordinates of your mouse 
	if input.UserInputType == Enum.UserInputType.MouseButton1 then
		print("Clicked at: ".. Input.Position) 
    end
end)

This will enable you to effectively find the mouseaim which you then should return as a parameter to your actual projectile system.

However, if your camera is constrained then you already know that your mouse position will always be pointing at the centre, which you can calculate by doing this:

local Vector = Vector2.new(workspace.CurrentCamera.ViewportSize.X / 2, workspace.CurrentCamera.ViewportSize.Y / 2  - (game:GetService("GuiService"):GetGuiInset().Y/2))

With that, you finally found the replacement for your mouseaim parameter (mouseaim = Vector)

PM Me if you have further questions!