Tower Defense X Range Mechanic

You can write your topic however you want, but you need to answer these questions:

  1. What do you want to achieve? Keep it simple and clear!
    I’m trying to make the Tower Defense X range mechanic (the circle changing if there are obstacles)

  2. What is the issue? Include screenshots / videos if possible!
    I have no idea how to achieve my goal.

  3. What solutions have you tried so far? Did you look for solutions on the Developer Hub?
    I have tried looking on the devForum and even using Ai.


-- Script for visualizing tower range (e.g., inside a Script in the Tower model)
local tower = script.Parent
local range = 10 -- Range of the tower
local rangePart = Instance.new("Part")

rangePart.Shape = Enum.PartType.Cylinder
rangePart.Size = Vector3.new(0.2, range * 2, range * 2)
rangePart.Anchored = true
rangePart.CanCollide = false
rangePart.Transparency = 0.5
rangePart.Parent = tower
rangePart.CFrame = tower.CFrame * CFrame.new(0, 0, 0) * CFrame.Angles(math.rad(90), 0, 0)


-- Script to detect enemies within range (e.g., inside a Script in the Tower model)
local tower = script.Parent
local range = 10 -- Range of the tower
local attackCooldown = 1 -- Time between attacks
local lastAttackTime = 0

local function isWithinRange(enemy)
    return (enemy.Position - tower.Position).Magnitude <= range
end

local function attack(enemy)
    if tick() - lastAttackTime >= attackCooldown then
        lastAttackTime = tick()
        -- Implement attack logic (e.g., reduce enemy health)
        print("Attacking enemy: " .. enemy.Name)
    end
end

while true do
    wait(0.1)
    for _, enemy in pairs(workspace.Enemies:GetChildren()) do
        if isWithinRange(enemy) then
            attack(enemy)
        end
    end
end


-- Example function to reduce enemy health
local function attack(enemy)
    if tick() - lastAttackTime >= attackCooldown then
        lastAttackTime = tick()
        if enemy:FindFirstChild("Health") then
            enemy.Health.Value = enemy.Health.Value - 10 -- Reduce health by 10 (example value)
            if enemy.Health.Value <= 0 then
                enemy:Destroy() -- Destroy enemy if health is 0
            end
        end
        print("Attacking enemy: " .. enemy.Name)
    end
end


-- Tower defense range mechanic script
local tower = script.Parent
local range = 10 -- Range of the tower
local attackCooldown = 1 -- Time between attacks
local lastAttackTime = 0

-- Create a range visualization part
local rangePart = Instance.new("Part")
rangePart.Shape = Enum.PartType.Cylinder
rangePart.Size = Vector3.new(0.2, range * 2, range * 2)
rangePart.Anchored = true
rangePart.CanCollide = false
rangePart.Transparency = 0.5
rangePart.Parent = tower
rangePart.CFrame = tower.CFrame * CFrame.new(0, 0, 0) * CFrame.Angles(math.rad(90), 0, 0)

local function isWithinRange(enemy)
    return (enemy.Position - tower.Position).Magnitude <= range
end

local function attack(enemy)
    if tick() - lastAttackTime >= attackCooldown then
        lastAttackTime = tick()
        if enemy:FindFirstChild("Health") then
            enemy.Health.Value = enemy.Health.Value - 10 -- Reduce health by 10 (example value)
            if enemy.Health.Value <= 0 then
                enemy:Destroy() -- Destroy enemy if health is 0
            end
        end
        print("Attacking enemy: " .. enemy.Name)
    end
end

while true do
    wait(0.1)
    for _, enemy in pairs(workspace.Enemies:GetChildren()) do
        if isWithinRange(enemy) then
            attack(enemy)
        end
    end
end