Raycasting help!

basically i’m moving a part with runservice.heartbeat()
and im raycasting every heartbeat to check if the part has hit anything

im using the parts lookvector * 2 for the direction and its position for the origin
for some reason it does not work most of the time and the part is able to go through walls

i’m not using the function workspace:GetPartBoundsInBox() because I need the normal vector of the object that hit the part

Is the part canCollide turned on

why is that important? that does not affect anything. I’m using raycast to check if the part has been hit while moving.

yeah im just wondering how it goes through walls

the part is anchored and cancollide is not enabled and i’m moving the part every heartbeat with runservice.

Mind showing a video of the issue

Normally, you’d want the raycast to be in the direction it’s moving (e.g. AssemblyLinearVelocity for an unanchored part, but in your case it will be some value in your code) and also for the length to be at least the magnitude of the velocity times the Heartbeat timestep ‘dt’. Otherwise, the ray might not be as long as how far the part is going to move.

Also, using the Part.CFrame.LookVector is only useful if the LookVector happens to be the exact same direction as the velocity. It’s not generally useful to raycast or shapecast in a direction other than the velocity, when what you’re trying to do is predict collisions with stationary objects like walls.

Of course, if you want to detect two moving objects colliding, you can’t do this with raycasts at all, you need some math to compute the intersection of their paths.

You can make the ray a bit longer than speed * dt in order to not miss boundary cases, but if you do this, you have to remember to check that the hit distance is less than or equal to speed * dt, otherwise you’re detecting a hit a frame early (perhaps more than one frame early if you ray is generously too long).

2 Likes

i’m just trying to get the normal vector of the object the projectile hit honestly that’s all I want to achieve if I don’t need raycasting to achieve this then what would you recommend?

Raycasting is by far the easiest way to get the surface normal at the hit location for a variety of shape parts, and really the only way for MeshParts.

still looking for a solution my previous idea had some bugs

@EmilyBendsSpace how should I raycast every heartbeat when I do the part sometimes can go through walls how can I make the ray more accurate?

all I want is the part to be destroyed when hitting any object while its moving and I want to use raycasting every heartbeat to check if it got hit

This is interesting. I’m not sure how close the two objects are, but LookVector actually has a very small magnitude, so I suggest multiplying it by more than 2. Of course, you don’t want it to see too far ahead, but trying beyond 2 COULD help.

Apart from that, I’d love a little more context about what exactly you’re making.

Your probably should try using .Stepped as well as its before physics.

Heartbeat is after so it might already be late when the update is applied to apply any sort of correction.

Also the new shapecast should also give a raycast normal you could try it out.

Hi,

I think the issue is that you are multiplying the parts LookVector by 2, I think that it should be multiplied by 1000. Then it is more likely to hit an object.

If you need a place file, i have one here
Raycasting Example.rbxl (55.7 KB)

uhhh… not at all. you’d only need to raycast how far the object is moving every heartbeat. If it was moving 50 studs every heartbeat, then youd do “Part.CFrame.LookVector * (speed / Part.Size.Z)”

like this:

local RunService = game:GetService("RunService")
local Bullet = workspace:WaitForChild("Bullet") -- blahhh blahh change this w ur part...

local Connection = nil
local PerFrameMovement = 50 -- Its honestly better practice to do a "Studs per second", then times it by deltatime when applying it, but you do you

local Params = RaycastParams.new()
Params.FilterDescendantsInstances = {Bullet}
Params.FilterType = Enum.RaycastFilterType.Exclude

Connection = RunService.Heartbeat:Connect(function(DT)
	Bullet.CFrame *= CFrame.new(0, 0, -PerFrameMovement)
	
	local BulletCFrame = Bullet.CFrame
	local Raycast = workspace:Raycast(
		BulletCFrame.Position, BulletCFrame.LookVector * (PerFrameMovement / Bullet.Size.Z), Params
	)
	if Raycast then
		print("Raycast:" ..Raycast.Instance.Name)
		
		local NewPos = CFrame.lookAt(BulletCFrame.Position, Raycast.Position)
		Bullet:PivotTo(NewPos)
		
		Connection:Disconnect()
		return nil
	end
end)

Now, no matter the studs per second, the bullet will stop when hitting a part. (Unless its an absurdly high number, again, implement a studs/second instead.)

The bullet and wall were given a highlight to show theres no overlapping

1 Like

ill make this the solution for now ill see if this formula works also thanks for your help

never mind it did not work still looking

I already tried that it does not make any difference unfortunately.

How are you achieving this? I ran the exact same test on my computer, even tried using runtime filtering, and these are the results im getting:


And this is at 10 studs per frame, nowhere close to the 50 you’re using. When I run the script at 50 studs/frame, the raycast doesnt detect at all

I had wrote “speed / Part.Size.Z” instead of “speed - (Part.Size.Z / 2)”.