Collision on Placement Script works rarely?

The title says it all. My collisions rarely works, meaning that it works but it only works if touching the corners of a cube and works rarely. I put it in a while loop, mouse.Move loop, but it does not update collisions as frequently. Additional info: I put the collision in a local script (did not write the server script); I also used lerp; and finally I used GetTouchingParts(). If you need the whole code or anything else, please ask.

--again, this was called in a while true do loop 
function CheckCollision()
	local tp = part.PrimaryPart:GetTouchingParts()
	for i,v in pairs(tp) do
		print(v)
		if v.Name == "Main" then
            --main is the name of the primary part
			print(v)
			canPlace = false
			part.PrimaryPart.BrickColor = BrickColor.Red()
			part.PrimaryPart.Transparency = 0.5
		else 
			canPlace = true
			part.PrimaryPart.BrickColor = BrickColor.Green()
			part.PrimaryPart.Transparency = 0.5		
		end
	end
end

Thanks for the help!

1 Like

yeah touched is not very reliable. There are many issues with it. Try using raycasting for detection.

Ok, can you perhaps provide me a small example.

just search up a tutorial on youtube. Its pretty basic

Quick note: GetTouchingParts() doesn’t work with non-cancollide parts, I’m pretty sure. Before going into other complex fixes check out this solution:

It works pretty well for my building system so supposedly it should work.

Before you do GetTouchingParts, you need to connect an empty .Touched to the Part, :GetTouchingParts need a TouchInterest in the part to work. So basically what I mean to fix your code is like this, probably before your while loop itself:

 local TouchedConnection = part.PrimaryPart.Touched:Connect(function() end)

And when you break your while loop, just disconnect the TouchedConnection

TouchedConnection:Disconnect()
1 Like

All of the parts have canCollide on; here is the whole script:

local mouse = player:GetMouse() 
local grid = 1
local part = game.Workspace.Part
local rotation = 0
local rotationSpeed = 45
local canPlace = false

function CalculatePosition()
	local x = math.floor(mouse.Hit.X / grid + 0.5) * grid
	--local y = math.floor(mouse.Hit.Y / grid + 0.5) * grid
	--local y = math.floor(mouse.Hit.Y + 0.5)
	local y = 4
	if y <= 4 then
		y = 4
	end
	local z = math.floor(mouse.Hit.Z / grid + 0.5) * grid
	part:SetPrimaryPartCFrame(part.PrimaryPart.CFrame:Lerp(CFrame.new(x,y,z) * CFrame.Angles(0, math.rad(rotation * rotationSpeed), 0), 0.3))
end

function RotateObject()
	rotation = rotation + 1
end

function PlaceObject()
	if canPlace == true then		
		local c = part:Clone()
		c:SetPrimaryPartCFrame(part.PrimaryPart.CFrame)
		c.Parent = game.Workspace.Obejcts
	end
end

function CheckCollision()
	local tp = part.PrimaryPart:GetTouchingParts()
	if tp then
	end
	for i,v in pairs(tp) do
		print(v)
		if v.Name == "Main" or v:IsA("Model")  then
			print(v)
			canPlace = false
			part.PrimaryPart.BrickColor = BrickColor.Red()
			part.PrimaryPart.Transparency = 0.5
		else 
			canPlace = true
			part.PrimaryPart.BrickColor = BrickColor.Green()
			part.PrimaryPart.Transparency = 0.5		
		end
	end
end

mouse.Button1Down:Connect(PlaceObject)
--function Movement()
--	CalculatePosition()
--	RotateObject()
--end
--mouse.Move:Connect(Movement)

game:GetService("UserInputService").InputBegan:Connect(function(inpObj, gp)
	if inpObj.KeyCode == Enum.KeyCode.R then
		RotateObject()
	end
end)

while true do
	wait()
	CheckCollision()
	CalculatePosition()
end

well the loop runs forever; I put it in a while true do loop

Thanks everyone for helping me! But unfortunately, your answers reduced the problem, but ultimately my collision script does not work as consistently and efficiently.

Hello, I have a placement script which i can give to you… It’s not very complex but it can be easily expanded if you plan to have additional features in your system… i have not run into any problems with GetTouchingParts() with this script

local Mouse = game:GetService("Players").LocalPlayer:GetMouse()
local Block = game.Workspace.Block -- Block is the object to be placed, change it to whatever you like in the main script
local UserInputService = game:GetService("UserInputService")
local function GetChildrenWithName (object, name)
 local table = object:GetChildren
 local results = {}
 for i,v in pairs (table) do
  if v.Name == name then 
   table.insert (results,v)
  end
 return results
local Bases = GetChildrenWithName (game.Workspace , "Base") --"Base" is the name of part on which players will place the object
Mouse.TargetFilter = game.Workspace.Block

while true do
for i, v in pairs (Bases) do
  if Mouse.Target == v then
 local GridSize =1
 local X = math.floor(Mouse.Hit.X / GridSize + 0.5) * GridSize
 local Z = math.floor(Mouse.Hit.Z / GridSize + 0.5) * GridSize
 Block.Position = Vector3.new(X,Block.Position.Y,Z)  
 local function GetTouchingParts(part) --this is needed because my script uses parts with CanCollide disabled; if you want to use it on parts with CanCollide enabled then pls skip this part
   local connection = part.Touched:Connect(function() end)
   local results = part:GetTouchingParts()
   connection:Disconnect()
   return results
end
local Collisions = GetTouchingParts(Block)
print(#Collisions)
local TouchingBounds = table.find(Collisions,game.Workspace.Bounds)
			if TouchingBounds then
				 game.Players.LocalPlayer.PlayerGui.Placer.TextLabel.Text = "Can't Place here"
				game.Players.LocalPlayer.PlayerGui.Placer.TextLabel.Visible = true
			else
				game.Players.LocalPlayer.PlayerGui.Placer.TextLabel.Visible = false
				UserInputService.InputBegan:Connect(function(input,gameprocessed)
					if input.UserInputType == Enum.UserInputType.Keyboard then
						if input.KeyCode == Enum.KeyCode.E then
							 
							game.ReplicatedStorage.PlacingEvent:FireServer(Vector3.new(Block.Position))
						end
					end
				end)
			end
 end
 end
 wait(0.01)
end

Note: I know this script is very messy; it’s because I made this in a hurry, pls understand.