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