Hey!
I have made a placement system and I forgot to add a part to the system, which is a box that separates towers. What I mean is something like this:
This would be allowed:
This wouldn’t be allowed:
I have had a go at this, but since raycast only returns a single target and not multiple it is impossible to tell, I also then ran into it falling when in placing mode:
robloxapp-20220218-1406487.wmv (2.0 MB)
You may need to pay attention, but the box just falls threw everything
I did weld this. The range circle which displays how far the tower can reach is welded the same way, yet, it doesn’t have the same issue.
The code:
local RunService = game:GetService("RunService")
local UserInputService = game:GetService("UserInputService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local PhysicsService = game:GetService("PhysicsService")
local getMap = ReplicatedStorage.SelectedMap
if not getMap.Value then
getMap:GetPropertyChangedSignal("Value"):Wait()
end
local getReplicatedMap = ReplicatedStorage.Maps:FindFirstChild(tostring(getMap.Value))
if not getReplicatedMap then
error("REPLICATED MAP: "..getMap.Name.." DOES NOT EXIST")
end
local PlacementEvents = ReplicatedStorage:WaitForChild("PlacementEvents")
local PlacementEventsMain = PlacementEvents:WaitForChild("Main")
local spawnTowerEvent = PlacementEventsMain:WaitForChild("SpawnTower")
local Camera = workspace.Camera
local gui = script.Parent
local TowerToSpawn = nil
local CanPlace = false
local Rotation = 0
local Placing = false
local function MouseRaycast(blacklist)
local mousePosition = UserInputService:GetMouseLocation()
local mouseRay = Camera:ViewportPointToRay(mousePosition.X, mousePosition.Y)
local raycastParams = RaycastParams.new()
raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
raycastParams.FilterDescendantsInstances = blacklist
local raycastResult = workspace:Raycast(mouseRay.Origin, mouseRay.Direction * 1000, raycastParams)
return raycastResult
end
UserInputService.InputBegan:Connect(function(input, gameProcessed)
if gameProcessed then
return --gameProcessed means inputed in different object e.g chat
end
if TowerToSpawn then
if input.UserInputType == Enum.UserInputType.MouseButton1 then
if CanPlace then
spawnTowerEvent:FireServer(TowerToSpawn.Name, TowerToSpawn.PrimaryPart.CFrame)
RemovePlaceholderTower()
end
elseif input.KeyCode == Enum.KeyCode.R then
Rotation += 90
end
end
end)
function RemovePlaceholderTower()
if TowerToSpawn then
TowerToSpawn:Destroy()
TowerToSpawn = nil
Rotation = 0
Placing = false
end
end
local function AddPlaceHolderTower(name : string)
local towerExists = getReplicatedMap.Towers:FindFirstChild(tostring(name))
if towerExists and Placing == false then
TowerToSpawn = towerExists:Clone()
TowerToSpawn.Parent = workspace.Towers.PlacingTowers
for i, object in ipairs(TowerToSpawn:GetDescendants()) do
if object:IsA("BasePart") then
PhysicsService:SetPartCollisionGroup(object, "Tower")
end
end
Placing = true
end
end
local function ColorPlaceholderTower(color)
for i, object in ipairs(TowerToSpawn:GetDescendants()) do
if object:IsA("BasePart") and object.Name ~= "RangeBox" then
object.Color = color
end
end
if not CanPlace then
TowerToSpawn.Range.Transparency = 1
else
TowerToSpawn.Range.Transparency = 0
end
end
gui["1"].MainButton.Activated:Connect(function()
AddPlaceHolderTower("Tower")
end)
RunService.RenderStepped:Connect(function()
if TowerToSpawn then
local result = MouseRaycast({TowerToSpawn})
if result and result.Instance then
if result.Instance.Parent.Name == "TowerArea" then
CanPlace = true
ColorPlaceholderTower(Color3.new(0,1,0))
else
CanPlace = false
ColorPlaceholderTower(Color3.new(1,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)
PhysicsService:SetPartCollisionGroup(TowerToSpawn.Range,"Tower")
PhysicsService:SetPartCollisionGroup(TowerToSpawn.RangeBox,"Tower")
TowerToSpawn.Range.Size = Vector3.new(0.1, TowerToSpawn.Levels[TowerToSpawn.CurrentLevel.Value].Range.Value * 2, TowerToSpawn.Levels[TowerToSpawn.CurrentLevel.Value].Range.Value * 2)
end
end
end)