WaitForChild inside tool, Infinite yield after death

You can write your topic however you want, but you need to answer these questions:

  1. What do you want to achieve? Keep it simple and clear!
    I want the player’s arm to rotate from the tool, even after death.

  2. What is the issue? Include screenshots / videos if possible!
    The issue is that when the player dies, the script stops working because of the WaitForChild having and infinite yield possible. It works if I get the tool when spawning though.

  3. What solutions have you tried so far? Did you look for solutions on the Developer Hub?
    I have searched for a solution, and have found that checking if the player’s character is in then assign character, to ensure that the character has loaded. But that hasn’t worked.

The script that doesn’t work is below :point_down:

local UserInputService = game:GetService("UserInputService")
--local player = game.Players.LocalPlayer
local tool = script.Parent
local player = game.Players:GetPlayerFromCharacter(tool.Parent) or tool.Parent.Parent
local work = false
local RunService = game:GetService("RunService")
local Players = game:GetService("Players")
local plr = game.Players:GetPlayerFromCharacter(tool.Parent) or tool.Parent.Parent
local char = player.Character or player.CharacterAdded:Wait()
script.Parent:FindFirstChild("Emitter").ParticleEmitter.Enabled = false

print("Rotate Arm Enabled :))")


local mouse = plr:GetMouse()

--local waitbro = player.Character:WaitForChild("HumanoidRootPart")
---- Function to handle tool equipped
--local function onToolEquipped(toolEquipped)
--	tool = toolEquipped
--end

---- Function to handle tool unequipped
--local function onToolUnequipped()
--	tool = nil
--end
local YAW_MIN = math.rad(-70) -- left/right (up to +/-180)
local YAW_MAX = math.rad(70)
local PITCH_MIN = math.rad(-30) -- up/down (up to +/-90)
local PITCH_MAX = math.rad(30)

local function rotateArm()
	--print(char)
	--local character = player.CharacterAdded:Wait()
	local character = player.Character
	if not character or character.Parent ~= game.Workspace then
		character = player.CharacterAdded:Wait()
	end
	character.Humanoid.Died:Connect(function()
		print("Kill Log -- "..player.Name)
		return
	end)
	local hrp = char:WaitForChild("HumanoidRootPart") or char.HumanoidRootPart
	local rShoulder = char:WaitForChild("Torso"):WaitForChild("Right Shoulder") or char.Torso["Right Shoulder"]

	-- jointWorld is the position of C0 with the rotation of C0*C1:
	local jointWorld = rShoulder.Part0.CFrame * rShoulder.C0

	-- joint->mouse vector in "joint space"
	local dirLocal = jointWorld:PointToObjectSpace(mouse.Hit.Position)

	-- yaw or pitch of 0 means "straight in front"
	local yaw = math.atan2(-dirLocal.Z, dirLocal.X) -- left/right rotation
	local pitch = math.asin(dirLocal.Unit.Y) -- up/down rotation (use above to make a triangle with the Y axis)

	local yawClamped = math.clamp(yaw, YAW_MIN, YAW_MAX)
	local pitchClamped = math.clamp(pitch, PITCH_MIN, PITCH_MAX)

	-- note: CFrame.Angles applies rotations in Z, Y, X order
	--       CFrame.fromOrientation applies in Y, X, Z order
	rShoulder.Transform = CFrame.fromOrientation(0, yawClamped, pitchClamped + math.pi/2)
end
 --Function to handle mouse movement
local function onMouseMove(input)
	if tool and work and input.UserInputType == Enum.UserInputType.MouseMovement then
		local mouse = player:GetMouse()
		tool.Handle.CFrame = CFrame.new(tool.Handle.Rotation, mouse.Hit.Position)
	end
end

-- Function to handle mouse button down
local function onMouseButtonDown(input)
	if tool and input.UserInputType == Enum.UserInputType.MouseButton1 then
		--player.Character.HumanoidRootPart.Anchored = true
		if script.Parent.Break.Value == false and script.Parent.Thing.Value == false then
			
		script.Parent.Work.Value = true
		script.Parent:FindFirstChild("Emitter").ParticleEmitter.Enabled = true
		else
			script.Parent:FindFirstChild("Emitter").ParticleEmitter.Enabled = false
		end
	end
end

-- Function to handle mouse button up
local function onMouseButtonUp(input)
	if tool and input.UserInputType == Enum.UserInputType.MouseButton1 then
		--player.Character.HumanoidRootPart.Anchored = false
		script.Parent.Work.Value = false
		script.Parent:FindFirstChild("Emitter").ParticleEmitter.Enabled = false
	end
end

-- Connect tool equipped and unequipped events

--player.Character.ChildAdded:Connect(onToolEquipped)
--player.Character.ChildRemoved:Connect(onToolUnequipped)

-- Connect mouse events

--UserInputService.InputChanged:Connect(onMouseMove)
local steppedConn
tool.Equipped:Connect(function()
	
	print("Rotate arm equipped:connected")
	print(tool)
	script.Parent.Thing.Value = false
	steppedConn = RunService.Stepped:Connect(function()
		rotateArm(char)
		--print("Rotate arm connected")
		UserInputService.InputBegan:Connect(onMouseButtonDown)
		UserInputService.InputEnded:Connect(onMouseButtonUp)
	end)
end)
tool.Unequipped:Connect(function()
	steppedConn:Disconnect()
	steppedConn = nil
	script.Parent.Thing.Value = true
	script.Parent:WaitForChild("Work").Value = false
	print("Tool Unequipedd")
	print(script.Parent.Work.Value)
end)


tool.Destroying:Connect(function()
	steppedConn:Disconnect()
	print("i'm destroyed")	
	print(char)
end)

Let me know if you need further information. Any help is appreciated!

2 Likes

I have the same issue right now, did you manage to solve it? If so, how?

When the character dies it is replaced with a new character, so u need to get the character again.

You can use a humanoid.Died event to check when the character dies and set the variable for character to the new characterAdded once it respawns.

omg thank you so much!!!

character limit

1 Like

If it’s resolved, make sure to add the post above as a solution!