Help with raycasting every frame

I am trying to make a system to detect when a projectile hits an object by using a raycast from the projectiles old position to the new position every frame, and seeing if the projectile touched anything in transit. Currently, the raycast is triggering in seemingly thin air, but the position of the raycast is multiple studs away from the projectile. Here is the part of my code:

CreateProjectile = function( velocity) – this function creates a visual bullet and handles raycast delay
print(“projectile createdcalled”)
local characters = game.Players
local rayparams = RaycastParams.new()
rayparams.FilterDescendantsInstances = {characters}
local projectile = Instance.new(“Part”)
projectile.CanQuery = false
projectile.Material = Enum.Material.Neon
projectile.Transparency = .5
projectile.Parent = game.Workspace
projectile.Size = Vector3.new(.1,.1,1)
projectile.CFrame = startPoint
projectile.Anchored = true
projectile.CanCollide = false
local projectileStartVector = projectile.Position
local MovementLoop
local hitCheck = false
local projectilePreviousPos

MovementLoop = game:GetService("RunService").Heartbeat:Connect(function()
	
	
	projectilePreviousPos = projectile.CFrame
	
	
	projectile.CFrame *= CFrame.new(0, 0, -velocity )
	local collisionCheck = workspace:Raycast(projectilePreviousPos.Position, projectile.CFrame.Position, rayparams)
	
	if collisionCheck and hitCheck == false  then
		hitCheck = true
		print("distance" ..  collisionCheck.Distance)
		print(projectile.Position)
		print(collisionCheck.Position)
		print(collisionCheck.Instance.Position)
		projectile:Destroy()
		MovementLoop:Disconnect()
	end
	

end)

Any help is appreciated, thank you!

1 Like

You’re using a RaycastParams object, but you’re not using any of its fields.

The RaycastParams object has a field called FilterDescendantsInstances which you can use to filter out instances you don’t want to collide with.

If you want to filter out the player, you can do something like this:

local raycastParams = RaycastParams.new()
raycastParams.FilterDescendantsInstances = {player}
1 Like

Is the raycast hitting the projectile? If so add an ignore list

local rayparams= RaycastParams.new()
rayparams.FilterType = Enum.RaycastFilterType.Exclude
rayparams.FilterDescendantsInstances = {projectile}

I added the raycast parameters, but the same issue is still happening.

You’re not using the RaycastParams object you created.

You need to pass the RaycastParams object to the Raycast function, like this:

local raycastParams = RaycastParams.new()
raycastParams.FilterDescendantsInstances = {player}
local raycastResult = workspace:Raycast(projectilePreviousPos.Position, projectile.CFrame.Position, raycastParams)

I defined the rayparams:
local raycastParams = RaycastParams.new()
raycastParams.FilterDescendantsInstances = {player}
local raycastResult = workspace:Raycast(projectilePreviousPos.Position, projectile.CFrame.Position, raycastParams)

I am then calling the raycast:
local collisionCheck = workspace:Raycast(projectilePreviousPos.Position, projectile.CFrame.Position, rayparams)

You’re using the wrong variable name.

You defined the variable as raycastParams, but you’re using rayparams.

You need to use the correct variable name:

local collisionCheck = workspace:Raycast(projectilePreviousPos.Position, projectile.CFrame.Position, raycastParams)

I corrected that, but nothing changed

You’re not checking the result of the Raycast.

You need to check the result of the Raycast to see if it hit anything.

You can do that by checking if the result is nil:

local raycastResult = workspace:Raycast(projectilePreviousPos.Position, projectile.CFrame.Position, raycastParams)
if raycastResult then
	-- The raycast hit something
end

I am doing that with this code:
if collisionCheck and hitCheck == false then
hitCheck = true
print(“distance” … collisionCheck.Distance)
print(projectile.Position)
print(collisionCheck.Position)
print(collisionCheck.Instance.Position)
projectile:Destroy()
MovementLoop:Disconnect()
end

collision check is the name of my raycast

You’re using the wrong variable name.

You defined the variable as raycastResult, but you’re using collisionCheck.

You need to use the correct variable name:

if raycastResult and hitCheck == false then
	hitCheck = true
	print("distance" ..  raycastResult.Distance)
	print(projectile.Position)
	print(raycastResult.Position)
	print(raycastResult.Instance.Position)
	projectile:Destroy()
	MovementLoop:Disconnect()
end

I am using different variable names but I am still using the same logic:

local collisionCheck = workspace:Raycast(projectilePreviousPos.Position, projectile.CFrame.Position, raycastParams)

	if collisionCheck and hitCheck == false  then
		hitCheck = true
		print("distance" ..  collisionCheck.Distance)
		print(projectile.Position)
		print(collisionCheck.Position)
		print(collisionCheck.Instance.Position)
		projectile:Destroy()
		MovementLoop:Disconnect()
	end

You’re not checking the result of the Raycast.

You need to check the result of the Raycast to see if it hit anything.

You can do that by checking if the result is nil:

local raycastResult = workspace:Raycast(projectilePreviousPos.Position, projectile.CFrame.Position, raycastParams)
if raycastResult then
	-- The raycast hit something
end

Yes, I am checking if the raycast hit, the name of my raycast is collisionCheck, and I am checking if it hit in the loop I provided above.

You’re using the wrong variable name.

You defined the variable as raycastResult, but you’re using collisionCheck.

You need to use the correct variable name:

if raycastResult then
	-- The raycast hit something
end

I am using the same syntax as you, but instead of raycast result, my raycast is called collisionCheck

You can generally just ignore him.

The second argument of Raycast is direction, not target. To convert target to direction, subtract the start position from the target position:

Raycast(projectilePreviousPos.Position, projectile.CFrame.Position-projectilePreviousPos.Position, rayparams)

That will create a ray that starts at projectilePreviousPos and ends at projectile.CFrame.Position (unless of course it hits something)

2 Likes

Thank you! That fixed my issue!

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.