I am trying to make my guns mobile-friendly and it seems my code is incorrect as shown in the video… please let me know if you have ideas!
local rayOrigin = tool.Handle.CFrame.p
local rayDirection
local screenCenter = Vector2.new(camera.ViewportSize.X / 2, camera.ViewportSize.Y / 2)
print(screenCenter.X)
local rayFromScreen = camera:ViewportPointToRay(screenCenter.X, screenCenter.Y)
rayDirection = (rayFromScreen.Direction).unit * 300
local ray = Ray.new(rayOrigin, rayDirection)
local part, position = workspace:FindPartOnRay(ray, player.Character, false, true)
I dont think the “dot” is in the middle of the screen (Atleast on mobile). because if you freeze frame at the time you actually hurt the rig, the dot wasn’t in the middle of the screen but the rig’s head was. So it’s probably a GUI issue not a code one.
If you set a frames position to {0.5, 0}, {0.5, 0} and its AnchorPoint to (0.5, 0.5) it should be at the middle of the screen. Make sure to also turn on IgnoreGuiInset in the ScreenGui which means that the ScreenGui will go over Roblox’s top bar UI as well.
Looking at the script it seems like you’re casting a ray from the handle in the direction of the reticle.
The ray won’t hit where the reticle points since the ray starts from the handle and not the camera.
Here’s a video showing two different ways of aiming the gun. The first half shows a similar approach as you’ve used. The second half however changes the rayDirection to point towards the position where a ray cast from the camera intersects the world.
One thing to note is that the latter method doesn’t work as well up close as the intersection point ends up to the right of the handle and in worst cases even behind it.
So instead of pointing the gun towards the reticles view you could instead point it towards a ray intersection point:
local rayParams = RaycastParams.new()
-- Add necessary filters for ray casting if necessary
local rayLength = 100
local rayOrigin = tool.Handle.CFrame.p
local rayDirection
-- Note: A ray towards the middle of the screen is the same as a camera's look vector
local screenCenter = Vector2.new(camera.ViewportSize.X / 2, camera.ViewportSize.Y / 2)
print(screenCenter.X)
local rayFromScreen = camera:ViewportPointToRay(screenCenter.X, screenCenter.Y)
rayResult = workspace:Raycast(camera.CFrame.Position, camera.CFrame.LookVector * rayLength, rayParams)
if rayResult then
rayDirection = rayResult.Position - rayOrigin
else
-- Ray didn't reach anything within a give distance
rayDirection = (rayFromScreen.Direction).unit * 300 -- Consider using camera.CFrame.LookVector
end
local ray = Ray.new(rayOrigin, rayDirection)
local part, position = workspace:FindPartOnRay(ray, player.Character, false, true)
Wow. Thank you for your lengthy response. I understand what you are saying. I have implemented the code and it seems to be working better though it has some issues. Do I need to destroy the ray or…
print("MOBILE")
local rayParams = RaycastParams.new()
local rayDirection
local rayLength = 100
local rayResult = nil
local rayOrigin = tool.Handle.CFrame.p
local screenCenter = Vector2.new(camera.ViewportSize.X / 2, camera.ViewportSize.Y / 2)
local rayFromScreen = camera:ViewportPointToRay(screenCenter.X, screenCenter.Y)
rayResult = workspace:Raycast(camera.CFrame.Position, camera.CFrame.LookVector * rayLength, rayParams)
if rayResult then
rayDirection = rayResult.Position - rayOrigin
else
rayDirection = (rayFromScreen.Direction).unit * 300
end
local ray = Ray.new(rayOrigin, rayDirection)
local part, position = workspace:FindPartOnRay(ray, player.Character, false, true)
I’m not really sure why it doesn’t work sometimes, try printing out rayResult and see if the ray actually hits the other characters when you’re aiming at them.
Also I’d recommend to replace the ´Ray.new()´ with another ray cast as workspace:FindPartOnRay() is deprecated. workspace:Raycast() is essentially the same but has better control over what to filter in / out when ray casting. In this case it doesn’t change much but it’s a good practice to not use deprecated functions.
To exclude descendants of the player’s character from both ray casts you should add the following code after creating the variable rayParams: