I made a tower defense unit placement. It works fine. Everything works fine but I’m attempting to create a barrier that doesnt allow units to be placed next to them. (This is so you cant place all units on top of each other) Ive gone through many different versions of this script to try and get it to work but it does not.
The main issue is the barrier doesnt change color or stop me from placing units within the barrier. This video shows the main issue: https://gyazo.com/4ed9bec601b5e9390e8214dec7914476
local gui = script.Parent
local rs = game:GetService("ReplicatedStorage")
local units = rs.Units.Units
local unitfolder = game.Workspace.TestMap.Units
local RunService = game:GetService("RunService")
local UIS = game:GetService("UserInputService")
local camera = game.Workspace.CurrentCamera
local slot1 = gui.Slot1.Main:FindFirstChildOfClass("TextButton")
local slot2 = gui.Slot2.Main:FindFirstChildOfClass("TextButton")
local slot3 = gui.Slot3.Main:FindFirstChildOfClass("TextButton")
local slot4 = gui.Slot4.Main:FindFirstChildOfClass("TextButton")
local slot5 = gui.Slot5.Main:FindFirstChildOfClass("TextButton")
local slot6 = gui.Slot6.Main:FindFirstChildOfClass("TextButton")
local unitToSpawn = nil
local canPlace = false
local isPreviewOverlapping = false
local placemode = false
local unitlimit = 4
local unitamount = 0
local previewBarrierTemplate = Instance.new("Part")
previewBarrierTemplate.Material = Enum.Material.ForceField
previewBarrierTemplate.Size = Vector3.new(2.5,2.5,2.5)
previewBarrierTemplate.CastShadow = false
previewBarrierTemplate.Shape = Enum.PartType.Cylinder
previewBarrierTemplate.CanTouch = true
previewBarrierTemplate.CanCollide = false
previewBarrierTemplate.Anchored = false
previewBarrierTemplate.Transparency = 0.5
local function placementMode()
if placemode == true then
for _, model in unitfolder:GetChildren() do
if model:IsA("Model") and model:FindFirstChild("HumanoidRootPart") then
local existingPlacedBarrier = model:FindFirstChild("Barrier")
if existingPlacedBarrier then existingPlacedBarrier:Destroy() end
local barrier1 = previewBarrierTemplate:Clone()
barrier1.Name = "Barrier"
barrier1.Parent = model
barrier1.CFrame = model.HumanoidRootPart.CFrame
barrier1.Color = Color3.fromRGB(255,0,0)
barrier1.Transparency = 0.7
local weld = Instance.new("Weld")
weld.Parent = barrier1
weld.Part0 = model.HumanoidRootPart
weld.Part1 = barrier1
weld.C0 = CFrame.new(0,0,0)
end
end
elseif placemode == false then
for _, model in unitfolder:GetChildren() do
if model:isA("Model") then
local existingBarrier = model:FindFirstChild("Barrier")
if existingBarrier and existingBarrier:IsA("BasePart") then
existingBarrier:Destroy()
end
end
end
end
end
local function MouseRaycast(blacklist)
local mousePosition = UIS:GetMouseLocation()
local mouseRay = camera:ViewportPointToRay(mousePosition.X, mousePosition.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
local function removeholder()
if unitToSpawn then
unitToSpawn:Destroy()
unitToSpawn = nil
end
end
local function unitadder(slot, name)
local existing = slot.Name
if existing == name then
placemode = true
placementMode()
removeholder()
local unitModel = units:FindFirstChild(name)
if not unitModel then
warn("Unit model not found in ReplicatedStorage:", name)
return
end
unitToSpawn = unitModel:Clone()
unitToSpawn.Parent = game.Workspace.TestMap.PlaceholderUnit
local hrp = unitToSpawn:FindFirstChild("HumanoidRootPart")
if not hrp or not hrp:IsA("BasePart") then
warn("UnitToSpawn", unitToSpawn.Name, "is missing HumanoidRootPart. Cannot add barrier.")
unitToSpawn:Destroy()
unitToSpawn = nil
return
end
local oldBarrier = unitToSpawn:FindFirstChild("Barrier")
if oldBarrier then
oldBarrier:Destroy()
end
local currentPreviewUnitBarrier = previewBarrierTemplate:Clone()
currentPreviewUnitBarrier.Name = "Barrier"
currentPreviewUnitBarrier.Parent = unitToSpawn
currentPreviewUnitBarrier.CFrame = hrp.CFrame
local weld = Instance.new("Weld")
weld.Parent = currentPreviewUnitBarrier
weld.Part0 = hrp
weld.Part1 = currentPreviewUnitBarrier
weld.C0 = CFrame.new(0, 0, 0)
for _, object in unitToSpawn:GetDescendants() do
if object:IsA("BasePart") and object.Name ~= "Barrier" then
object.CollisionGroup = "Unit"
end
end
end
end
slot1.Activated:Connect(function()
unitadder(slot1, slot1.Name)
end)
slot2.Activated:Connect(function()
unitadder(slot2, slot2.Name)
end)
slot3.Activated:Connect(function()
unitadder(slot3, slot3.Name)
end)
slot4.Activated:Connect(function()
unitadder(slot4, slot4.Name)
end)
slot5.Activated:Connect(function()
unitadder(slot5, slot5.Name)
end)
slot6.Activated:Connect(function()
unitadder(slot6, slot6.Name)
end)
UIS.InputBegan:Connect(function(input, processed)
if processed then
return
end
if unitToSpawn and input.UserInputType == Enum.UserInputType.MouseButton1 then
if unitamount < unitlimit then
if canPlace == true and not isPreviewOverlapping then
local event = rs.UnitSpawn
event:FireServer(unitToSpawn.Name, unitToSpawn:GetPivot())
removeholder()
unitamount = unitamount + 1
placemode = false
placementMode()
else
if not canPlace then
warn("Cannot place unit here: Invalid surface or target.")
elseif isPreviewOverlapping then
warn("Cannot place unit: Overlapping with another unit's barrier or a restricted area.")
end
end
else
warn("Unit limit reached. Cannot place more units.")
end
end
end)
RunService.RenderStepped:Connect(function()
if unitToSpawn then
local result = MouseRaycast({unitToSpawn})
local currentPreviewUnitBarrier = unitToSpawn:FindFirstChild("Barrier")
if result and result.Instance then
if result.Instance.Parent and result.Instance.Parent.Name == "Green" and unitamount < unitlimit then
canPlace = true
else
canPlace = false
end
local y_offset = 0
local hrp = unitToSpawn:FindFirstChild("HumanoidRootPart")
local humanoid = unitToSpawn:FindFirstChildOfClass("Humanoid")
if hrp and humanoid then
y_offset = humanoid.HipHeight + (hrp.Size.Y / 2)
elseif hrp then
y_offset = hrp.Size.Y / 2
end
local x = result.Position.X
local y = result.Position.Y + y_offset
local z = result.Position.Z
local CF = CFrame.new(x,y,z)
unitToSpawn:PivotTo(CF)
if currentPreviewUnitBarrier then
isPreviewOverlapping = false
local touchingParts = currentPreviewUnitBarrier:GetTouchingParts()
for _, part in touchingParts do
if (part.Name == "Barrier" and not part:IsDescendantOf(unitToSpawn)) or part.Name == "Path" then
isPreviewOverlapping = true
break
end
end
else
isPreviewOverlapping = true
warn("Preview unit '" .. unitToSpawn.Name .. "' is missing its Barrier part in RenderStepped!")
end
else
canPlace = false
end
if currentPreviewUnitBarrier then
if canPlace == true and not isPreviewOverlapping then
currentPreviewUnitBarrier.Color = Color3.fromRGB(0,255,0)
else
currentPreviewUnitBarrier.Color = Color3.fromRGB(255,0,0)
end
end
else
canPlace = false
isPreviewOverlapping = false
end
end)