Tool acting as if it did not exist

I have a tool that shows a preview campfire (you may remember this from a previous post.) when you hold it and place when you click. However, after changing its parent from a GUI button (if your wondering, that was for easy access for a crafting script) to ServerStorage, any time I get my hands on it, it just pretends that it does not exist. As in it doesn’t even fire any of the events. Tool.Equipped doesn’t fire, and I know this because I have a print that should fire when Tool.Equipped fires, but it doesn’t. I already ruled out Client/Server discrepancies, because a quick check shows that the tool is inside the character when I equip it on both the client and the server. I also know it’s not just Tool.Equipped, because Tool.Activated doesn’t fire it’s print either. No errors.

Source Code: (Local Script inside tool)

player = game.Players.LocalPlayer
character = player.Character
if not character or character.Parent then
	character = player.CharacterAdded:Wait()
end
mouse = player:GetMouse()
event = game.ReplicatedStorage.BuildEvent
tool = script.Parent
equipped = false
rotation = 0
ContextActionService = game:GetService("ContextActionService")
Run = game:GetService("RunService")

Run.RenderStepped:Connect(function(step)
	rate = step
end)

tool.Equipped:Connect(function()
	print("equipped")
	equipped = true
	Item = script.Campfire:Clone()
	Item.Parent = workspace
	mouse.TargetFilter = Item
	ContextActionService:BindAction("RotatePlus", function() rotation = rotation + 15 end, true, Enum.KeyCode.Q)
	ContextActionService:BindAction("RotateMinus", function() rotation = rotation - 15 end, true, Enum.KeyCode.E)
	while equipped == true do wait(rate)
		local UnitRay = mouse.UnitRay
		local ray = Ray.new(UnitRay.Origin, UnitRay.Direction * 9999)
		local ignore = {character, Item}
		local objs = workspace:GetDescendants()
		for i = 1, #objs do
			local obj = objs[i]
			if string.sub(obj.Name, -6) == "Hitbox" then
				ignore[#ignore + 1] = obj
			end
		end
		local _, pos, _, _ = workspace:FindPartOnRayWithIgnoreList(ray, ignore)
		Item:SetPrimaryPartCFrame(CFrame.new(pos) * CFrame.Angles(0,math.rad(rotation),0))
	end
end)

tool.Unequipped:Connect(function()
	equipped = false
	ContextActionService:UnbindAction("RotatePlus")
	ContextActionService:UnbindAction("RotateMinus")
	Item:Destroy()
end)

tool.Activated:Connect(function()
	local UnitRay = mouse.UnitRay
	local ray = Ray.new(UnitRay.Origin, UnitRay.Direction * 9999)
	local ignore = {character, Item}
	local objs = workspace:GetDescendants()
	for i = 1, #objs do
		local obj = objs[i]
		if string.sub(obj.Name, -6) == "Hitbox" then
			ignore[#ignore + 1] = obj
		end
	end
	local _, pos, _, _ = workspace:FindPartOnRayWithIgnoreList(ray, ignore)
	print(pos, rotation)
	event:FireServer(pos, "Campfire", rotation)
	Item:Destroy()
	tool:Destroy()
end)

If the ServerSide part of the tool matters, here it is: (Server Script located in ServerScriptService)

event = game.ReplicatedStorage.BuildEvent
entities = game.ServerStorage.Entities

event.OnServerEvent:Connect(function(player, pos, item, rotation)
	if item == "Campfire" then
		local entity = entities.Campfire:Clone()
		entity.Parent = workspace
		entity:SetPrimaryPartCFrame(CFrame.new(pos) * CFrame.Angles(0, math.rad(rotation), 0))
		local owner = script.Owner:Clone()
		owner.Value = player
		owner.Parent = entity
	elseif item == "Corn" then
		local entity = entities.CornPlantSmall:Clone()
		entity.Parent = workspace
		entity:SetPrimaryPartCFrame(CFrame.new(pos) * CFrame.Angles(0, math.rad(rotation), 0))
		entity.GrowScript.Disabled = false
		local owner = script.Owner:Clone()
		owner.Value = player
		owner.Parent = entity
	elseif item == "FueledHeater" then
		local entity = entities.FueledHeater:Clone()
		entity.Parent = workspace
		entity:SetPrimaryPartCFrame(CFrame.new(pos) * CFrame.Angles(0, math.rad(rotation), 0))
		local owner = script.Owner:Clone()
		owner.Value = player
		owner.Parent = entity
	end
end)
1 Like

Your LocalScript will infinitely yield on line 4 because of a logical mistake on line 3.

if not character or character.Parent then -- Line 3
	character = player.CharacterAdded:Wait() -- Line 4
end

The above statement will yield until the .CharacterAdded event is fired if the Player.Character reference is nil or if the characters parent exists. Since the reference is not nil, the second condition is checked, which will always return true because you are checking if the characters parent exist, rather than if it does not. The character already exists, so the .CharacterAdded event is not fired which ultimately halts the scripts execution. What you wanted to do was:

if not character and not character.Parent then -- Line 3
	character = player.CharacterAdded:Wait() -- Line 4
end

… or even better,

local character = Player.Character or Player.CharacterAdded:Wait()
1 Like

Thing is, the local script was working just fine. It only broke after I moved the tool.

Edit: Just tested it, and that fixed it somehow? Either way, Thanks!

1 Like

My guess is that the LocalScript ran before the character had loaded in the previous location, which ultimately hid the fact there was a logical error on line 3 (since the .CharacterAdded event would be fired anyway).

Fix the logic error like I said and let me know the result.