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
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).
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.
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.
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.
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