Raycast Placement System places part inside a another part

i have a bug where i placing a part in my placement system causes it to be inside a another part. here’s the video for reference.

i can’t seem to think of any way to get this working. a person in a scripting help server told me to use RaycastResult.Normal but it bugs out. also, i’ve tried viewing this thread and i can’t seem to understand it. here’s my code

local connection

local plr = game.Players.LocalPlayer
local config = require(script.Parent:WaitForChild("Configuration"))

local cas = game:GetService("ContextActionService")

local pos
local orien

script.Parent.Equipped:Connect(function()
	connection = game.ReplicatedStorage.toolEvents.Build.BuildEventClient.Event:Connect(function()
		local part = game.ReplicatedStorage.Parts[config.currentPart]:Clone()
		local p = Instance.new("Part")
		
		while true do
			local m = plr:GetMouse()
			local surface = m.TargetSurface.Name
			
			local cam = workspace.CurrentCamera
			
			local unitRay = cam:ScreenPointToRay(m.X, m.Y)
			
			local rayParams = RaycastParams.new()
			
			rayParams.FilterDescendantsInstances = {part, p}
			
			for i,v in pairs(workspace.buildParts:GetDescendants()) do
				table.insert(rayParams.FilterDescendantsInstances, v)
			end
			
			rayParams.FilterType = Enum.RaycastFilterType.Blacklist
			
			rayParams.IgnoreWater = true
			
			task.wait()
		
			local rayResult = workspace:Raycast(unitRay.Origin, unitRay.Direction * 1000, rayParams)
			
			if rayResult then
				local grid = config.Studs
				local rayPos = CFrame.lookAt(rayResult.Position, rayResult.Position + rayResult.Normal)

				local posX = math.round(rayPos.X/grid)*grid
				local posY = math.round(rayPos.Y/grid)*grid
				local posZ = math.round(rayPos.Z/grid)*grid
				
				part.Parent = workspace
				part.Position = Vector3.new(posX, posY + 0.5, posZ) + rayResult.Normal * part.Size.Z/2
				part.Anchored = true
				
				print(rayResult.Normal)
			
				
				local function rotatePart(action, state, obj)
					if state == Enum.UserInputState.Begin then
						part.Orientation = Vector3.new(part.Orientation.X, part.Orientation.Y + config.Rotation, part.Orientation.Z)
					end
				end
				
				local function tiltPart(action, state, obj)
					if state == Enum.UserInputState.Begin then
						part.Orientation = Vector3.new(part.Orientation.X, part.Orientation.Y, part.Orientation.Z + config.Rotation)
					end
				end
				
				cas:BindAction("rotate", rotatePart, false, Enum.KeyCode.R)
				cas:BindAction("tilt", tiltPart, false, Enum.KeyCode.T)
				
				pos = part.Position
				orien = part.Orientation
			end
			
			if config.isBuilding == false then part:Destroy() break end
		end
	end)
	
	plr.PlayerGui.toolGui.Enabled = true
end)

script.Parent.Unequipped:Connect(function()
	connection:Disconnect()
	config.isBuilding = false
	
	plr.PlayerGui.toolGui.Enabled = false
end)

script.Parent.Activated:Connect(function()
	if config.isBuilding == true then
		game.ReplicatedStorage.toolEvents.Build.BuildEvent:FireServer(config.currentPart, pos, orien)
	end
end)

function translateXYZ(target, surface, part)
	if target then
		local pip = workspace:GetPartsInPart(part)
		
		if #pip >= 0 then
			if surface == "Left" then
				for i,v in pairs(pip) do
					part.Position = Vector3.new(part.Position.X + v.Size.X/2, part.Position.Y, part.Position.Z)
				end
				
				return "sucess"
			else if surface == "Right" then
					for i,v in pairs(pip) do
						part.Position = Vector3.new(part.Position.X + v.Size.X/-2, part.Position.Y, part.Position.Z)
					end
					
					return "sucess"
				end
			end
			
			if surface == "Front" then
				for i,v in pairs(pip) do
					part.Position = Vector3.new(part.Position.X, part.Position.Y, part.Position.Z + v.Size.X/-2)
				end
				
				return "sucess"
			elseif surface == "Back" then
				for i,v in pairs(pip) do
					part.Position = Vector3.new(part.Position.X, part.Position.Y, part.Position.Z + v.Size.X/-2)
				end
				
				return "sucess"
			end
			
			if surface == "Top" then
				for i,v in pairs(pip) do
					part.Position = Vector3.new(part.Position.X, part.Position.Y + v.Size.X/2, part.Position.Z)
				end
				
				return "sucess"
			elseif surface == "Bottom" then
				for i,v in pairs(pip) do
					part.Position = Vector3.new(part.Position.X, part.Position.Y + v.Size.X/-2, part.Position.Z)
				end
				
				return "sucess"
			end
		end
	end
end
1 Like

See my answer in this similar thread: Block Collisions
(there’s a code example linked)

1 Like

Couldn’t understand that but I found a solution

1 Like

Please post how you solved it, or where you found a solution so others who have the same issue can get an answer from your post.

1 Like
function translateXYZ(part, pos, surface, normal, size)
	if surface == "Left" or surface == "Right" then
		part.Position = Vector3.new(pos.X, pos.Y + 0.5, pos.Z) + normal * size.X/2
		
		return true
	end
	
	if surface == "Front" or surface == "Back" then
		part.Position = Vector3.new(pos.X, pos.Y + 0.5, pos.Z) + normal * size.Z/2
		
		return true
	end
	
	if surface == "Left" or surface == "Right" then
		part.Position = Vector3.new(pos.X, pos.Y + 0.5, pos.Z) + normal * size.X/2

		return true
	end
end

this is the solution however it’s a bit buggy when calling this function you put in the preview part in the part parameter, preview part position in the pos paramater, surface’s name for the raycastresult, normal from the raycast result and part size for the size parameter. the 0.5 is just a placeholder you can replace it with something else.

it basically positions the preview part next to the surface/side of the part you are facing

1 Like

just wrote it when you typed this message

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.