Character is nil before added to game and after. detecting character methods not working?

  1. basically whenever the players receives a tool that matches the name of the tool’s names that are in the game.ReplicatedStorage.fishstorage folder, it should then add a copy to their inventory folder which is game.ReplicatedStorage.inventory

  2. some reason the line 64 is where the problems are, and the issue is some reason the character keeps being nil and no matter how i detect the character it always comes out nil then it stops running the rest of the code?

  3. i tried using google and other search engines just for a fix even looked into forums for anything similar with the error i have and i tried requesting help from other sources and nothing. i do not know what to and i tried everything i could think of myself.


local frame = script.Parent.Frame
local Open = script.Parent.Open
local scrollingframe = frame.ScrollingFrame
local FishName = scrollingframe.TextButton
local fishicon = FishName.ImageButton
local originalPosition = fishicon.Position



local player = game.Players.LocalPlayer
local inventory = game.ReplicatedStorage.inventory
local fishstorage = game.ReplicatedStorage.fishstorage

local DS = game:GetService("DataStoreService"):GetDataStore("FishStorageDS")
local SAVE_KEY = "sdfiuw4yerhed3gsdssssss"

local numSlots = 0 -- number of slots of the tools that are added to inventory

local customToolNames = {"Blowfish", "Errorfish","Flounder","GodsCoin","Jellyfish","Rabidfish","Rockfish","Shark","Snail","Swordfish","Tuna","WormyKing","epic face fish","ur mom"} -- Add your custom tool names to this table



function updateFishingJournal()
	scrollingframe.CanvasSize = UDim2.new(0, 0, 0, (#scrollingframe:GetChildren() - 1) * 100)
	for _, child in ipairs(scrollingframe:GetChildren()) do
		if child:IsA("TextButton") then
			child:Destroy()
		end
	end
	numSlots = 0 -- reset the number of slots
	for _, fish in ipairs(inventory:GetChildren()) do
		if fish:IsA("Tool") then
			local fishName = fish.Name
			local fishModel = inventory:FindFirstChild(fishName)
			if fishModel then
				local newFish = FishName:Clone()
				newFish.Name = fishName
				newFish.Parent = scrollingframe
				newFish.Text = fishName
				newFish.Position = originalPosition -- Set position to the same as the original FishName

				-- Create the new ImageButton for the tool
				local fishIcon = fishicon:Clone()
				fishIcon.Parent = newFish
				fishIcon.Image = fishModel.TextureId
				fishIcon.Position = originalPosition

				-- ...

				numSlots = numSlots + 1 -- Increment the number of slots

				-- Adjust the position of the new slot
				local x = (numSlots - 1) % 4 -- 4 is the number of slots per row
				local y = math.floor((numSlots - 1) / 4) -- Integer division to get the row number
				newFish.Position = UDim2.new(0.1 + x * 0.2, 0, 0.1 + y * 0.25, 0) -- Adjust the position of the slot
			end
		end
	end
	scrollingframe.CanvasSize = UDim2.new(0, 0, 0, math.ceil(numSlots / 4) * 100) -- Adjust the size of the Canvas
end


local function cloneTool(tool)  --section that needs fixed to stop nil
	if tool and tool:IsA("Tool") then
		local toolName = tool.Name
		local player = game.Players.LocalPlayer
		local character = nil

		while not character do
			print("not found will not run through rest of code")
			character = player.Character
			wait()
			
		end
			print("character found code is now running")
			
			-- Code that depends on the player's character

			
			print("Found character added")
			
		local backpack = player.Character:WaitForChild("Backpack")
		if backpack then
		if not inventory:FindFirstChild(toolName) then
			
			print("trying to run the rest after local backpack")
			for _, customName in ipairs(customToolNames) do
				if string.find(toolName, customName) and fishstorage:FindFirstChild(toolName) then
					-- Check if the player has the matching tool in their backpack
					if backpack:FindFirstChild(toolName) then
						-- Add the tool to the player's inventory folder
						local toolCopy = tool:Clone()
						toolCopy.Parent = inventory
						DS:SetAsync(SAVE_KEY..toolName, true)
						print("Added tool "..toolName.." to inventory")
						updateFishingJournal()
	

					
				-- Create a new TextButton and ImageButton for the tool
				local newFish = FishName:Clone()
				newFish.Name = toolName
				newFish.Position = FishName.ImageButton.Position
				newFish.Parent = scrollingframe
				newFish.Text = toolName
				newFish.Visible = true -- Set Visible to true

				-- Create the new ImageButton for the tool
				local fishIcon = Instance.new("ImageButton")

				fishIcon.Name = "FishIcon"
				fishIcon.BackgroundTransparency = 1
				fishIcon.Size = UDim2.new(0, 45,0, 39)
				fishIcon.Position = UDim2.new(0.1, 0, 0.05, 0)
				fishIcon.Image = tool.TextureId
				fishIcon.Visible = true
				fishIcon.Position = originalPosition

				-- Set the new ImageButton as a child of the TextButton
				fishIcon.Parent = newFish

				-- Calculate the position of the new slot
				local numSlots = #scrollingframe:GetChildren() - 1 -- Subtract 1 to exclude the FishName template
				local x = numSlots % 4 -- 4 is the number of slots per row
				local y = math.floor(numSlots / 4) -- Integer division to get the row number
				newFish.Position = UDim2.new(0.1 + x * 0.2, 0, 0.1 + y * 0.25, 0) -- Adjust the position of the slot

				FishName.Visible = false  -- Set Visible to false
			end
		
			warn("Tool "..toolName.." already exists in fish storage")
						end
					end
				end
			end
		end
	end
	
	






-- Check for new tools in the player's backpack and add them to their storage folder
if player and player:IsDescendantOf(game.Players) then
	local backpack = player.Backpack
	if backpack and backpack.ChildAdded then
		backpack.ChildAdded:Connect(function(child)
			backpack.ChildAdded:Connect(function(child)
				if child:IsA("Tool") then
					if table.find(customToolNames, child.Name) and not inventory:FindFirstChild(child.Name) then
						cloneTool(child)
					end
				end
			end)

			if child:IsA("Tool") and table.find(customToolNames, child.Name) then
				local storeTool = inventory:FindFirstChild(child.Name)
				if not storeTool then
					cloneTool(child)
				end
			end
		end)
	end

	local character = player.Character or player.CharacterAdded:Wait()
	character.ChildAdded:Connect(function(child)
		if child:IsA("Tool") and table.find(customToolNames, child.Name) then
			local storeTool = inventory:FindFirstChild(child.Name)
			if not storeTool then
				cloneTool(child)
			end
		end
	end)
end

-- Check for new tools in the game's Replicated

-- Check for new tools in the player's backpack and add them to their storage folder
if player and player:IsDescendantOf(game.Players) then
	local backpack = player.Backpack
	if backpack and backpack.ChildAdded then
		backpack.ChildAdded:Connect(function(child)
			if child:IsA("Tool") and table.find(customToolNames, child.Name) then
				local storeTool = inventory:FindFirstChild(child.Name)
				if not storeTool then
					cloneTool(child)
				end
			end
		end)
	end

	local character = player.Character or player.CharacterAdded:Wait()
	character.ChildAdded:Connect(function(child)
		if child:IsA("Tool") and table.find(customToolNames, child.Name) then
			local storeTool = inventory:FindFirstChild(child.Name)
			if not storeTool then
				cloneTool(child)
			end
		end
	end)
end

-- Check for new tools in the game's ReplicatedStorage and add them to the player's storage folder
for _, tool in ipairs(game.ReplicatedStorage.fishstorage:GetChildren()) do
	if tool:IsA("Tool") and table.find(customToolNames, tool.Name) then
		local storeTool = inventory:FindFirstChild(tool.Name)
		if not storeTool then
			cloneTool(tool)
		end
	end
end

Open.MouseButton1Click:Connect(function()
	frame.Visible = not frame.Visible
	
end)

Hey !

I also recently encountered this “problem” while programming some things, and i finaly found a good solution which is to create nil variables at the top of the script, that will be used to reference the character itself and other things i need inside it.

So using a Player.CharacterAdded or Tool.Equiped function, i’m just getting the new character and things, then update the top Character variables.
By doing this, you don’t need to search the player character in each functions anymore.

Also, i see in your script you are creating a player variable multiple time, which is useless.

Here is an example using a local script in Player Script:

local PlayerService = game:GetService("Players")

local Player = PlayerService.LocalPlayer

local Character = nil
local Root = nil
local Humanoid = nil

local function Example()
	if Root then
		Root.CFrame = CFrame.new(0,0,0)
	end
end

local function GetCharacter(NewCharacter)
	local NewRoot = NewCharacter:WaitForChild("HumanoidRootPart",3)
	local NewHumanoid =  NewCharacter:WaitForChild("Humanoid",3)

	if NewRoot and NewHumanoid then
		Character = NewCharacter
		Root = NewRoot
		Humanoid = NewHumanoid
	end
end

Player.CharacterAdded:Connect(GetCharacter)

Here is an example using any script in a Tool

local Tool = script.Parent

local Character = nil
local Root = nil
local Humanoid = nil

local function Example()
	if Root then
		Root.CFrame = CFrame.new(0,0,0)
	end
end

local function GetCharacter()
	local NewCharacter = Tool.Parent
	local NewRoot = NewCharacter:WaitForChild("HumanoidRootPart",3)
	local NewHumanoid =  NewCharacter:WaitForChild("Humanoid",3)

	if NewRoot and NewHumanoid then
		Character = NewCharacter
		Root = NewRoot
		Humanoid = NewHumanoid
	end
end

Tool.Equipped:Connect(GetCharacter)

i got that part fixed. but now here’s another issue.

the local backpack = player:WaitForChild(“Backpack”) is becoming nil now just like the player was but the same method i tried didn’t work.

i marked where issue is it’s at line 63 through 106. that section is where the problem is

local frame = script.Parent.Frame
local Open = script.Parent.Open
local scrollingframe = frame.ScrollingFrame
local FishName = scrollingframe.TextButton
local fishicon = FishName.ImageButton
local originalPosition = fishicon.Position



local player = game.Players.LocalPlayer
local inventory = game.ReplicatedStorage.inventory
local fishstorage = game.ReplicatedStorage.fishstorage

local DS = game:GetService("DataStoreService"):GetDataStore("FishStorageDS")
local SAVE_KEY = "sdfiuw4yerhed3gsdssssss"

local numSlots = 0 -- number of slots of the tools that are added to inventory

local customToolNames = {"Blowfish", "Errorfish","Flounder","GodsCoin","Jellyfish","Rabidfish","Rockfish","Shark","Snail","Swordfish","Tuna","WormyKing","epic face fish","ur mom"} -- Add your custom tool names to this table



function updateFishingJournal()
	scrollingframe.CanvasSize = UDim2.new(0, 0, 0, (#scrollingframe:GetChildren() - 1) * 100)
	for _, child in ipairs(scrollingframe:GetChildren()) do
		if child:IsA("TextButton") then
			child:Destroy()
		end
	end
	numSlots = 0 -- reset the number of slots
	for _, fish in ipairs(inventory:GetChildren()) do
		if fish:IsA("Tool") then
			local fishName = fish.Name
			local fishModel = inventory:FindFirstChild(fishName)
			if fishModel then
				local newFish = FishName:Clone()
				newFish.Name = fishName
				newFish.Parent = scrollingframe
				newFish.Text = fishName
				newFish.Position = originalPosition -- Set position to the same as the original FishName

				-- Create the new ImageButton for the tool
				local fishIcon = fishicon:Clone()
				fishIcon.Parent = newFish
				fishIcon.Image = fishModel.TextureId
				fishIcon.Position = originalPosition

				-- ...

				numSlots = numSlots + 1 -- Increment the number of slots

				-- Adjust the position of the new slot
				local x = (numSlots - 1) % 4 -- 4 is the number of slots per row
				local y = math.floor((numSlots - 1) / 4) -- Integer division to get the row number
				newFish.Position = UDim2.new(0.1 + x * 0.2, 0, 0.1 + y * 0.25, 0) -- Adjust the position of the slot
			end
		end
	end
	scrollingframe.CanvasSize = UDim2.new(0, 0, 0, math.ceil(numSlots / 4) * 100) -- Adjust the size of the Canvas
end


local function cloneTool(tool)  --section that needs fixed to stop nil
	if tool and tool:IsA("Tool") then
		local toolName = tool.Name
		local player = game.Players.LocalPlayer
		local character = nil

		if character then
			print("character nil and not found will not run through rest of code")
			character = player.Character
		
			
			wait()

		end
		print("character found code is now running")

		-- Code that depends on the player's character


		print("Found character added")
		
		local backpack = player:WaitForChild("Backpack")
		
		if backpack then
			print("backpack went nil trying to find...")
			backpack = player.Backpack
			
			end
		
		if backpack then
			print("found backpack code is running..")
			if not inventory:FindFirstChild(toolName) then

				print("trying to run the rest after local backpack")
				for _, customName in ipairs(customToolNames) do
					if string.find(toolName, customName) and fishstorage:FindFirstChild(toolName) then
						-- Check if the player has the matching tool in their backpack
						if backpack:FindFirstChild(toolName) then
							-- Add the tool to the player's inventory folder
							local toolCopy = tool:Clone()
							toolCopy.Parent = inventory
							DS:SetAsync(SAVE_KEY..toolName, true)
							print("Added tool "..toolName.." to inventory")
							updateFishingJournal()



							-- Create a new TextButton and ImageButton for the tool
							local newFish = FishName:Clone()
							newFish.Name = toolName
							newFish.Position = FishName.ImageButton.Position
							newFish.Parent = scrollingframe
							newFish.Text = toolName
							newFish.Visible = true -- Set Visible to true

							-- Create the new ImageButton for the tool
							local fishIcon = Instance.new("ImageButton")

							fishIcon.Name = "FishIcon"
							fishIcon.BackgroundTransparency = 1
							fishIcon.Size = UDim2.new(0, 45,0, 39)
							fishIcon.Position = UDim2.new(0.1, 0, 0.05, 0)
							fishIcon.Image = tool.TextureId
							fishIcon.Visible = true
							fishIcon.Position = originalPosition

							-- Set the new ImageButton as a child of the TextButton
							fishIcon.Parent = newFish

							-- Calculate the position of the new slot
							local numSlots = #scrollingframe:GetChildren() - 1 -- Subtract 1 to exclude the FishName template
							local x = numSlots % 4 -- 4 is the number of slots per row
							local y = math.floor(numSlots / 4) -- Integer division to get the row number
							newFish.Position = UDim2.new(0.1 + x * 0.2, 0, 0.1 + y * 0.25, 0) -- Adjust the position of the slot

							FishName.Visible = false  -- Set Visible to false
						end

						warn("Tool "..toolName.." already exists in fish storage")
					end
				end
			end
		end
	end
end








-- Check for new tools in the player's backpack and add them to their storage folder
if player and player:IsDescendantOf(game.Players) then
	local backpack = player.Backpack
	if backpack and backpack.ChildAdded then
		backpack.ChildAdded:Connect(function(child)
			backpack.ChildAdded:Connect(function(child)
				if child:IsA("Tool") then
					if table.find(customToolNames, child.Name) and not inventory:FindFirstChild(child.Name) then
						cloneTool(child)
					end
				end
			end)

			if child:IsA("Tool") and table.find(customToolNames, child.Name) then
				local storeTool = inventory:FindFirstChild(child.Name)
				if not storeTool then
					cloneTool(child)
				end
			end
		end)
	end

	local character = player.Character or player.CharacterAdded:Wait()
	character.ChildAdded:Connect(function(child)
		if child:IsA("Tool") and table.find(customToolNames, child.Name) then
			local storeTool = inventory:FindFirstChild(child.Name)
			if not storeTool then
				cloneTool(child)
			end
		end
	end)
end

-- Check for new tools in the game's Replicated

-- Check for new tools in the player's backpack and add them to their storage folder
if player and player:IsDescendantOf(game.Players) then
	local backpack = player.Backpack
	if backpack and backpack.ChildAdded then
		backpack.ChildAdded:Connect(function(child)
			if child:IsA("Tool") and table.find(customToolNames, child.Name) then
				local storeTool = inventory:FindFirstChild(child.Name)
				if not storeTool then
					cloneTool(child)
				end
			end
		end)
	end

	local character = player.Character or player.CharacterAdded:Wait()
	character.ChildAdded:Connect(function(child)
		if child:IsA("Tool") and table.find(customToolNames, child.Name) then
			local storeTool = inventory:FindFirstChild(child.Name)
			if not storeTool then
				cloneTool(child)
			end
		end
	end)
end

-- Check for new tools in the game's ReplicatedStorage and add them to the player's storage folder
for _, tool in ipairs(game.ReplicatedStorage.fishstorage:GetChildren()) do
	if tool:IsA("Tool") and table.find(customToolNames, tool.Name) then
		local storeTool = inventory:FindFirstChild(tool.Name)
		if not storeTool then
			cloneTool(tool)
		end
	end
end

Open.MouseButton1Click:Connect(function()
	frame.Visible = not frame.Visible

end)

i got it now, the problem to find the players backpack was because the way it was trying to find the players backpack was coded bad lol it wasn’t locating the backpack in the first place so no matter what i did regardless it would always turn nil

Did you tried to do it like this ?
Also, don’t forget to do a check (if Backpack then) in your other functions to avoid doing things when the object is nil.

local PlayerService = game:GetService("Players")

local Tool = script.Parent

local Player = nil
local Backpack = nil

local Character = nil
local Root = nil
local Humanoid = nil

local function GetCharacter()
	local NewCharacter = Tool.Parent	
	local NewRoot = NewCharacter and NewCharacter:WaitForChild("HumanoidRootPart",3)
	local NewHumanoid =  NewCharacter and NewCharacter:WaitForChild("Humanoid",3)
	
	local NewPlayer = PlayerService:FindFirstChild(NewCharacter.Name)
	local NewBackpack = NewPlayer and NewPlayer:WaitForChild("Backpack",3)
	
	if NewRoot and NewHumanoid then
		Character = NewCharacter
		Root = NewRoot
		Humanoid = NewHumanoid
	end
	
	if NewBackpack then
		Player = NewPlayer
		Backpack = NewBackpack
	end
end

Tool.Equipped:Connect(GetCharacter)