Ui visible when humanoid is idle help

There’s a marker that’s suppose to be visible every time a unit is doing a action.

Attempted part of LocalScript
while true do
	wait(0.1)
	
	local hum = Unit:WaitForChild("Humanoid")
	
	if hum.MoveDirection == Vector3.new(0, 0, 0) and hum:GetState() ~= Enum.HumanoidStateType.Jumping and hum:GetState() ~= Enum.HumanoidStateType.Running and hum:GetState() ~= Enum.HumanoidStateType.Physics then
	 
		for _, track in ipairs(hum:GetPlayingAnimationTracks()) do
		   
			if track.IsPlaying then
			    IdleNotification.Visible = false
			else
			    IdleNotification.Visible = true
			end
		end
		IdleNotification.Visible = true
	end
end
Entire LocalScript
local player = game.Players.LocalPlayer
local Team = player.Team
local Frames = script.Parent
local CamBlock = workspace:WaitForChild("CamBlock")
local TroopCollection = workspace.Enviroment.Teams[Team.Name].Troops


local function createButtonForUnit(Unit)
   	local troop_button = Instance.new("ImageButton")
	troop_button.Name = "Troop_Button"
	troop_button.BorderSizePixel = 0
	troop_button.BackgroundTransparency = 1
	troop_button.Image = "rbxassetid://3270704442"
	
	local IdleNotification = Instance.new("ImageLabel",troop_button)
	IdleNotification.Name = "IdleNotification"
	IdleNotification.BorderSizePixel = 0
	IdleNotification.Position = UDim2.new(0.7,0,0,0)
	IdleNotification.Size = UDim2.new(0.4,0,0.4,0)
	IdleNotification.Image = "rbxassetid://3301006650"
	IdleNotification.BackgroundTransparency = 1
	IdleNotification.Visible = true
	
        troop_button.Parent = Frames

	troop_button.MouseButton1Click:connect(function() -- camera goes to head
		CamBlock.Position = Unit.Head.Position + Vector3.new(0,30,0)
	end)
	
	--[[while true do ATTEMPTED PART
		wait(0.1)
		
		local hum = Unit:WaitForChild("Humanoid")
		
		if hum.MoveDirection == Vector3.new(0, 0, 0) 
			and hum:GetState() ~= Enum.HumanoidStateType.Jumping and hum:GetState() ~= Enum.HumanoidStateType.Running and hum:GetState() ~= Enum.HumanoidStateType.Physics then
		 
			for _, track in ipairs(hum:GetPlayingAnimationTracks()) do
			   
				if track.IsPlaying then
					IdleNotification.Visible = false
				else
					IdleNotification.Visible = true
				end
			end
			IdleNotification.Visible = true
		end
	end--]]
	
end

local function unitDied()
   print("im G O N E")
end

TroopCollection.ChildAdded:Connect(createButtonForUnit)
TroopCollection.ChildRemoved:Connect(unitDied)

for _, Unit in pairs(TroopCollection:GetChildren()) do
    createButtonForUnit(Unit)
end

Could you break down the problem a little more? What exactly are you trying to achieve? What happens instead? :slight_smile:

1 Like

So basically, I have a dummy that attacks at trees when i click on it. I’m trying to make a ImageLabel appear near its icon when the dummy is in idle

Capture
I already have the ImageLabel setup to appear by default because the dummy is standing still when the player joins the game.

BUT the actual problem is that when i have two of them only one of the buttons will do what its told to do and the other button stops the image label from appearing.

Try putting your While loop inside spawn() to create a seperate thread, as I believe the loop at the bottom of the code will get stuck after one unit.

E.g

spawn(function()
    while true do
        -- more code
    end
end)
1 Like

Thanks man i really appreciate the help you gave me and it worked out perfectly it was just the ending of the script i had the imagelabel go straight back to visible not mattering about what action the dummy was doing.

Turned out:

Summary
  spawn(function()
	while true do
		wait()
		
		local hum = Unit:WaitForChild("Humanoid")
		
		if hum.MoveDirection == Vector3.new(0, 0, 0) and hum:GetState() ~= Enum.HumanoidStateType.Jumping and hum:GetState() ~= Enum.HumanoidStateType.Running and hum:GetState() ~= Enum.HumanoidStateType.Physics then
		 
			for _, track in ipairs(hum:GetPlayingAnimationTracks()) do
			   
				if track then
				    IdleNotification.Visible = false
				end
				
			end
		else
			IdleNotification.Visible = true
		end
	end
end)
2 Likes

Yielding at the start of an iteration is typically not a good idea. This also follows one of the pitfalls that is introduced in the While-Wait-Do Idiom. I would personally move the wait to the very bottom of the while loop.

That aside, Mario’s solution should work out for your use case. In the future you should look into coroutines as they are far more powerful than spawn. Spawns also runs on the legacy thread scheduler.

coroutine.wrap(function ()
    while condition do
        code()
    end
end)()

local actionThread = coroutine.create(function ()
    while condition do
        code()
    end
end)
coroutine.resume(actionThread)

coroutine.resume(coroutine.create(function ()
    while condition do
        code()
    end
end))
2 Likes