Need help ray casting

https://gyazo.com/cfe4df3082d7e12983859dcb2b8177bf
Hello, so as you can see on the gif, it prints when it hits something, but for some reason the hit isn’t realistic or sometimes it doesn’t detects at all

This is my test code:

local plr = game.Players.LocalPlayer
local char = plr.Character or plr.CharacterAdded:Wait()
local mou = plr:GetMouse()

mou.Button1Down:Connect(function()
	local Bullet = Instance.new('Part')
	Bullet.Size = Vector3.new(0.16, 0.18, 3.02)
	Bullet.BrickColor = BrickColor.new('New Yeller')
	Bullet.Material = Enum.Material.Neon
	Bullet.Anchored = false
	Bullet.Parent = workspace
Bullet.CanCollide = false
Bullet.CFrame = CFrame.new(char.Head.CFrame.Position, mou.Hit.Position) * CFrame.new(0,0,-2)
Bullet.Velocity = -(char.Head.CFrame.Position - mou.Hit.Position).Unit * 2300

while (Bullet) do
	local ray = Ray.new(Bullet.CFrame.Position, Bullet.CFrame.LookVector.Unit * 20)
	local hit,pos,surface = workspace:FindPartOnRayWithIgnoreList(ray,{char,Bullet})
	if hit then
		print(hit.Name)
	end
	wait()
end

game:GetService('Debris'):AddItem(Bullet,10)
end)

How can I make it detects the ray correctly?

It’s not the best idea to use physics bullets. The calculations at such high speeds can be less than accurate.

1 Like

Then what do you recommend me to do?
:thinking:

You can use hitscan detection, or you can create your own custom bullet drop raycasting system, which isn’t difficult at all. I’ll tell you how to do it here, but if you still can’t do it then I’m pretty sure there’s a module that everyone’s been repping that does it for you.

First, fire a ray straight out. If there is no hit, then wait a small bit and fire a new ray that is angled slightly down from the end position of the first ray. Repeat until you reach a limit you set, or when you hit something. With some math, you can make a bullet follow this path as well.

So something like this?

while (Bullet) do
	local down = 0
	local ray = Ray.new(Bullet.CFrame.Position, (Bullet.CFrame.LookVector.Unit - Vector3.new(0,down,0)) * 20)
	local hit,pos,surface = workspace:FindPartOnRayWithIgnoreList(ray,{char,Bullet})
	if hit then
		print(hit.Name)
		elseif not hit then
			down = down + 0.5
	end
	wait()
end

EDIT: still it doesn’t works pretty fine

Sort of. Posted this in a previous thread for someone:

local PROJECTILE_SPEED = 3   -- how fast projectile moves
local RAY_DISTANCE     = 500 -- max distance it can travel
local PROJECTILE_DROP  = 0   -- whether the bullet drops or not, needs to be negative number if you want it to drop

local fireBullet = (function (A, B, projectile, ignore_model, ignore_func)
	ignore_func = ignore_func or (function () return false end)
	
	if not projectile then
		return
	end
	
	local shot_dir = B.lookVector * RAY_DISTANCE
	local shot_ray = Ray.new(B.p, shot_dir)
	
	local _, true_shot = game.Workspace:FindPartOnRay(shot_ray, ignore_model)
	
	local drop = CFrame.Angles((math.random() * PROJECTILE_DROP) * 0.01, 0, 0)
	
	projectile.Anchored = true
	projectile.CFrame   = CFrame.new(A.p, true_shot)
	projectile.Parent   = game.Workspace
	
	local Dist, Hit, Pos, endPos, Surface = 0
	repeat
		local start = projectile.Position
		    end_pos = ((projectile.Position + (projectile.CFrame * drop).lookVector * PROJECTILE_SPEED) - projectile.Position).unit
		
		local dir_ray = Ray.new(
			start,
			end_pos.unit * PROJECTILE_SPEED
		)
		Hit, Pos, Surface = game.Workspace:FindPartOnRay(dir_ray, ignore_model)
		projectile.CFrame = CFrame.new(Pos, Pos + dir_ray.Direction)
		
		Dist = Dist + PROJECTILE_SPEED
		wait()
	until (Hit and not ignore_func(Hit)) or Dist > RAY_DISTANCE

	return {
		distance    = Dist;
		hit         = Hit;
		hit_pos     = Pos;
		hit_surface = Surface;
		projectile  = projectile;
	}
end)

Use example:

-- example usage:
local ignore_these_hits = (function (part)
	-- don't ignore anything unless it's called "ignore_me"
	if part.Name == "ignore_me" then
		return true
	end
	return false
end)

local hit_data = fireBullet(
	CFrame.new(0, 5, 0),			     -- Start position of bullet (must be CFrame)
	game.Workspace.CurrentCamera.CFrame, -- Player's camera position (must be CFrame)
	game.Workspace.Bullet,				 -- Pass any bullet part
	game.Worspace.Character,			 -- Pass a model you want it to ignore, e.g. the user's character that is shooting
	ignore_these_hits 					 -- Function for the raycasting to ignore any objects defined in the function as it shoots
)

if hit_data then
	print("Bullet travelled:", hit_data.distance)
	if hit_data.hit then
		print("Bullet hit:", hit_data.hit, "at position:", hit_data.hit_pos, "on surface:", hit_data.hit_surface)
	else
		print("Bullet did not hit anything, landed at location:", hit_data.projectile.CFrame)
	end
	
	-- remove bullet
	hit_data.projectile:Destroy()
end
3 Likes

So there’s no other way to ray cast this?

What do you mean by this? 30chars