Raycast collision goes through walls and corners at high speeds

For my game, I want there to be an enemy that spins along the floor and bounces of the sides of the walls, sort of like a rogue sawblade.

With the script I made for this, the part is fine for a bit, but then randomly clips through the corners and walls.

It happens almost instantly when cranking the speed up.

Here is the code I have so far.

local RunService = game:GetService("RunService")
local part = script.Parent

local speed = 3
local direction = Vector3.new(1, 0, 1).Unit 

local function checkCollision()
	local raycastParams = RaycastParams.new()
	raycastParams.FilterType = Enum.RaycastFilterType.Exclude
	raycastParams.FilterDescendantsInstances = { part }

	local origin = part.Position
	local raycastResult = workspace:Raycast(origin, direction, raycastParams)

	if raycastResult then
		local normal = raycastResult.Normal
		direction = direction - 2 * (direction:Dot(normal)) * normal
	end
end

RunService.Heartbeat:Connect(function()
	task.wait() 
	part.Position = part.Position + direction * speed
	checkCollision()
end)

Is there a better way to handle something like this? Or is slow collision detection inevitable?

The entire game is client sided and single player, by the way. So this is not server lag.

Thanks for any help.

Oops, the first video cut out a bit too early. It happened, though.

Just make it so that CanCollide is on? Why do you need collisions on?

The script uses raycasting detect walls, and bounce off them when it hits one. CanCollide is on, but it wouldn’t matter if it was on or off because it doesn’t use it for collisions.

You could check when the part has collided with a wall. If it is, you could place the part at the player’s humanoidrootpart. I’m gonna go to sleep in a bout a minute so yeah sorry about that.

try

local raycastResult = workspace:Raycast(origin, direction * speed, raycastParams)

Looks like your raycast isn’t fast enough to take into account the collisions.
Why are you using task.wait() inside the Heartbeat function? Doesn’t the Heartbeat take care of the crashing/freezing caused by something like a while true do loop without a task.wait() in it?

Accidentally left that it when changing it from a normal loop. Thanks for that. Still, it will clip through sometimes. I think at normal speeds it’s main problem is corners, since that’s all it seems to go through. Is it normal for raycasting to bug out with corners?

Did you try debugging?


if raycastResult then
		print(tostring(raycastResult.Instance))
		local normal = raycastResult.Normal
		direction = direction - 2 * (direction:Dot(normal)) * normal
	end

Yes.

It will print that it hit a part before going through the wall.

you found a solution to this? I got the same problem.