Gyro not deleting

Hello. So I wanted to make this effect where if your standing still after a certain point you’ll start looking at the ball.

I’ve ran into a problem where when you start moving after staring at the part you’ll still be looking at it instead of not looking at it anymore(Deleting the BodyGyro). Please help me.

Code:

-- Variables --
local Character = script.Parent
local HumanoidRootPart = Character:WaitForChild('HumanoidRootPart')
local Humanoid = Character:WaitForChild('Humanoid')
---

-- New Main --
while true do wait()
	if Humanoid.MoveDirection == Vector3.new(0,0,0) then
		-- Make Gyro --
		wait(2)
		local BodyGyro = Instance.new('BodyGyro',HumanoidRootPart)
		BodyGyro.Name = 'BodyGyro'
		BodyGyro.MaxTorque = Vector3.new(math.huge,math.huge,math.huge)
		BodyGyro.P = 15500
		BodyGyro.D = 500
		-- Move Body --
		while true do
			BodyGyro.CFrame = CFrame.lookAt(HumanoidRootPart.Position,Vector3.new(workspace.Football.Position.X,HumanoidRootPart.Position.Y,workspace.Football.Position.Z))
			wait(0.01)
		end
	else
		if HumanoidRootPart:FindFirstChild('BodyGyro') then Humanoid:FindFirstChild('BodyGyro'):Destroy() end
	end
end
---
1 Like

Notice this?

You will never exit this loop, meaning the you will never iterate through the outer loop. Also, bodygyro as been deprecated. I’d recommend using AlignOrientation | Roblox Creator Documentation, which has support for exactly this type of thing.

Side note:
IKControl | Roblox Creator Documentation may be a good alternative to this! See below for an example on how to use it.

2 Likes

Hello! You have a lot of errors in your code. Let me help you.

This part detects when the player stops moving and waits 2 seconds but it doesn’t detect if the player has moved during the 2 seconds that elapsed.

The while loop constantly runs and there’s nothing that stops it. That means that when you destroy the body gyro with this line:

the while loop will still run and break your code.

This wait() makes the script wait to destroy the body gyro when it would be much better to destroy it right away with events.

Here’s my script:

-- Variables --
local Character = script.Parent
local HumanoidRootPart = Character:WaitForChild('HumanoidRootPart')
local Humanoid = Character:WaitForChild('Humanoid')
---

local function f()
	local BodyGyro = Instance.new('BodyGyro',HumanoidRootPart)
	BodyGyro.Name = 'BodyGyro'
	BodyGyro.MaxTorque = Vector3.new(math.huge,math.huge,math.huge)
	BodyGyro.P = 15500
	BodyGyro.D = 500
	-- Move Body --
	local debounce = true
	task.spawn(function()
		while debounce do
			BodyGyro.CFrame = CFrame.lookAt(HumanoidRootPart.Position,Vector3.new(workspace.Football.Position.X,HumanoidRootPart.Position.Y,workspace.Football.Position.Z))
			task.wait(.01)
		end
		BodyGyro:Destroy()
	end)
	Humanoid.Running:Wait()
	debounce = false
end

local debounce = false

Humanoid.Running:Connect(function(speed)
	if speed == 0 and not debounce then
		print('starting function')
		debounce = true
		local moved = false
		task.delay(2, function()
			if not moved then
				f()
			end
		end)
		Humanoid.Running:Wait()
		moved = true
		debounce = false -- debounce is like the reset button.
	end
end)

I made sure the player is still and that the function isn’t running with a debounce. Then I use task.delay() to delay the body gyro function by 2 seconds. You could also put code after task functions so I used Wait() to wait for the player to move again. If the player moves the moved variable is turned to true making no more use of the function since moved has to be equal to false so debounce is set back to false. However, if the player hasn’t moved within 2 seconds the function continues and will run until a local debounce is set to false when the player moves again. Note that the function runs twice for the first time but that shouldn’t cause any issues. If it does let me know. Oh yeah, and Align Orientation would be much better for this.

You can also use inverse kinematics for a more realistic looking effect if you want to move something else like only the head but body gyro works fine for moving the whole body.

2 Likes

Ive ran into a problem where. If they’res no ball in the workspace. It starts freezing the client with a error about exhaustion with the Humanoid.Running:Wait() In the function.

How can I fix this?

Updated Script -

-- Variables --
local HitPart = script.Parent.Parent
local HitboxFolder = HitPart.Parent
local Character = HitboxFolder.Parent
local Player = game.Players:GetPlayerFromCharacter(Character)
repeat wait() until Player and Player.CharacterAppearanceLoaded
-- Char Children --
local HumanoidRootPart = Character:WaitForChild('HumanoidRootPart')
local Humanoid = Character:WaitForChild('Humanoid')
-- Values --
local Football = nil
local CanLook = false
---

-- Functions --
function FindBall(Parent)
	for I,V in pairs(Parent:GetChildren()) do
		if V:IsA('MeshPart') and V.Name == 'Football' then
			Football = V
		else
			FindBall(V)
		end
	end
end
--
local function FaceBall(Part)
	if HitPart:GetAttribute('InStance',true) then return end
	if Humanoid.PlatformStand == true then return end
	if Character:FindFirstChild('Football') then return end
	-- Make Gyro --
	local BodyGyro = Instance.new('BodyGyro',HumanoidRootPart)
	BodyGyro.MaxTorque = Vector3.new(math.huge,math.huge,math.huge)
	BodyGyro.P = 5000
	BodyGyro.D = 500
	-- Look At Ball --
	local CanLook = true
	task.spawn(function()
		while CanLook do
			FindBall(workspace)
			if Football ~= nil then
				if Football:IsDescendantOf(workspace) then
					BodyGyro.CFrame = CFrame.lookAt(HumanoidRootPart.Position,Vector3.new(Football.Position.X,HumanoidRootPart.Position.Y,Football.Position.Z))
					task.wait(0.01)
				end
			end
		end
		BodyGyro:Destroy()
	end)
	Humanoid.Running:Wait()
	CanLook = false
end
---

-- Main --
Humanoid.Running:Connect(function(Speed)
	if Speed == 0 and not CanLook then
		CanLook = true
		local Moved = false
		task.delay(1,function()
			if not Moved then
				FaceBall()
			end
		end)
		Humanoid.Running:Wait()
		Moved = true
		CanLook = false
	end
end)
---

Problem -

This error message means that a function is calling itself infinitely. The function that’s doing this is the FindBall() function.

while CanLook do
	FindBall(workspace)
	if Football ~= nil then
		if Football:IsDescendantOf(workspace) then
			BodyGyro.CFrame = CFrame.lookAt(HumanoidRootPart.Position,Vector3.new(Football.Position.X,HumanoidRootPart.Position.Y,Football.Position.Z))
			task.wait(0.01)
		end
	end
end

Since there is no football the while loop runs the FindBall() function repeatably.

Why not use workspace:FindFirstDescendant(“Football”) instead?

Here:

-- Variables --
local HitPart = script.Parent.Parent
local HitboxFolder = HitPart.Parent
local Character = HitboxFolder.Parent
local Player = game.Players:GetPlayerFromCharacter(Character)
repeat wait() until Player and Player.CharacterAppearanceLoaded
-- Char Children --
local HumanoidRootPart = Character:WaitForChild('HumanoidRootPart')
local Humanoid = Character:WaitForChild('Humanoid')
-- Values --
local Football = nil
local CanLook = false
---

-- Functions --
local function FaceBall(Part)
	if HitPart:GetAttribute('InStance',true) then return end
	if Humanoid.PlatformStand == true then return end
	if Character:FindFirstChild('Football') then return end
	-- Make Gyro --
	local BodyGyro = Instance.new('BodyGyro',HumanoidRootPart)
	BodyGyro.MaxTorque = Vector3.new(math.huge,math.huge,math.huge)
	BodyGyro.P = 5000
	BodyGyro.D = 500
	-- Look At Ball --
	local CanLook = true
	task.spawn(function()
		while CanLook do
			if workspace:FindFirstDescendant("Football") then
				if Football:IsDescendantOf(workspace) then
					BodyGyro.CFrame = CFrame.lookAt(HumanoidRootPart.Position,Vector3.new(Football.Position.X,HumanoidRootPart.Position.Y,Football.Position.Z))
					task.wait(0.01)
				end
			else
				break
			end
		end
		BodyGyro:Destroy()
	end)
	Humanoid.Running:Wait()
	CanLook = false
end
---

-- Main --
Humanoid.Running:Connect(function(Speed)
	if Speed == 0 and not CanLook then
		CanLook = true
		local Moved = false
		task.delay(1,function()
			if not Moved then
				FaceBall()
			end
		end)
		Humanoid.Running:Wait()
		Moved = true
		CanLook = false
	end
end)
---

That happens when I remove the ball from the workspace

Oh, then I would use the same code you used.

Im trying to do something like. If there is no ball in the workspace. Then it won’t get turned on until a ball a found. If that makes sense

I think this code should work:

-- Variables --
local HitPart = script.Parent.Parent
local HitboxFolder = HitPart.Parent
local Character = HitboxFolder.Parent
local Player = game.Players:GetPlayerFromCharacter(Character)
repeat wait() until Player and Player.CharacterAppearanceLoaded
-- Char Children --
local HumanoidRootPart = Character:WaitForChild('HumanoidRootPart')
local Humanoid = Character:WaitForChild('Humanoid')
-- Values --
local Football = nil
local CanLook = false
---

-- Functions --
local function FaceBall(Part)
	if HitPart:GetAttribute('InStance',true) then return end
	if Humanoid.PlatformStand == true then return end
	if Character:FindFirstChild('Football') then return end
	-- Make Gyro --
	local BodyGyro = Instance.new('BodyGyro',HumanoidRootPart)
	BodyGyro.MaxTorque = Vector3.new(math.huge,math.huge,math.huge)
	BodyGyro.P = 5000
	BodyGyro.D = 500
	-- Look At Ball --
	local CanLook = true
	task.spawn(function()
		while CanLook do
			for i,v in pairs(workspace:GetDescendants()) do
				if v.Name == "Football" then
					Football = v
					BodyGyro.CFrame = CFrame.lookAt(HumanoidRootPart.Position,Vector3.new(Football.Position.X,HumanoidRootPart.Position.Y,Football.Position.Z))
					task.wait(0.01)
				else
					break
				end
			end
		end
		BodyGyro:Destroy()
	end)
	Humanoid.Running:Wait()
	CanLook = false
end
---

-- Main --
Humanoid.Running:Connect(function(Speed)
	if Speed == 0 and not CanLook then
		CanLook = true
		local Moved = false
		task.delay(1,function()
			if not Moved then
				FaceBall()
			end
		end)
		Humanoid.Running:Wait()
		Moved = true
		CanLook = false
	end
end)
---

I’ve tried changing the wait time on line 15 and 22 but it didn’t help.

local Character = script.Parent
local HumanoidRootPart = Character:WaitForChild(‘HumanoidRootPart’)
local Humanoid = Character:WaitForChild(‘Humanoid’)

– New Main –
local gyro = nil

local function onMoveDirectionChanged(newMoveDirection)
if newMoveDirection == Vector3.new(0, 0, 0) then
gyro = Instance.new(‘BodyGyro’, HumanoidRootPart)
gyro.Name = ‘BodyGyro’
gyro.MaxTorque = Vector3.new(math.huge, math.huge, math.huge)
gyro.P = 15500
gyro.D = 500
elseif gyro then
gyro:Destroy()
end
end

Humanoid.MoveDirectionChanged:Connect(onMoveDirectionChanged)

– Move Body –
while true do
if gyro then
gyro.CFrame = CFrame.lookAt(HumanoidRootPart.Position, Vector3.new(workspace.Football.Position.X, HumanoidRootPart.Position.Y, workspace.Football.Position.Z))
end
wait(0.01)
end