Raycast Result changes with material

Hello everyone! I have a problem where I used this script for my game. I found out that the speed of the laser/bullet changes according to the material it hit. Please help me. Here is my script:

Summary
local function Shoot(hrp,mouseCF,spellName,plr,fireball)
	local hitAlr = false

	if fireball:FindFirstChild("Ricochet") then
		if plr.Ricochet.Value > 0 then
			fireball.Ricochet.Value = plr.Ricochet.Value
		end
	end
	local maxDistance = 100
	local curDistance = 0
	local totalTime = 0
	local stepDistance = 3
	local stepWait = 0
	coroutine.resume(coroutine.create(function()
		while fireball do
			wait(1)
			totalTime += 1
			if totalTime > 20 then
				hitAlr = true
			end
		end
	end))
	local currentPos = hrp.Position
	local currentNormal = (mouseCF - hrp.Position).lookVector
	local function Step(overrideDistance)
		-- Cast ray:
		local params = RaycastParams.new()
		local direction = currentNormal * (overrideDistance or stepDistance)
		params.FilterType = Enum.RaycastFilterType.Blacklist
		local result = workspace:Raycast(currentPos, direction)
		local pos
		
		if result then
			pos = result.Position
		else
			pos = currentPos + direction
		end

		-- Update laser position:
		if fireball then
			fireball.CFrame = CFrame.new(currentPos:Lerp(pos, 0.5), pos)
		end

		local oldPos = currentPos
		currentPos = pos

		if result then
			-- r = d - 2(d DOT n)n
			if spellTable[result.Instance.Name] == nil then
				local hit = result.Instance
				local runDestroy = false
				local prepStr = hit.Parent.Parent.Name.."."..hit.Parent.Name.."."..hit.Name
			
				
				if true then
					local ok, no = pcall(function()
						if hit ~= nil then
							if hit.Parent ~= plr.Character and hit.Parent.Parent ~= plr.Character and hit.Parent.Parent.Parent ~= plr.Character and spellTable[hit.Name] ~= 1 and hit.ClassName ~= "SpawnLocation" then
								local markedPlayer = nil
								local markedNPC = nil
								print(prepStr)
								
								local prepStr = hit.Parent.Parent.Name.."."..hit.Parent.Name.."."..hit.Name
								if game.Players:GetPlayerFromCharacter(hit.Parent) then
									markedPlayer = game.Players:GetPlayerFromCharacter(hit.Parent)
								elseif game.Players:GetPlayerFromCharacter(hit.Parent.Parent) then
									markedPlayer = game.Players:GetPlayerFromCharacter(hit.Parent.Parent)
								elseif game.Players:GetPlayerFromCharacter(hit.Parent.Parent.Parent) then
									markedPlayer = game.Players:GetPlayerFromCharacter(hit.Parent.Parent.Parent)
								end
								if not markedPlayer then
									if hit.Parent:FindFirstChild("Humanoid")then
										markedNPC = hit.Parent
									elseif hit.Parent.Parent:FindFirstChild("Humanoid")then
										markedNPC = hit.Parent.Parent
									end
								end
								if fireball:FindFirstChild("Blast") then
									fireball.Blast.Enabled = true
								end
								if markedPlayer then
									if markedPlayer.Character ~= nil and markedPlayer.TeamColor ~= plr.TeamColor then
										if markedPlayer.Character.Humanoid.Health > 0  then		
											print("MARKEDPLAYER!")
											hitAlr = true
											markedPlayer.Character.Humanoid.Health -= (plr.Damage.Value)
											game.ReplicatedStorage.Earn:FireClient(plr,"LVL",math.floor((Spellmodule.FindXP(plr.Level.Value)/20)))
											plr.XP.Value += math.floor((Spellmodule.FindXP(plr.Level.Value)/20))
											if plr.XP.Value >= Spellmodule.FindXP(plr.Level.Value) then
												plr.XP.Value = plr.XP.Value - Spellmodule.FindXP(plr.Level.Value)
												plr.Level.Value = plr.Level.Value + 1
												game.ReplicatedStorage.LevelUp:FireClient(plr)
												plr.leaderstats.Cash.Value = plr.leaderstats.Cash.Value + (5 * Spellmodule.FindXP(plr.Level.Value))
											end
											local give = math.ceil((plr.Level.Value^(math.random(1.1,3.3)))) + 20
											plr.leaderstats.Cash.Value += give
											game.ReplicatedStorage.Earn:FireClient(plr,"CASH",give)
											if markedPlayer.Character.Humanoid.Health <= 0 then
												print("KILLED THAT PLAYER")
												plr.Kills.Value += 1
												plr.leaderstats.Cash.Value = plr.leaderstats.Cash.Value + 200
												game.ReplicatedStorage.Earn:FireClient(plr,"CASH",200)
												game.ReplicatedStorage.Died:FireClient(markedPlayer,spellName,plr.DisplayName)
											end

											if spellName == "Fireball" then
												local fires = {}

												for i, child in pairs(markedPlayer.Character:GetChildren()) do

													if child:IsA("BasePart") and child.Name ~= "Head" then

														local fire = Instance.new("Fire", child)
														fire.Name = "fire"
														table.insert(fires, fire)
													end

												end
												wait(5)
												for i, child in pairs(markedPlayer.Character:GetChildren()) do

													if child:FindFirstChild("fire") then
														table.remove(fires,table.find(fires,child.fire))
														child.fire:Destroy()
													end
												end
											elseif spellName == "Freeze Flake" then
												FreezeCharacter(markedPlayer.Character,markedPlayer) 

											elseif spellName == "Fog" then
												fireball.Weldy.Part0 = markedPlayer.Character.HumanoidRootPart
												fireball.CFrame = markedPlayer.Character.HumanoidRootPart.CFrame
												game.ReplicatedStorage.SelfSpell:FireClient(markedPlayer,"FOG")
												wait(5)
												game.ReplicatedStorage.SelfSpellEnd:FireClient(markedPlayer,"FOG")

											elseif spellName == "Pumpkin Head" then
												coroutine.resume(coroutine.create(function()
													local cloned = game.ServerStorage.SpellEffect:FindFirstChild(spellName):Clone()
													for i, v in pairs(cloned:GetChildren()) do
														if v:IsA("BasePart") then
															v.CFrame = markedPlayer.Character.Head.CFrame
														end
													end
													cloned.Weldy.Part0 = markedPlayer.Character.Head
													cloned.Weldy.Enabled = true
													cloned.Cone.Position = Vector3.new(cloned.Cone.Position.X,cloned.Cone.Position.Y + 1,cloned.Cone.Position.Z)
													game.ReplicatedStorage.SelfSpell:FireClient(markedPlayer,"PUMPKIN HEAD")
													wait(5)
													game.ReplicatedStorage.SelfSpellEnd:FireClient(markedPlayer,"PUMPKIN HEAD")
												end))
											elseif spellName == "Skull" then
												fireball.CFrame = markedPlayer.Character.Head.CFrame
												fireball.Weldy.Part0 = markedPlayer.Character.Head
												fireball.Weldy.Enabled = true
												wait(10)
												game.ReplicatedStorage.SelfSpell:FireClient(markedPlayer,"SKULL")
												wait(5)
												game.ReplicatedStorage.SelfSpellEnd:FireClient(markedPlayer,"SKULL")
											end

										end
									end

								else
									if markedNPC then
										print("MARKEDNPC!!")
										hitAlr = true
										--===================================================
										--NPC NPC NPC NPC NPC NPC NPC NPC NPC NPC NPC NPC NPC
										--===================================================
										markedNPC.Humanoid.Health -= (plr.Damage.Value)
										game.ReplicatedStorage.Earn:FireClient(plr,"LVL",math.floor((Spellmodule.FindXP(plr.Level.Value)/20)))
										plr.XP.Value += math.floor((Spellmodule.FindXP(plr.Level.Value)/20))
										if plr.XP.Value >= Spellmodule.FindXP(plr.Level.Value) then
											plr.XP.Value = plr.XP.Value - Spellmodule.FindXP(plr.Level.Value)
											plr.Level.Value = plr.Level.Value + 1
											game.ReplicatedStorage.LevelUp:FireClient(plr)
											plr.leaderstats.Cash.Value = plr.leaderstats.Cash.Value + (5 * Spellmodule.FindXP(plr.Level.Value))
										end
										local give = math.ceil((plr.Level.Value^(math.random(1.1,3.3)))) + 20
										plr.leaderstats.Cash.Value += give
										game.ReplicatedStorage.Earn:FireClient(plr,"CASH",give)
										if markedNPC.Humanoid.Health <= 0 then
											if debounce == false then
												debounce = true
												print("KILLED THAT PLAYER")
												plr.Kills.Value += 1
												plr.leaderstats.Cash.Value = plr.leaderstats.Cash.Value + 200
												game.ReplicatedStorage.Earn:FireClient(plr,"CASH",200)

												debounce = false
											end
										end

										if spellName == "Fireball" then
											local fires = {}

											for i, child in pairs(markedNPC:GetChildren()) do

												if child:IsA("BasePart") and child.Name ~= "Head" then

													local fire = Instance.new("Fire", child)
													fire.Name = "fire"
													table.insert(fires, fire)
												end

											end
											wait(5)
											for i, child in pairs(markedNPC:GetChildren()) do

												if child:FindFirstChild("fire") then
													table.remove(fires,table.find(fires,child.fire))
													child.fire:Destroy()
												end
											end
										elseif spellName == "Freeze Flake" then
											FreezeCharacter(markedNPC,"NPC") 

										elseif spellName == "Fog" then
											fireball.Weldy.Part0 = markedNPC.HumanoidRootPart
											fireball.CFrame = markedNPC.HumanoidRootPart.CFrame
											wait(5)
										elseif spellName == "Pumpkin Head" then
											coroutine.resume(coroutine.create(function()
												local cloned = game.ServerStorage.SpellEffect:FindFirstChild(spellName):Clone()
												for i, v in pairs(cloned:GetChildren()) do
													if v:IsA("BasePart") then
														v.CFrame = markedNPC.Head.CFrame
													end
												end
												cloned.Weldy.Part0 = markedNPC.Head
												cloned.Weldy.Enabled = true
												cloned.Cone.Position = Vector3.new(cloned.Cone.Position.X,cloned.Cone.Position.Y + 1,cloned.Cone.Position.Z)
												wait(5)
											end))
										elseif spellName == "Skull" then
											fireball.CFrame = markedNPC.Head.CFrame
											fireball.Weldy.Part0 = markedNPC.Head
											fireball.Weldy.Enabled = true
											wait(5)
										end
									else
										if plr.Ricochet.Value > 0  then
											if fireball:FindFirstChild("Ricochet") and hit ~= nil then
												if fireball.Ricochet.Value > 0 and spellTable[hit.Name] ~= 1 then
													if hit.Parent.Name ~= plr.Name and hit.Parent.Parent.Name ~= plr.Name  and hit.Name ~= "Fog" and hit.ClassName ~= "SpawnLocation" then
														print(prepStr)
														fireball.Ricochet.Value -= 1
														local norm = result.Normal
														local reflect = (currentNormal - (2 * currentNormal:Dot(norm) * norm))
														currentNormal = reflect

														Step()

													else
														hitAlr = true
													end
												else
													hitAlr = true
												end
											else
												hitAlr = true
											end
										else
											hitAlr = true
										end
										if hitAlr then
											if hit.Name ~= "Floor" and spellName == "Ghost" then
												hitAlr = false
											end

										end
									end
								end
								fireball:Destroy()
								hitAlr = true
							end
						end
					end)
					if not ok then
						warn(no)
						game.ReplicatedStorage.SendError:FireClient(plr,no)
					end
				end
			end

		else
			local ok1, no1 = pcall(function()
				for i, v in pairs(game.Players:GetPlayers()) do
					if v.Character and plr.Character and v.TeamColor ~= plr.TeamColor and v ~= plr then
						if v.Character:FindFirstChild("Humanoid") and plr.Character:FindFirstChild("Humanoid") then
							if v.Character.Humanoid.Health > 0 and plr.Character.Humanoid.Health > 0 then
								if (plr.Character.HumanoidRootPart.Position - v.Character.HumanoidRootPart.Position).Magnitude < plr.Detect.Value * 5 then
									currentNormal = CFrame.new(fireball.Position,v.Character.HumanoidRootPart.Position).lookVector
									print("DETECT!")
									break
								end
							end
						end
					end
				end
			end)
			if not ok1 then
				warn(no1)
				game.ReplicatedStorage.SendError:FireClient(plr,no1)
			end
		end

		curDistance = (curDistance + (pos - oldPos).Magnitude)

		-- Recurse if max distance not reached:
		if hitAlr == false or totalTime < 20 then
			wait(stepWait)
			Step()
		end
	end

	Step()

	-- Done! Destroy laser:
	pcall(function()
		fireball:Destroy()
	end)
end

The video:

Everything works all fine, there are no errors, the only thing it the material that the laser/bullet hit changes according to the material. If you read until here, please help! Thanks!

The “Material” property of the returned RaycastResult table will change according the tip of material the raycast hit.

Thank you, but do you know how to make the script unaffected by the material it hits?

What do you mean? As in phase through the parts?

No, because as it is shown in the video, the part is supposed to bounce. Its kind like this:

local tableOfIgnoreParts = {"Red","Blue","Yellow","Fireball"}
result = workspace:raycast(pos,direction,param)
    if results.Instance then
        print("HIT")
        if results.Instance.Name is not in the table of ignore parts then
           make the result.Instance bounce
        end
    end

It is in a function calling itself so its like looping. The thing is that if it prints “hit”, the speed of the spell sometimes change. Please help. Thanks!

In the video it is bouncing though?

Yes, it is bouncing, but the speed it travels through the air changes. I manae to find out how to fix it tho using params thx

But right now it print(prepStr) infinitely. Please help

Add a debounce to prevent the function being executed too often.