Weld / Physics issue

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:
image

This wouldn’t be allowed:
image

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)
1 Like

Issue is still not solved, would be great if someone helped.

1 Like

I can’t see the video any way you can use another alternative to show it?

1 Like

You need to download it then open it. You need a app, but you can just get a random app to open it.

1 Like

I am a little confused about what the issue is exactly. Do you want to detect whether the block that you are placing is obstructed?

2 Likes

I see your point, if you’ve played a tower defense game before, there is a box that stops you from packing towers to close, but when I add a box that is welded to the main part, it just falls threw everything.

1 Like

I recommend to get rid of the box and use the RotatedRegion3 module instead. This way, you can check if the tower that you are placing is obstructed without raycasts.

1 Like

Why not round the values of your placement system so the towers are placed on a grid. For example you can only place them at grid Positions (5, 0, 23) instead of (5.2, 0, 23.5).

How did you weld your placement boxes to the towers?

1 Like

I don’t think it’s generally a good idea to rely on a external module for a vital part, and, it’s unneeded re-scripting.

1 Like

A grid system is probably not good either, you need to tightly pack towers in most situations so it would pretty much get rid of it.

1 Like

Are the towers different sizes, or all the same size? If they are all the same then why wouldn’t a grid work?
If they are all 1.4 studs wide then you could make the grid 1.5 studs. They’d pack against each other, but not overlap.

2 Likes

I understand that it may sound a little scary, but I think that it is worth to consider. It is quite popular and maintained in this GitHub repository. Also, it does not require a grid.

1 Like

Towers would be different sized, and as I mentioned before, it removes the ability to tightly pack towers, so, people would just get mad and request it to be removed, putting me back into this position.

1 Like

That eliminates 1/2 of the issue. The 2nd is the re-scripting, I think I may of come up with a alternative, but if it doesn’t work, I’ll try out this.

1 Like

Well that is important information that you haven’t posted previously.
For us to help we need to know the details of what you are trying to accomplish.

You also haven’t answered

2 Likes

Turns out, I welded a test model and not the duplicating model, thanks for that, I wouldn’t of seen that if you didn’t ask lol. But now, it just ignores the box?
image

1 Like

I’m just making it so the RangeBox is collide able with each other. How would I do this? The PhysicsService:
image

How would I enable collisions?

That’s only used in game with Physics. If you are placing it with CFrames I don’t think it works.

If you were doing it physically then you would only need to have the TowerBox colliding with Default and TowerBox. Since the Tower is inside the box it doesn’t make sense to have that.

1 Like

Oh. Then how would I make it so if the tower is in the box it can’t be put there?

You can weld Parts (the tower) inside other Parts (the box).
You only need to worry about the boxes colliding, all the other Parts can be CanCollide off

1 Like