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