LocalScript exclusively prints "nil"?

i’m trying to fade in an “arrow” object in the workspace. it is properly named, it’s anchored, and it exists in the workspace. but for some reason it only prints nil. why is that? (i’m not using WaitForChild, because that seems to break my script.)

repeat
	task.wait()
until game:IsLoaded()

local arrow = workspace:FindFirstChild("bigGreenArrow")
local player = game:GetService("Players").LocalPlayer
local camera = workspace.CurrentCamera
local character = player.CharacterAdded:Wait()
local tweenService = game:GetService("TweenService")

local info = TweenInfo.new(0.3, Enum.EasingStyle.Circular, Enum.EasingDirection.In)
local propertyTable = {
	Transparency = 0
}
local propertyTable2 = {
	Transparency = 1
}

local function fadeIn()
	tweenService:Create(arrow, info, propertyTable):Play()
end

local function fadeOut()
	tweenService:Create(arrow, info, propertyTable2):Play()
end

camera.CameraType = Enum.CameraType.Scriptable
print("arrow:", arrow) -- why does this print nil?

game:GetService("RunService").RenderStepped:Connect(function()
	local part = workspace:FindFirstChild("Part")

	if character and part then
		camera.CFrame = part.CFrame
		local primaryPartPosition = character.PrimaryPart.Position

		-- check if the primary part is on screen
		local _, onScreen = camera:WorldToScreenPoint(primaryPartPosition)

		if arrow then
			if onScreen then
				local obstructingParts = camera:GetPartsObscuringTarget({camera.CFrame.Position, primaryPartPosition}, {part})
				if #obstructingParts == 0 then
					-- print("primary part is on screen!")
					if arrow.Transparency == 0 then
						fadeOut()
					end
				else
					-- print("primary part is on screen but obstructed by other parts.")
					if arrow.Transparency == 0 then
						fadeOut()
					end
				end
			else
				-- print("primary part is offscreen.")
				if arrow.Transparency == 1 then
					fadeIn()
				end
			end
		else
			warn("arrow not found in workspace.")
		end
	end
end)
3 Likes

wait until game:IsLoaded won’t do the job. Why don’t you use waitforchild? How will it break the script?

3 Likes

i don’t exactly know how it breaks the script, but the camera’s cframe simply won’t update or even be set to scriptable if i use WaitForChild

2 Likes

FindFirstChild find’s the first instance with the name you provided if it does NOT find the first instance it will return nil which is why you are getting nil :+1: Unlike FindFirstChild, WaitForChild Delays the script until the instance exists you can set a timeout if the instance is not found within the timeout it will quit and return nil. (Timeout counts in seconds)

3 Likes

Yep it yields and don’t procede down to the script. Wierd though it shall at least print Infinite Yield something if so?

3 Likes

Well if you tried using WaitForChild and the Cameras CFrame doesn’t update, that means the part isn’t loading. Is your part actually in the workspace or perhaps you typed the part’s name incorrectly?

3 Likes

There is a tip for loading instances though, find them using waitforchild or findfirstchild after using character = plr.Character or CharacterAdded:Wait(), after that usually most objects have loaded into workspace.

3 Likes

hows the arrow being parented into the workspace?
is it being cloned or is it there beforehand

if the arrow is being cloned or moved into the workspace after it tries to initially search for the arrow, it will always appear “nil”, even if it has been moved into the workspace

3 Likes

i have already placed it in the workspace beforehand

2 Likes

Are you sure it’s properly named? Could you try using this code and telling me what the output says?

Code:

if not game:IsLoaded() then
	game.Loaded:Wait()
end

local tweenService = game:GetService("TweenService")

local player = game:GetService("Players").LocalPlayer
local character = player.CharacterAdded:Wait()
local camera = workspace.CurrentCamera
local arrow = workspace:WaitForChild("bigGreenArrow")

local info = TweenInfo.new(0.3, Enum.EasingStyle.Circular, Enum.EasingDirection.In)
local propertyTable = {
	Transparency = 0
}
local propertyTable2 = {
	Transparency = 1
}

local function fadeIn()
	tweenService:Create(arrow, info, propertyTable):Play()
end

local function fadeOut()
	tweenService:Create(arrow, info, propertyTable2):Play()
end

camera.CameraType = Enum.CameraType.Scriptable
print("arrow:", arrow) -- why does this print nil?

game:GetService("RunService").RenderStepped:Connect(function()
	local part = workspace:FindFirstChild("Part")

	if character and part then
		camera.CFrame = part.CFrame
		local primaryPartPosition = character.PrimaryPart.Position

		-- check if the primary part is on screen
		local _, onScreen = camera:WorldToScreenPoint(primaryPartPosition)

		if arrow then
			if onScreen then
				local obstructingParts = camera:GetPartsObscuringTarget({camera.CFrame.Position, primaryPartPosition}, {part})
				if #obstructingParts == 0 then
					-- print("primary part is on screen!")
					if arrow.Transparency == 0 then
						fadeOut()
					end
				else
					-- print("primary part is on screen but obstructed by other parts.")
					if arrow.Transparency == 0 then
						fadeOut()
					end
				end
			else
				-- print("primary part is offscreen.")
				if arrow.Transparency == 1 then
					fadeIn()
				end
			end
		else
			warn("arrow not found in workspace.")
		end
	end
end)

You can also use game.Loaded:Wait()

1 Like

Check to see whether you are utilizing StreamingEnabled or not, as if the arrow is a BasePart then it will not be immediately sent to the client which may cause FindFirstChild to return nil. Try changing it to WaitForChild or disabling StreamingEnabled (depending on your use-case).

1 Like

it says “arrow: bigGreenArrow”

character limit, ignore

There’s your part! Problem Solved I guess.

1 Like

Try adding a wait:

if not game:IsLoaded() then
	game.Loaded:Wait()
end

local tweenService = game:GetService("TweenService")

local player = game:GetService("Players").LocalPlayer
local character = player.CharacterAdded:Wait()
local camera = workspace.CurrentCamera
local arrow = workspace:WaitForChild("bigGreenArrow")

local info = TweenInfo.new(0.3, Enum.EasingStyle.Circular, Enum.EasingDirection.In)
local propertyTable = {
	Transparency = 0
}
local propertyTable2 = {
	Transparency = 1
}

local function fadeIn()
	tweenService:Create(arrow, info, propertyTable):Play()
end

local function fadeOut()
	tweenService:Create(arrow, info, propertyTable2):Play()
end

task.wait(0.1)
camera.CameraType = Enum.CameraType.Scriptable
print("arrow:", arrow) -- why does this print nil?

game:GetService("RunService").RenderStepped:Connect(function()
	local part = workspace:FindFirstChild("Part")

	if character and part then
		camera.CFrame = part.CFrame
		local primaryPartPosition = character.PrimaryPart.Position

		-- check if the primary part is on screen
		local _, onScreen = camera:WorldToScreenPoint(primaryPartPosition)

		if arrow then
			if onScreen then
				local obstructingParts = camera:GetPartsObscuringTarget({camera.CFrame.Position, primaryPartPosition}, {part})
				if #obstructingParts == 0 then
					-- print("primary part is on screen!")
					if arrow.Transparency == 0 then
						fadeOut()
					end
				else
					-- print("primary part is on screen but obstructed by other parts.")
					if arrow.Transparency == 0 then
						fadeOut()
					end
				end
			else
				-- print("primary part is offscreen.")
				if arrow.Transparency == 1 then
					fadeIn()
				end
			end
		else
			warn("arrow not found in workspace.")
		end
	end
end)
1 Like

game.Loaded:Wait() and repeat task.wait() until game:IsLoaded() is essentially doing the same thing.

1 Like

I’m talking about the wait before we set the camera. Not sure how you didn’t see that since I mentioned the game.Loaded:Wait() before.

1 Like

Does same thing as the first lines from the first post.

1 Like

Hey, are you reading what I’m saying or not?

1 Like

Put your arrow statement inside the RunService loop:

-- check if the primary part is on screen
local _, onScreen = camera:WorldToScreenPoint(primaryPartPosition)
local arrow = workspace:FindFirstChild("bigGreenArrow")
print(arrow) --for testing purposes
if arrow then
	--rest of your code

Also, remove the local arrow line and the print statement from outside the RunService loop else it will interfere with this.

1 Like