The RaycastParams blacklist doesn't want to change?

Ah, so we must be working backwards now…

local tool = script.Parent
local debris = game:GetService('Debris')

local function VisualizeRaycast(raycastResult: RaycastResult, originVector: Vector3)
    local distance: number = (originVector - raycastResult.Position).Magnitude
    local thickness: number = 0.1

    local linearLine: Part = Instance.new("Part")
    linearLine.Anchored = true
    linearLine.CanCollide = false
    linearLine.Size = Vector3.new(thickness, thickness, distance)
    linearLine.CFrame = CFrame.lookAt(originVector, raycastResult.Position) * CFrame.new(0, 0, -(distance / 2))
    linearLine.Color = Color3.fromRGB(math.random(0, 255), math.random(0, 255), math.random(0, 255))
    linearLine.Parent = workspace
    debris:AddItem(linearLine, 1)

    return linearLine
end

script.Parent.Shoot.OnServerEvent:Connect(function(player, mousePosition)
    local penetrationAttempts = tool:GetAttribute('Penetration')
    local damage = tool:GetAttribute('Damage')
    local Enemy = nil
    local rOrigin = tool.Raycast.Position

    local whitelist = {}
    local blacklist = {player.Character}

    while penetrationAttempts > 0 do
        local raycastParams = RaycastParams.new()
        raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
        raycastParams.FilterDescendantsInstances = blacklist
        local rayResult = game.Workspace:Raycast(rOrigin, (mousePosition - rOrigin) * 200, raycastParams)

        if rayResult then
            VisualizeRaycast(rayResult, rOrigin)

            Enemy = rayResult.Instance.Parent
            rOrigin = rayResult.Position

            if Enemy:FindFirstChildOfClass('Humanoid') then
                Enemy.Humanoid.Health -= damage
                table.insert(whitelist, Enemy)
            end

            table.insert(blacklist, rayResult.Instance)
            penetrationAttempts -= 1
        else
            break
        end
    end
end)

We are maintaining two separate tables, whitelist and blacklist, which keep track of the instances that we want to allow or disallow in subsequent raycasts. The whitelist table initially contains only the player’s character, while the blacklist table is empty.

In each iteration of the loop, we first create a new RaycastParams object with a FilterType of Blacklist, and FilterDescendantsInstances set to the blacklist table. We then perform a raycast using these parameters.

If the raycast hits something, we add the instance to the blacklist table (to prevent subsequent raycasts from hitting it), and if the instance is an enemy with a Humanoid descendant, we reduce their health and add them to the whitelist table.

We then decrement the penetrationAttempts variable and continue with the loop, unless there are no more penetration attempts remaining, in which case we break out of the loop.

If this doesn’t work, there might be one more thing I can think of, but let me know! :sob:

Now it goes like in the video I posted above lol. I might end up just making a different folder for enemies and always whitelist them

That could be a viable solution, sorry I couldn’t be of more help!

Nah that’s okay. Maybe we can use some properties of ray result? Like normal vector. Don’t even know what that is xd

Hey, I’ve actually got something. Now I need to somehow keep the right angle. Also the solution I wanted to try with folders didn’t work

local tool = script.Parent
local debris = game:GetService('Debris')

local function VisualizeRaycast(raycastResult: RaycastResult, originVector: Vector3)
	local distance: number = (originVector - raycastResult.Position).Magnitude
	local thickness: number = 0.1

	local linearLine: Part = Instance.new("Part")
	linearLine.Anchored = true
	linearLine.CanCollide = false
	linearLine.Size = Vector3.new(thickness, thickness, distance)
	linearLine.CFrame = CFrame.lookAt(originVector, raycastResult.Position) * CFrame.new(0, 0, -(distance / 2))
	linearLine.Color = Color3.fromRGB(math.random(0, 255), math.random(0, 255), math.random(0, 255))
	linearLine.Parent = workspace
	debris:AddItem(linearLine, 1)

	return linearLine
end

tool.Shoot.OnServerEvent:Connect(function(player, mousePosition)
	local penetrationAttempts = tool:GetAttribute('Penetration')
	local damage = tool:GetAttribute('Damage')
	local Enemy = nil
	local rOrigin = tool.Raycast.Position

	local raycastParams = RaycastParams.new()
	raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
	raycastParams.FilterDescendantsInstances = {player.Character}
	
	local rayResult = game.Workspace:Raycast(rOrigin, (mousePosition - rOrigin) * 200, raycastParams)

	while penetrationAttempts > 0 do
		task.wait(0.1)
		penetrationAttempts -= 1

		if rayResult then
			VisualizeRaycast(rayResult, rOrigin)

			Enemy = rayResult.Instance.Parent
			rOrigin = rayResult.Position

			if Enemy:FindFirstChildOfClass('Humanoid') then
				Enemy.Humanoid.Health -= damage / (tool:GetAttribute('Penetration') - penetrationAttempts)
			else
				break
			end
			
			rayResult = game.Workspace:Raycast(rOrigin, rayResult.Normal * -200, raycastParams)
		end
	end
end)

Nice! It looks to me like it just went that way because you had your cursor over in that direction.

Look closer to the end, it’s always a straight line sadly

Ah, I see now! It looks like the issue is in how you’re calculating the direction of the raycast.

In the line game.Workspace:Raycast(rOrigin, (mousePosition - rOrigin) * 200, raycastParams) , you’re using mousePosition - rOrigin to calculate the direction of the raycast.

However, mousePosition is the position of the mouse in screen coordinates, not in world coordinates, so this calculation won’t work as intended.

I’m not sure if this would work but we can always give it a go! I’ve rewritten the code snippet that I’m replying to using the Camera’s ViewportPointToRay method to convert the mouse position to a ray in world space.

tool.Shoot.OnServerEvent:Connect(function(player, mousePosition)
    local penetrationAttempts = tool:GetAttribute('Penetration')
    local damage = tool:GetAttribute('Damage')
    local Enemy = nil
    local rOrigin = tool.Raycast.Position

    local raycastParams = RaycastParams.new()
    raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
    raycastParams.FilterDescendantsInstances = {player.Character}

    local camera = workspace.CurrentCamera
    local ray = camera:ViewportPointToRay(mousePosition.X, mousePosition.Y)

    local rayResult = game.Workspace:Raycast(rOrigin, ray.Direction * 200, raycastParams)

    while penetrationAttempts > 0 do
        task.wait(0.1)
        penetrationAttempts -= 1

        if rayResult then
            VisualizeRaycast(rayResult, rOrigin)

            Enemy = rayResult.Instance.Parent
            rOrigin = rayResult.Position

            if Enemy:FindFirstChildOfClass('Humanoid') then
                Enemy.Humanoid.Health -= damage / (tool:GetAttribute('Penetration') - penetrationAttempts)
            else
                break
            end
            
            rayResult = game.Workspace:Raycast(rOrigin, rayResult.Normal * -200, raycastParams)
        end
    end
end)

(oops, I forgot to mention make sure you don’t replace the entire script with this, only after the .OnServerEvent)

Actually mousePosition is a Vector3. Mouse.Hit.Position and my bullet always goes in same direction despite my mouse or screen in this method

Hmm. Instead of subtracting the origin (rOrigin) from the mouse position (mousePosition), what happens if we subtract the origin from the Hit.Position property of the mouse?

tool.Shoot.OnServerEvent:Connect(function(player, mousePosition)
    local penetrationAttempts = tool:GetAttribute('Penetration')
    local damage = tool:GetAttribute('Damage')
    local Enemy = nil
    local rOrigin = tool.Raycast.Position

    local raycastParams = RaycastParams.new()
    raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
    raycastParams.FilterDescendantsInstances = {player.Character}

    local mouse = player:GetMouse()
    local ray = Ray.new(rOrigin, (mouse.Hit.Position - rOrigin).Unit * 200)

    local rayResult = game.Workspace:Raycast(ray, raycastParams)

    while penetrationAttempts > 0 do
        task.wait(0.1)
        penetrationAttempts -= 1

        if rayResult then
            VisualizeRaycast(rayResult, rOrigin)

            Enemy = rayResult.Instance.Parent
            rOrigin = rayResult.Position

            if Enemy:FindFirstChildOfClass('Humanoid') then
                Enemy.Humanoid.Health -= damage / (tool:GetAttribute('Penetration') - penetrationAttempts)
            else
                break
            end
            
            rayResult = game.Workspace:Raycast(ray, rayResult.Normal * -200, raycastParams)
        end
    end
end)

uh well I must say that Ray.new is not the way game.Workspace:Raycast would work. Anyway the result stays the same after fixing

I rarely ever use Raycasting, so I knew I’d be bound to make a mistake somewhere. Thanks for letting me know!

I’m truly stumped, but I suppose we could calculating the direction vector from the rOrigin towards the mousePosition instead of just multiplying mousePosition by a scalar value.

Try this out and let me know:

tool.Shoot.OnServerEvent:Connect(function(player, mousePosition)
    local penetrationAttempts = tool:GetAttribute('Penetration')
    local damage = tool:GetAttribute('Damage')
    local Enemy = nil
    local rOrigin = tool.Raycast.Position
    
    local raycastParams = RaycastParams.new()
    raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
    raycastParams.FilterDescendantsInstances = {player.Character}
        
    while penetrationAttempts > 0 do
        task.wait(0.1)
        penetrationAttempts -= 1
        
        local direction = (mousePosition - rOrigin).Unit
        local rayResult = game.Workspace:Raycast(rOrigin, direction * 200, raycastParams)
        
        if rayResult then
            VisualizeRaycast(rayResult, rOrigin)
            
            Enemy = rayResult.Instance.Parent
            rOrigin = rayResult.Position
            
            if Enemy:FindFirstChildOfClass('Humanoid') then
                Enemy.Humanoid.Health -= damage / (tool:GetAttribute('Penetration') - penetrationAttempts)
            else
                break
            end
        else
            break
        end
    end
end)

Nope, the result is same as my very first video here. So the solution was simple as hell. Since the second time we raycast, the direction (mousePosition - rOrigin) becomes 0 because mousePosition and rOrigin are same values at this point. So instead of making a new direction we save the very first one (Direction)

local tool = script.Parent
local debris = game:GetService('Debris')

local function VisualizeRaycast(raycastResult: RaycastResult, originVector: Vector3)
	local distance: number = (originVector - raycastResult.Position).Magnitude
	local thickness: number = 0.1

	local linearLine: Part = Instance.new("Part")
	linearLine.Anchored = true
	linearLine.CanCollide = false
	linearLine.Size = Vector3.new(thickness, thickness, distance)
	linearLine.CFrame = CFrame.lookAt(originVector, raycastResult.Position) * CFrame.new(0, 0, -(distance / 2))
	linearLine.Color = Color3.fromRGB(math.random(0, 255), math.random(0, 255), math.random(0, 255))
	linearLine.Parent = workspace
	debris:AddItem(linearLine, 1)

	return linearLine
end

tool.Shoot.OnServerEvent:Connect(function(player, mousePosition)
	local penetrationAttempts = tool:GetAttribute('Penetration')
	local damage = tool:GetAttribute('Damage')
	local Enemy = nil
	local rOrigin = tool.Raycast.Position

	local raycastParams = RaycastParams.new()
	raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
	raycastParams.FilterDescendantsInstances = {player.Character}
	
	local Direction = mousePosition - rOrigin
	local rayResult = game.Workspace:Raycast(rOrigin, Direction * 200, raycastParams)

	while penetrationAttempts > 0 do
		task.wait(0.1)
		penetrationAttempts -= 1

		if rayResult then
			VisualizeRaycast(rayResult, rOrigin)

			Enemy = rayResult.Instance.Parent
			rOrigin = rayResult.Position

			if Enemy:FindFirstChildOfClass('Humanoid') then
				Enemy.Humanoid.Health -= damage / (tool:GetAttribute('Penetration') - penetrationAttempts)
			else
				break
			end
			
			rayResult = game.Workspace:Raycast(rOrigin, Direction * 200, raycastParams)
		end
	end
end)

But thanks for all your help guys

1 Like

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