Knife Throwing Physics Help

Math is my biggest weakpoint in scripting, and this issue is really hurting me right now. I’m trying to make a knife throw that can kill players.

At first I just let the server handle the physics and hitboxes(bad idea), but now I want a smoother knife throw and lets the client handle ownership. But I’m having issues with detecting when the knife hits something.

On the client, I have the client rotate the knife(manually CFrame, I don’t know any math for a physics rotation thing) as well as raycast every frame to detect if the knife hits something. The problem is, my raycast isn’t consistent. Sometimes it works fine, sometimes it’s a little off, and sometimes it just doesn’t work.

Below is a gif of what I mean(grey line is the raycast)
https://gyazo.com/71ed43c3f076235c28fa6fd889022bd3

I have no idea how to tackle this problem.

4 Likes

It looks like you’re pointing the raycast in the direction of the knife, when you actually want it pointed in the direction the knife is going in. You should make sure you’re using Ray.new(knifePosition, travelDirection) and not Ray.new(knifePosition, knife.lookVector)

1 Like

I wasn’t using lookVector before, but I did try it and got this:
https://gyazo.com/875dbd3b001e3bd4747967dd5e632d5c

Sorry if I sound stupid, but what is “travelDirection”

Here is my code if interested
https://gyazo.com/df0ed232da52873b5031c6f54154ff19

1 Like

Well, somewhere in your knife code, when the player clicks their mouse, the code takes the mouse’s hit position (the wall) and subtracts the starting position (the character’s hand probably) from it to get the direction the knife travels in (from the hand to the wall). This direction is what you want the second parameter in the Ray.new() to be. If for some reason you don’t have that in your script, then you can get the direction by subtracting the knife’s last position from it’s current position.

local hitRange = 1 -- this is the length of the raycast
local lastPos = knife.Position
local currentPos = knife.Position
while true do
    wait()
    lastPos = currentPos
    currentPos = knife.Position
    local direction = (currentPos - lastPos).unit
    local hit1, end1 = CastRay(knife.Position, direction * damageRange)
    -- deal damage if hit1
end
1 Like

I just tried it out, it works, but there are still instances where the knife just won’t detect it hit something

local Igs = {game.Workspace.Debribs,game.Workspace.Coins,game.Workspace.Clocks,Player.Character,game.Workspace.Knives,Knife,HB}

local function CastRay(StartP,Dir)
	local ray = xz_ray(StartP,Dir*1)
	local Hit,Eend = game.Workspace:FindPartOnRayWithIgnoreList(ray,Igs)
	return Hit,Eend
end

--[[local ppp1 = MakePart()
ppp1.CanCollide = false
ppp1.Parent = game.Workspace.Debribs]]

local lastPos = HB.Position
local currentPos = HB.Position

local done = false
local killA = false

local hum

repeat
	
	lastPos = currentPos
	currentPos = HB.Position
	
	local Direction = (currentPos - lastPos).unit
	
	Knife.CFrame = Knife.CFrame*CFrame.Angles(math.pi/16,0,0)
	
	local hit1,enD1 = CastRay(HB.Position,Direction)
	local Dist1 = (HB.Position-enD1).magnitude
	
	--ppp1.Size = Vector3.new(.1,.1,Dist1)
	--ppp1.CFrame = CFrame.new(Knife.Position,enD1)*CFrame.new(0,0,Dist1/-2)
	
	print(Dist1)
	
	
	--if hit1 then
		if hit1 then
			
			if hum then
				killA = true
			end
			
			Knife.Velocity = Vector3.new(0,0,0)
			Knife.Anchored = true
			
			done = true
			
		end
	--end
	
	RS.Heartbeat:wait()
until done or not Knife or not Knife.Parent

Here’s a closer look at my code.

1 Like

Can you upload it to a place or upload a gif of it happening? It’s probably because the knife is hitting the target near the edge but since the ray is at the center of the knife it doesn’t see the target.

1 Like