Problem with "Attempt to index nil with "

I try to fix my old project and my brain were pretty screwed from fixing this problem.

local RS = game:GetService("RunService")
local Player = game:GetService("Players").LocalPlayer

RS.RenderStepped:Connect(function()
	
	local TextLabel = script.Parent
	
	local FindChar = Player.Character or Player.CharacterAdded:Wait()
	
	if FindChar then
		
		local Humanoid = FindChar.Humanoid
		local Health = Humanoid.Health
		
		local RoundHealthVal = math.floor(Health)
		local FixedHealtVal
		
		if RoundHealthVal == nil then
			FixedHealtVal = 1
		elseif RoundHealthVal <= 1 then
			FixedHealtVal = 1
		elseif RoundHealthVal >= 1 then
			FixedHealtVal = 1
		end
		
		
		TextLabel.Text = tostring(FixedHealtVal)
		
	end
	
end)

Sorry if this was a simple problem, but i having a mind problem right now

This is where the exact problem occured on this line

		TextLabel.Text = tostring(FixedHealtVal)

Error :

2:21:26.782 Players.PowGeek.PlayerGui.Health.Health.Health:27: attempt to index nil with ‘Text’ - Studio

image

i’m still new to GUI

3 Likes

i think it errors because TextLabel didn’t load yet. try this:

repeat task.wait() until script.Parent

put this line at the beginning of the function, before you define TextLabel. i think this should work.

1 Like

I don’t think the child can exist without the parent existing first, so I never bother doing that.

2 Likes

I’d recommend just adding checks and cancelling the entire code for that RenderStepped cycle for TextLabel and FindChar variables.

So replace this

local TextLabel = script.Parent
	
local FindChar = Player.Character or Player.CharacterAdded:Wait()

with this

local TextLabel = script.Parent
if not TextLabel then return end
	
local FindChar = Player.Character
if not FindChar then return end

You also probably don’t want to wait for the player to load because RenderStepped runs every frame anyway.

2 Likes

yeah, if you’re going to wait for the TextLabel then you would turn it into a while loop. but anyway stopping the function would also work.

1 Like

i thought localscripts could load before things like TextLabels even though it’s the localscript’s parent

1 Like

This could be because FixedHealtVal was never defined when it passed the if function, add this:

else
FixedHealtVal = RoundHealthVal

(if thats what i understand)

1 Like

im pretty sure the error is because TextLabel = nil

1 Like

Sorry i thought it was the text and not the instance, i misread

1 Like

Really? I’m don’t delve into how the Studio engine actually works, but I like to imagine that everything loads in top-to-bottom fashion, and I can run script.Parent just fine.

But I just read up on the RenderStepped docs and it says that the code can execute before the environment renders, meaning that everything is loading fine and its just that RenderStepped runs the code before that happens.

I’m pretty sure my solution works since it’ll just skip the first cycle and find the TextLabel in the second.

1 Like

This work with addition i turn off the ScreenGUI.ResetOnSpawn. Even though the script is already working fine there was still error that quickly show up before it got fixed (Because of RunService rapidly), it now show Attempt to index with Character after the character has respawned back

Ignore the other problem as i mentioned old project, Focues on the Attempt to index with “Character”

I might respond tomorrow as of time right now i have to sleep (Midnight)

weird how there’s an error on an empty line ----???

Can i know what attempt to index with …something really mean? i’m quite confused

look, a TextLabel has a property called Text. nil doesn’t have a property called Text. when you write TextLabel.Text = tostring(FixedHealtVal), what you are really writing is nil.Text = tostring(FixedHealtVal), and since nil doesn’t have a Text property, and you are looking for the property ‘Text’ from nil, you are attempting to index nil with a property called Text that it doesn’t have, so it errors.

Unless you’re doing something outside this script to remove the script or something it should work just fine, I tried a new game with your exact setup. However, you could probably fix this by not making a local for the textlabel each frame. Simply move this part

local TextLabel = script.Parent

to outside the stepped loop like this

local TextLabel = script.Parent

RS.RenderStepped:Connect(function()

this way you have defined the textlabel when the script loads and even if the script is moved the textlabel variable will still point to the textlabel, no matter what.

“attempt to index nil with” simply means you’re trying to index something in nil
what you see

local variable = script:FindFirstChild("Object") -- Object doesnt exist so it returns nil
variable.Name = "hi"

but what is really going on is this

local variable = nil
nil.Name = "hi"

and since nil can’t be index, it errors

First, you have 3 useless statemetns, each statement gives the same reuslt, soo you can simply change it to:

local FixedHealthValue = 1

also what is important is that Health can’t be equal nil, which makes this statement usesless too

Second, your code is wrong, you placed constants under runService, which makes script not even bad, but lag machine! you don’t have to check if character is true, even if some strange weird error occur, local script is not required to work, as it’s not important.


-- Services related
local player = game:GetService("Players").LocalPlayer
local RunService = game:GetService("RunService")

-- Objects
local TextLabel = script.Parent
local Character = player.CharacteAdded:Wait() 

-- Change displayed health
local function OnRenderStepped()
    local Health = math.floor(Character.Humanoid.Health)
    TextLabel.Text = Health or "Player's health is 0"
end

RunService.RenderStepped:Connect(OnRenderStepped)

ExampleCode of what u try to achieve

EDIT: you really don’t have to change health every frame, you can use while loop running 4-5 times per second, players will see no difference, but game will be thankfull

-- Services related
local player = game:GetService("Players").LocalPlayer
local RunService = game:GetService("RunService")

-- Objects
local TextLabel = script.Parent
local Character = player.CharacteAdded:Wait() 

-- Change displayed health
local function UpdateHealth()
    local Health = math.floor(Character.Humanoid.Health)
    TextLabel.Text = Health or "Player's health is 0"
end

while true do
    UpdateHealth()
    task.wait(1/5)
end

Just a few changes I would make

Always try to index the character first, because if you do this when the character already loaded the script will yield until you respawn. Additionally if the gui resets on respawn it will only work if the character loads after the script.

Try avoid using loops, especially while loops as they can be exhausted and the script will break.
Instead I would use Humanoid.HealthChanged:Connect(UpdateHealth) as it only calls the update function when necessary

Oh i forget about events, still too much custom stuff when you have to use loops, also exhaustion don’t occur when there is wait statement, also local scripts can break and this is not that… important usually, but good point thx

I do believe loops can still be exhausted even if you have a wait, but I believe it only happens in case of a huge lag spike as roblox will break any loop