Tutorial code not working

hi i’m following a tutorial for a tower defense game, here’s the code:

local userInputService = game:GetService("UserInputService")
local camera = game.Workspace.CurrentCamera
local RunService = game:GetService("RunService")
local gui = script.Parent
local physicsService = game:GetService("PhysicsService")
local events = game.ReplicatedStorage:WaitForChild("Events")
local functions = game.ReplicatedStorage:WaitForChild("Functions")
local info = game.Workspace:WaitForChild("Info")

local health = require(game.ReplicatedStorage:WaitForChild("Health"))
local map = workspace.Greenland

local hoveredInstance = nil
local selectedTower = nil
local towerToSpawn = nil
local canPlace = false
local rotation = 0
local placedTowers = 0
local maxTowers = 10

-------
health.Setup(map.Base, gui.Info.Health)

workspace.Mobs.ChildAdded:Connect(function(mob)
	health.Setup(mob)
end)

info.Wave.Changed:Connect(function(change)
	gui.Info.Stats.Wave.Text = "Wave: " ..change
end)

game.Players.LocalPlayer.Money.Changed:Connect(function(change)
	gui.Info.Stats.Money.Text = game.Players.LocalPlayer.Money.Value .."$"
end)
gui.Info.Stats.Money.Text = game.Players.LocalPlayer.Money.Value .."$"
-----------


function mouseRaycast(blacklist)
	local mousePos = userInputService:GetMouseLocation()
	local mouseRay = camera:ViewportPointToRay(mousePos.X, mousePos.Y)
	local raycastParams = RaycastParams.new()
	
	raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
	raycastParams.FilterDescendantsInstances = blacklist
	
	local raycastResult = game.Workspace:Raycast(mouseRay.Origin, mouseRay.Direction * 1000, raycastParams)
	
	return raycastResult
end

function removePlaceholderTower()
	if towerToSpawn then
		towerToSpawn:Destroy()
		towerToSpawn = nil
		rotation = 0
	end
end

function addPlaceholderTower(name)
	local towerExists = game.ReplicatedStorage:WaitForChild("Towers"):FindFirstChild(name)
	if towerExists then
		removePlaceholderTower()
		towerToSpawn = towerExists:Clone()
		towerToSpawn.Parent = game.Workspace
		
		for i, object in ipairs(towerToSpawn:GetDescendants()) do
			if object:IsA("BasePart") then
				object.CollisionGroup = "Tower"
			end
		end
	end
end

function colorPlaceholderTower(color)
	for i, object in ipairs(towerToSpawn:GetDescendants()) do
		if object:IsA("BasePart") then
			object.Color = color
		end
	end
end

for i, tower in pairs(game.ReplicatedStorage:WaitForChild("Towers"):GetChildren()) do
	if tower:IsA("Model") then
		local button = gui.TowerFrame.Tower:Clone()
		local config = tower:WaitForChild("Config")
		button.Text = tower.Name
		button.Parent = script.Parent.TowerFrame
		button.Visible = true
		button.Price.Text = config.Price.Value
		button.LayoutOrder = config.Price.Value

		button.Activated:Connect(function()
			local allowedToSpawn = functions:WaitForChild("RequestTower"):InvokeServer(tower.Name)
			if allowedToSpawn then
				addPlaceholderTower(tower.Name)
			end
		end)
	end
end

function toggleUpgradeGui()
	if selectedTower then
		gui.TowerInfo.Visible = true
		local config = selectedTower.Config
		
		gui.TowerInfo.Damage.Text = config.Damage.Value
		gui.TowerInfo.Cooldown.Text = config.Cooldown.Value
		gui.TowerInfo.Range.Text = config.Range.Value
		gui.TowerInfo.TowerName.Text = selectedTower.Name
		
		local upgradeTower = config:FindFirstChild("Upgrade")
		if upgradeTower then
			gui.TowerInfo.Upgrade.Visible = true
			gui.TowerInfo.Upgrade.Text = "Upgrade: " ..upgradeTower.Value.Config.Price.Value
		else
			gui.TowerInfo.Upgrade.Visible = false
		end
	else
		gui.TowerInfo.Visible = false
	end
end

gui.TowerInfo.Upgrade.Activated:Connect(function()
	if selectedTower then
		local upgradeTower = selectedTower.Config.Upgrade.Value
		
		local allowedToUpgrade = functions:WaitForChild("RequestTower"):InvokeServer(upgradeTower.Name)
		if allowedToUpgrade then
			selectedTower = functions:WaitForChild("SpawnTower"):InvokeServer(upgradeTower.Name, selectedTower.PrimaryPart.CFrame, selectedTower)
			toggleUpgradeGui()	
		end
	end
end)

userInputService.InputBegan:Connect(function(input, processed)
	if processed then
		return
	end
	
	if towerToSpawn then
		if input.UserInputType == Enum.UserInputType.MouseButton1 then
			if canPlace then
				local placedTower = functions:WaitForChild("SpawnTower"):InvokeServer(towerToSpawn.Name, towerToSpawn.PrimaryPart.CFrame)
				if placedTower then
					placedTowers += 1
					removePlaceholderTower()
					toggleUpgradeGui()
				end
			end
		elseif input.KeyCode == Enum.KeyCode.R then
			rotation += 90
		end
		
	elseif hoveredInstance and input.UserInputType == Enum.UserInputType.MouseButton1 then
		local model = hoveredInstance:FindFirstAncestorOfClass("Model")
		
		if model and model.Parent == workspace.Towers then
			selectedTower = model
		else
			selectedTower = nil
		end
		
		toggleUpgradeGui()
	end
end)

RunService.RenderStepped:Connect(function()
	local result = mouseRaycast({towerToSpawn}) -- put stuff to ignore here
	
	if result and result.Instance then	
		if towerToSpawn ~= nil then
			hoveredInstance = nil
			
			if result.Instance.Parent.Name == "TowerArea" then
				canPlace = true
				colorPlaceholderTower(Color3.new(127,127,127))
			else
				canPlace = false
				colorPlaceholderTower(Color3.new(0.886275, 0, 0))
			end
			local x = result.Position.X
			local y = result.Position.Y + towerToSpawn.Humanoid.HipHeight + (towerToSpawn.PrimaryPart.Size.Y / 2)
			local z = result.Position.Z

			local cframe = CFrame.new(x,y,z) * CFrame.Angles(0,math.rad(rotation),0)
			towerToSpawn:SetPrimaryPartCFrame(cframe)
		else
			hoveredInstance = result.Instance
		end
	else
		hoveredInstance = nil
	end
end)

So here i’m calling the toggleUpgradeGui function:

userInputService.InputBegan:Connect(function(input, processed)
	if processed then
		return
	end
	
	if towerToSpawn then
		if input.UserInputType == Enum.UserInputType.MouseButton1 then
			if canPlace then
				local placedTower = functions:WaitForChild("SpawnTower"):InvokeServer(towerToSpawn.Name, towerToSpawn.PrimaryPart.CFrame)
				if placedTower then
					placedTowers += 1
					removePlaceholderTower()
					toggleUpgradeGui() --this is where i am calling it

but the issue is when i try to call it, there’s an if selectedTower statement, but it doesnt seem to find a selectedTower, but for him it does. I cannot find where i made a mistake so maybe someone can help here

also i dont know what to title this

Do you have EVERYTHING named the same in your scripts/models/workspace/folders etc. as the tutorial says?
Do you have EVERYTHING located in the exact same spots as the tutorial says?
Are your scripts Local or Server scripts as per the tutorial instructions?

For troubleshooting you can do print statements that give you information. For example before your if placedTower then line of code put print(placedTower) to find out what the variable is so you can see why the if statement isn’t working.