I’m having an issue with my knife throwing system. The knife is supposed to anchor itself when it touches a block, but instead seems to anchor before it touches the block. Is there a way to fix this?
I’m using AssemblyLinearVelocity to move the part, and a function to anchor the knife as soon as it touches something that isn’t the character who threw it.
The hitbox of the knife is also exactly the size of the knife.
Thanks!
Script
local k = script.Parent
local handle = k:WaitForChild("Handle")
local ts = game:GetService("TweenService")
local throwevent = game.ReplicatedStorage.Events:WaitForChild("KnifeThrow")
local throwanim = script:WaitForChild("ThrowAnimation")
local db = 2
local isdb = false
local readytime = 0.55
throwevent.OnServerEvent:Connect(function(plr, mouseHit)
print("recieved")
local char = plr.Character
if not char or not char:FindFirstChild("Humanoid") then return end
if isdb then return end
isdb = true
char.Humanoid:LoadAnimation(throwanim):Play()
wait(readytime)
local kclone = handle:Clone()
-- kclone.Velocity = mouseHit.LookVector * 300
--kclone.AssemblyLinearVelocity = CFrame.lookAt(kclone.Position, mouseHit) * 100
--kclone.AssemblyLinearVelocity = CFrame.lookAt(kclone.Position, mouseHit) * Vector3.new(100,0,0)
kclone.CanCollide = true
kclone.Parent = workspace
handle.Transparency = 1
-- kclone.CFrame = CFrame.new(kclone.Position, mouseHit.LookVector * 300)
-- local bav = Instance.new("BodyAngularVelocity")
-- bav.MaxTorque = Vector3.new(math.huge, math.huge, math.huge)
-- bav.AngularVelocity = kclone.CFrame:VectorToWorldSpace(Vector3.new(-400,0,0))
-- bav.Parent = kclone
-- game.ReplicatedStorage.Events.KnifeThrow:FireAllClients(kclone, k.Parent)
--local tweeninfo = TweenInfo.new(.1, Enum.EasingStyle.Linear)
--local prop = {CFrame = mouseHit}
--local tween = ts:Create(kclone, tweeninfo, prop)
--tween:Play()
kclone.CFrame = CFrame.lookAt(kclone.Position, mouseHit)
kclone.AssemblyLinearVelocity = kclone.CFrame.LookVector * 200
kclone.Touched:Connect(function(touched)
if touched.Transparency < 1 and not k.Parent:IsAncestorOf(touched) then
kclone.Anchored = true
kclone.CanCollide = false
local hum = touched.Parent:FindFirstChild("Humanoid") or touched.Parent.Parent:FindFirstChild("Humanoid")
if hum then
hum.Parent:BreakJoints()
end
wait(2)
kclone:Destroy()
end
end)
wait(db - readytime)
isdb = false
handle.Transparency = 0
end)
There is a LocalScript firing the event. There is no problem with the event, just the anchoring part.
When I used tween, I got this error:
20:01:48.385 TweenService:Create property named ‘CFrame’ cannot be tweened due to type mismatch (property is a ‘CoordinateFrame’, but given type is ‘Vector3’) - Server - KnifeServer:51
Line 51 is local tween = ts:Create(kclone, tweeninfo, prop)
My new code, if you need it (it’s just the old, except the AssemblyLinearVelocity part is commented out and the tween stuff is un-commented out.
Code
local k = script.Parent
local handle = k:WaitForChild("Handle")
local ts = game:GetService("TweenService")
local throwevent = game.ReplicatedStorage.Events:WaitForChild("KnifeThrow")
local throwanim = script:WaitForChild("ThrowAnimation")
local db = 2
local isdb = false
local readytime = 0.55
throwevent.OnServerEvent:Connect(function(plr, mouseHit)
print("recieved")
local char = plr.Character
if not char or not char:FindFirstChild("Humanoid") then return end
if isdb then return end
isdb = true
char.Humanoid:LoadAnimation(throwanim):Play()
wait(readytime)
local kclone = handle:Clone()
-- kclone.Velocity = mouseHit.LookVector * 300
--kclone.AssemblyLinearVelocity = CFrame.lookAt(kclone.Position, mouseHit) * 100
--kclone.AssemblyLinearVelocity = CFrame.lookAt(kclone.Position, mouseHit) * Vector3.new(100,0,0)
kclone.CanCollide = true
kclone.Parent = workspace
handle.Transparency = 1
-- kclone.CFrame = CFrame.new(kclone.Position, mouseHit.LookVector * 300)
-- local bav = Instance.new("BodyAngularVelocity")
-- bav.MaxTorque = Vector3.new(math.huge, math.huge, math.huge)
-- bav.AngularVelocity = kclone.CFrame:VectorToWorldSpace(Vector3.new(-400,0,0))
-- bav.Parent = kclone
-- game.ReplicatedStorage.Events.KnifeThrow:FireAllClients(kclone, k.Parent)
local tweeninfo = TweenInfo.new(.1, Enum.EasingStyle.Linear)
local prop = {CFrame = mouseHit}
local tween = ts:Create(kclone, tweeninfo, prop)
tween:Play()
-- kclone.CFrame = CFrame.lookAt(kclone.Position, mouseHit)
--kclone.AssemblyLinearVelocity = kclone.CFrame.LookVector * 200
kclone.Touched:Connect(function(touched)
if touched.Transparency < 1 and not k.Parent:IsAncestorOf(touched) then
kclone.Anchored = true
kclone.CanCollide = false
local hum = touched.Parent:FindFirstChild("Humanoid") or touched.Parent.Parent:FindFirstChild("Humanoid")
if hum then
hum.Parent:BreakJoints()
end
wait(2)
kclone:Destroy()
end
end)
wait(db - readytime)
isdb = false
handle.Transparency = 0
end)
I think you should remove the {CFrame = mouseHit} and just do mouseHit to fix the error. your creating a CFrame but you also need to add the orientation if your doing so, which your just giving it the Vector3 position. I think changing it to mouseHit will fix the error.
Before, you were setting the cframe to mouseHit, which is actually a vector3. All you had to do was create a new cframe from this vector3 for it to work.
Yes it would go faster the longer the distance. You could make the length of the tween dependant on the distance between the player and mouseHit for a constant speed.
To calculate the distance between the player and the mouse cursor, you would substract the positions and find the magnitude. Then, you would make the tween length the distance divided by the speed, in studs per second. This would look like
local distance = (char.HumanoidRootPart.Position - mouseHit).Magnitude -- distance between player and mouseHit
local speed = 10 -- studs per second
local tweeninfo = TweenInfo.new(distance / speed, Enum.EasingStyle.Linear) -- tween length dependent on distance and speed
My knife system may be a little more advanced, however raycasting is how I determine hit objects while the knife is in motion. There is a ton of math involved in my system in particular, but it continuously raycasts short distances to see if it has hit something, and then stops based on that hit.
Whether you choose this route or another, I would recommend replicating the knife info to the client to handle any motion-based functions, as it would eliminate this issue:
Handle any killing or whatever on the server, but send info to each client in order to have smooth, seamless knife motion.