Ray does not hit where the mouse is, in third person

But … it does work properly. If you want to change it feel free. This code fixes your problem, though

1 Like

Here is the code that I have got with the use of your Module. I basically changed :ViewportToRay to :ScreenPointToRay and changed additional 2 line, it seems like this is how your module works but the result is that it does not work.

Did I miss something? Here is the script:

function ShootBullet(ViewRay, Muzzle, Spread)
	local MuzzlePosition = Muzzle.Position
	if Ammo > 0 and Reloading == false then
		local CachedBullet = BulletCache:GetPart()	

		local worldRay = Ray.new(Muzzle.Position, ViewRay.Direction.Unit * 300)--I added this
		local ray = workspace:Raycast(worldRay.Origin, worldRay.Direction * 300)--And this
        --It seems like this is just like your module does it, but it still doesn't work. Did I miss something?
		
if ray ~= nil then
              --Rest of the code

Here is how I get the ViewRay:

local MouseLocation = UserInputService:GetMouseLocation()
local ViewRay = workspace.Camera:ScreenPointToRay(MouseLocation.X, MouseLocation.Y)
ShootBullet(ViewRay, Muzzle)--Call the Shoot function

The rest of the code is identical to the one I have posted in the post.

Pic of the result I got:

ray2

1 Like

Pretty sure the issue is that the ray is casted from the gun. If the ray was casted form the camera then it would work correctly

Now, you want the ray to start from the gun, so you have to calculate the direction vector yourself, you can’t use the one from the camera
To get this, you just have to substract Mouse.Hit with the guns position (the destination of the ray - the origin of the ray)
This does require 2 raycasts but I don’t think there is a way around it

1 Like

I believe Mouse.Hit is using :GetMouse which is not recommended by Roblox, this is why I am using the recommended one, UserInputService:GetMouseLocation. Is there a way to do this with this method?

1 Like

Ray.new() ins’t a raycast, it’s simply a data type to represent a ray
It has some nice methods, but that is basically it
Though it is a neat object to use when dealing with raycasts

1 Like

Yeah, basically, you want to raycast a first ray to find Mouse.Hit, where the mouse intersects with the world, this can either be done using :GetMouse() or casting a ray yourself using ScreenPointToRay() or ViewportPointToRay (always forget which one to use). Then, using this value, you are able to find where the ray coming from the weapon would end up at. You can then raycast a second ray from the weapon to Mouse.Hit (where direction is Mouse.Hit.Position - Origin) and use that ray for your gun’s code

Imo, :GetMouse() is totally fine. The ease of use makes it really appealing as opposed to doing raycasting yourself. I did make a module that replicates Player:GetMouse() but uses the newer alternatives, if you are interested.

2 Likes

If you don’t want to use Mouse.Hit to calculate the mouse position I recommend:
image

5:10 - Is where he shows the line of code I sent as a image.

2 Likes

Ok, I think I am doing what you and another user have told me, but it is still work.

I am casting two rays, first one with data from :ViewportPointToRay (I also tried with :ScreenPointToRay) and the second ray one based on the first one, like this:

local MouseLocation = UserInputService:GetMouseLocation()
local ViewRay = workspace.Camera:ScreenPointToRay(MouseLocation.X, MouseLocation.Y)

local mousePos = Ray.new(ViewRay.Origin, ViewRay.Direction * 300)
local ray = workspace:Raycast(MuzzlePosition, mousePos.Direction * 300)

For the “local ray = workspace:Raycast(MuzzlePosition, mousePos.Direction * 300)” I also tried to do “mouse.Pos.Origin - MuzzlePosition” (mouse.Pos.Position does not exist, had to use Origin) as you told me here but it didn’t work.

Where exacly is my code wrong? By the way, the rest of the code stayed unchanged, just like how I posted it in the beginning.

@WizulousThe2nd

FindPartOnRay is deprecated. Here is my code but it doesn’t work, where exactly is the problem?

local MouseLocation = UserInputService:GetMouseLocation()
local ViewRay = workspace.Camera:ViewportPointToRay(MouseLocation.X, MouseLocation.Y)

local mousePos = Ray.new(ViewRay.Origin, ViewRay.Direction * 300)
local ray = workspace:Raycast(MuzzlePosition, mousePos.Direction * 300)

Here the only difference between the code in the video and mine is this line which I replaced since the one in the video is deprecated:

local ray = workspace:Raycast(MuzzlePosition, mousePos.Direction * 300)

Maybe the problem is with this line?

  • 300 should be the distance, maybe try * 1000

And what’s not working about it?

The result is similar to the one I have posted at the start of the post. With ScreenPointToRay it is even worse.

Basically this:
Ray
ray2

Looks to me like you want the ray to aim towards wherever you mouse lands in world space.
You can achieve this by using the GetMouse function to get the mouse object, and then read the hit property.

This can be done using the following code:

local Client = game:GetService("Players").LocalPlayer -- Get the player object
local Mouse = Client:GetMouse() -- Get the mouse object
local MousePosition = Mouse.hit.Position -- hit is a CFrame, we only want the position

-- When then find the difference between our Raycast' origin and this point to get the direction of our raycast
local Direction = (MousePosition - MuzzlePosition)

In this code sample provided Direction would replace ViewRay.Direction in your Raycast.

You currently are not doing it in two steps, in this code, you are still making a raycast using the ViewRay and Muzzle directly
Also, btw, ViewRay and mousePos are like the same thing but with a longer direction, that you make longer a second time when raycasting
Here, ray should be

local RaycastResult = workspace:Raycast(mousePos.Origin, mousePos.Direction * 300)
if RaycastResult then 
	local GunRay = ray.new(MuzzlePosition, RaycastResult.Position - MuzzlePosition)
	-- Here you can perform a new raycast using GunRay
end
1 Like

Could you please give me an example of such a raycast using GunRay?

How does it look when shooting at the floor or a much closer object. To me it looks right, its just that the bullet part doesnt extend long enough.
Sorry I didnt read the part that mentioned that it works in close positions. Still, the bullet part doesnt seem to be long enough.

I am standing right next to a wall, there is no way it is not long enough.

local RaycastResult = workspace:Raycast(GunRay.Origin, GunRay.Direction * 1.1) -- Making the ray a bit longer than the distance, to make sure it hits

There is nothing fancy going on here, it’s just a raycast that follows GunRay
You can then use the RaycastResult to find if it hit a player or whatever your gun is supposed to shoot at

1 Like

Everyhting seems to work fine now, but not when the range of the ray that I cast from the muzzle of the gun is out. Meaning this part of the code doesn’t work:

if ray ~= nil then
--Some Code
		else--if the ray hit maximum range
			CachedBullet.CFrame = CFrame.lookAt(MuzzlePosition + (ViewRay.Direction * 300)/2, MuzzlePosition + ViewRay.Direction * 300) * CFrame.Angles(0, math.rad(90), 0)
			CachedBullet.Size = Vector3.new(300, 0.15, 0.15)
		end

Basically a similar result as before when I just started this post happens. I suppose the formula of the CFrame.lookAt is wrong, but I don’t know where exactly. By the way, I use CFrame.Angles to rotate the part since it is a Cylinder sphere.

Here instead of using ViewRay, you should use GunRay. ViewRay is the ray of the screen (aka the camera) to the mouse, while gun ray is the ray from the gun to the mouse, and thus should be used instead

1 Like

If you want the bullets to hit where you clicked, then you should cast a ray from the camera to the mouse.

function RaycastModule.rayCastToInput(origin, inputObject,passed_Params)
	local Camera = workspace.CurrentCamera
	local worldRay = Camera:ScreenPointToRay(inputObject.Position.X, inputObject.Position.Y)
	return rayCast(origin, worldRay.Direction,passed_Params)
end