Tool touch not detected?

So i made this script so that if the black object is touched by the clone of knife its supposed the destroy the tool and disappear the part below it for a few seconds. But when i run it there isnt any error and nothing happens. Plus i got an infinity yield output.
Here is the video: https://gyazo.com/eb4c2c28160536b8645604b05e44811f
Here is the script (local script present in starter Gui) :

local Fall = game.Workspace.FallOff
local player = game:GetService("Players"):WaitForChild("Throwing Knife")
Popup.Touched:Connect(function(hit)
	if hit.Parent == player then
		wait(0.2)	
		Fall.Transparency = 0.4
		Fall.CanTouch = false
		Fall.CanCollide = false
		wait(2)
		Fall.Transparency = 0
		Fall.CanTouch = true
		Fall.CanCollide = true
		
	end
end)

I even made another script but too didnt work, it was under the tool

local handle = tool.Handle
local Fall = game.Workspace.FallOff

handle.Touched:Connect(function(hit)
	if hit.Name == "target1" then 
		wait(0.2)	
		Fall.Transparency = 0.4
		Fall.CanTouch = false
		Fall.CanCollide = false
		wait(2)
		Fall.Transparency = 0
		Fall.CanTouch = true
		Fall.CanCollide = true
		tool:Destroy()
	end
end)
1 Like

You need to add .LocalPlayer to this line to get the Local Player:

local player = game:GetService("Players").LocalPlayer:WaitForChild("Throwing Knife")

But even then it would throw an error because the knife wouldn’t be found.
If the player was holding the knife it would be in player.Character, if it was still in the players backpack it would be in player.Backpack but you may also need to check if the player even has a knife to begin with as the script may run before the knife has been added to the player.

its in the player not in the backpack, so i assume i use
local player = game.player.character ?

and also its a clone, when the knife is used to throw it makes a clone of itself.

The first script you say is (local script present in starter Gui)
So that is where the yield error is happening.

it looks like you are trying to get the knife instance.
so I would use
player = game:GetService(“Players”).LocalPlayer
knife = player.Character:WaitForChild(“Throwing Knife”)

then in the Touched:Connect, have the if statement
if hit.Parent == knife then

I just saw you said the knife is a clone, where do you parent the clone and what is the clone’s name?

this is where i script it

function getKnife()
	local knife = Handle:clone()
	knife.Transparency = 0
	knife.Hit.Pitch = math.random(90, 110)/100
	
	local lift = Instance.new("BodyForce")
	lift.force = Vector3.new(0, 196.2, 0) * knife:GetMass() * 0.8
	lift.Parent = knife
	
	local proj = Tool.Projectile:Clone()
	proj.Disabled = false
	proj.Parent = knife
	
	return knife
end

i get a infinite yield on it when i run

ok, this function gets you a cloned knife, but it does not say where it is parented.
where is the code that is calling this function? look there and see where you parent the clone.

This is how I would set this type of situation up.
Have the target contain a ‘server’ script that is detecting hits.
Don’t try to get player or knife or anything, just detect the hit, and look for an attribute you create… like “MissileObject”
If you get a ‘true’ value for that attribute, then the object is a thrown knife, and you can set that value to nil or delete the knife, etc…

On the ‘tool’ side, I would change the script where you make the knife clone, and add code to create an attribute called “MissileObject” on the clone and set its value to true

its under the knife present in workspace

Try doing it as I suggested above, using an attribute to detect if the target was hit by a knife.

This way it keeps the target logic and the knife logic and the player character all separate.

Target only cares if whatever hit it has the attribute
The knife only cares about ‘throwing’ itself, and setting its attribute stating it is a missile object
Nobody cares if the knife was thrown by the player or not, only the projectile script uses the player to calculate where to throw.

what type shall the attribute be? string or boolean?

I would just set it as a bool, because we really only need to know the attribute exists. If in the future you want the target to detect different thrown objects, such as it does different things if they throw a knife, or throw a ball, etc…

Then you would want to make it a string, with the text being the ‘missile type’ such as “kinfe”, “ball”
but for now I would just do…

kinfe:SetAttribute("MissileObject", true) --when cloning the knife

and in the target

local Fall = game.Workspace.FallOff
Popup.Touched:Connect(function(hit)
	if hit:GetAttribute("MissileObject") == true then
         hit:SetAttribute("MissileObject",nil)
		wait(0.2)	
		Fall.Transparency = 0.4
		Fall.CanTouch = false
		Fall.CanCollide = false
		wait(2)
		Fall.Transparency = 0
		Fall.CanTouch = true
		Fall.CanCollide = true
		hit:Destroy()
	end
end)

Using attributes you can even get fancy, and let each different missile object, handle its own ‘destruction’ by having the code on the missile object check for attribute change, so when the target sets it to nil, the missile detects this, and can play an animation, or sound, or particle effect, or even just destroy itself.
Attributes I have found are really handy.

It worked thank you so much, just that when i try to destroy i get the error parent property of workspace is locked

That means it is trying to be destroyed after it has been destroyed.
Check to see where all it is being destroyed at, probably in the projectile script of the knife, and in the target script.

Either should be ok, just not both.

Actually, I would keep the destroy in the projectile and remove the destroy under the target code, the knife really should be in charge of destroying itself, not really the target’s place to do so.

tbh i added tool:Destroy when the part is touched but it didnt do it

well, if you are doing in the ‘tool’ code, the tool is still in your hand, you really need to have it in the projectile code (which is parented to the cloned handle of the tool) so in the projectile code it would be script.Parent:Destroy() --destroying the handle instance that was cloned and thrown.

or in the target, using hit:Destroy(), destroying the ‘BasePart’ instance that was detected as hitting the target.

However… and I know this is a bit more complicated, I would have each ‘knife’ (cloned handle of the knife tool) be added to game.debris, for 5 seconds, so even if you don’t destroy it, it will be removed after 5 seconds (you would put this in the ‘getKnife’ function, where it is cloned)
Then have the projectile script, check for a hit, and when the knife hits something, it can either destroy itself, or just set transaprnecy to 1, and cancollide to false, and let the game.Debris handle its destruction after 5 seconds.