Part clipping corners in holding system

here’s the problem I’m having, when you reach the corner with the part, it continues into the floor rather than stopping at the corner.

https://gyazo.com/c1a2277da0adefaeb1bb5349846fd34e

here’s my code, I used the TargetSurface to align it with the wall, otherwise the part would be half way through the wall when you’re dragging it. I also set the targetfilter as the part you are holding.

local function align()
    if mouse.Target then
	    if mouse.TargetSurface.Name == "Top" then
	    	target.Position = mouse.Hit.Position + Vector3.new(0,target.Size.Y/2,0)
	    elseif mouse.TargetSurface.Name == "Bottom" then
		    target.Position = mouse.Hit.Position - Vector3.new(0,target.Size.Y/2,0)
	    elseif mouse.TargetSurface.Name == "Front" then
		    target.Position = mouse.Hit.Position - Vector3.new(0,0,target.Size.Z/2)
	    elseif mouse.TargetSurface.Name == "Back" then
	    	target.Position = mouse.Hit.Position + Vector3.new(0,0,target.Size.Z/2)
	    elseif mouse.TargetSurface.Name == "Right" then
	    	target.Position = mouse.Hit.Position + Vector3.new(target.Size.X/2,0,0)
	    elseif mouse.TargetSurface.Name == "Left" then
	    	target.Position = mouse.Hit.Position - Vector3.new(target.Size.X/2,0,0)
	    end
	    target.Orientation = mouse.Target.Orientation
    end
end

mouse.Move:Connect(function()
    if down == true and target ~= nil then 
    	align()
	end 
end)

Perhaps use the snapping function i just post in this question

Edit: I know its not really a solution for the particulair problem you are facing altho perhaps you might consider something like that

there isn’t really a grid. it’s gonna be a physics/puzzle game rather than actual building. here’s the sort of thing I’m looking for, where the part stops at the corner

Roblox (gyazo.com)

edit, not the placement or holding style, just the corner clipping

Oh Cool!, I recently like 10 minutes ago or something worked on my grabbing script. I faced the issue that if the player grabbed an object and hold it below its own character in third person it would send the player flying.

I tried various methods in order to calculate if the player is touching the model (beware this was a model and not a part). From raycasting to magnitude, from making the whole part collide to basically forcing the CFrame to be 1 stud above the player.

Anyway, long story I know. I don’t think i have a solution for you right away. But I imagine with raycasting you will come a whole end. I just put this here as inspiration code.

In your code you make somewhere the dragball when you move your objects. Assuming the first line is that dragball.

dragball == The blue sphere placed on the part when clicking it

local DragBall = createDragBall();

-- Since I work with models I kinda have to do this, If you are only using a part 
-- I would suggest to group that part into a model.

local pk; -- Set the primary Key
if GrabObject:IsA("Model") then -- GrabObject references the object you are lifting, in this case mouse.Target
	GrabObject.PrimaryPart = DragBall; -- Make the dragball the primary part of the model
	pk = GrabObject; -- set the PK variable to the GrabObject
elseif GrabObject.Parent:IsA("Model") then -- Same story but without `GrabObject.Parent`
	GrabObject.Parent.PrimaryPart = DragBall;
	pk = GrabObject.Parent;							
end

-- Amazing, now we made ourself an object which we can work with.
local partTouched = {}; --- Make a local list which keeps track of ontouch events
if pk ~= nil then  -- make sure the PK is not nil
        -- Time for the magic
	local descendants = pk:GetDescendants(); -- Get all descendants from the PK
	for _, descendant in pairs(descendants) do -- Iterate over them
		if descendant:IsA("Part") -- Check for all valid part options, we dont want anything else, (This is just particulair in my case... you can do it differently ofcourse)
			or descendant:IsA("UnionOperation")
			or descendant:IsA("MeshPart") 
			or descendant:IsA("TrussPart") 
			or descendant:IsA("WedgePart") 
			or descendant:IsA("CornerWedgePart") 
			or descendant:IsA("SpawnLocation")  
		then -- This block is important since it will assign the touch events
			local touchEvent = descendant.Touched:connect(function(hit) -- Make a touched event of the part in question
				if hit ~= nil and hit.Parent ~= nil and hit.Parent:FindFirstChild("Humanoid") ~= nil then -- so in my story I explained I had issues when the part was hitting my character, therefor this line, you could ignore it
					-- Next thing is to simply force the whole model a few studs higher and my problem was solved
                    pk:SetPrimaryPartCFrame(CFrame.new(Vector3.new(pk.PrimaryPart.CFrame.Position.X, pk.PrimaryPart.CFrame.Position.Y + 0.5, pk.PrimaryPart.CFrame.Position.Z)))
				end
			end)
			table.insert(partTouched, touchEvent) -- finally, lets populate that list we made
		end
	end
end

Alright, so you will now end up with a List which contains all the Touch events of each part of the model you are dragging at that moment. It’s very important after you while Dragger do loop you disconnect all those events.

if #partTouched > 0 then 
	for _, touchEvent in pairs(partTouched) do
		touchEvent:disconnect();
	end	
end

If you do this you can check for each part in the model if its hitting something, from there you could perhaps manage to force it back? You can also put invisble parts on each side of the model with a weld to the model. If one is touched raycast to the object that is touching it,… something like

-- To check whats below the object
local ray = Ray.new(Vector3.new(hit.Position.x, hit.Position.y, hit.Position.z), Vector3.new(0, -1, 0).unit * 500);
local ignoreList = {hit, player.Character};
local target, position = workspace:FindPartOnRayWithIgnoreList(ray, ignoreList); 

Its a lot of info and I don’t expect this is a straight up solution for your problem, however I hope it inspires you to find a suitable solution

1 Like