Need help with scripting dragging for a building tool

Hey all. So i have this a building tool, that can support different modes (move, clone, scale and delete) which are all in the one tool, instead of having more than one tool to build. I got the delete mode done, but now i need to work on dragging. Theres a function at line 43 which handles the dragging. but at Line 48 and line 51 in the function, are the lines that i need help with, which will be much appreciated!

heres a section of the Local Script that i need help with:

Mouse.Button1Down:Connect(function()
	if Mode.Value == 1 then
		if Mouse.Target ~= nil then
			if Mouse.Target.Locked == false then
				if Mouse.Target.Parent.ClassName == "Model" then
					-- This is the part that i can't do and need help with
				else
					if Mouse.Target:IsA("BasePart") then
						-- This is the part that i can't do and need help with
					end
				end
			end
		end
	end
end)

You need to continuously set the PrimaryPart CFrame of the model relative to the mouse position every RenderStepped, or Hearbeat if it’s a server script.

Keep doing it until MouseButton1 is no longer being pressed.

Think you could help me out with this? i’m not a very experienced scripter, but experienced enough to get this far into coding

I was planning to right out examples of pseudocode and links, but I actually found an identical topic that was already solved. If you check out the scripts in the tools in the link, you should be able to get all the information you need!

Let me know if the code in the script is not what you are looking for, or if parts of it does not make sense to you. Please do your best to make some searches first; here and on the Developer Hub (it seems better to search on google with “roblox” in the search due to the current bugs with their webpage search engine).

i’ve tried working with these, but they just won’t work the system im going for. They are also pretty complex for me.

If you can explain why they won’t work/what is too complex to understand then I can help you.

1 Like

Firstly, the script isn’t in the tool. Secondly the dragger system is way too damn hard for me to understand. Could you possibly help me create a dragger?

It’s actually very simple, if you understand a CFrame it’s essentially just a Vector3 position with rotational components.

Take the Mouse.Target and update the CFrame to the mouse’s position combined with the rotational components of the CFrame every frame or tween it if you want a more fluid movement, and add the part’s Size.Y/2 to the CFrame (to keep it on top of the object the mouse is on, rather than halfway into the ground).

If you want it to not be effected by latency, you should do this on the client every RenderStepped (while dragging a part) and only send the final position to the server (when the mouse button is no longer held down). If you want everyone to be able to see it moving before they choose the new position, then you need to do it on the server and then use Heartbeat (as your wait) for your loop.

It’s basically as simple as, if player is holding their click on a part, then update the CFrame of the part in a fast loop to the mouse’s position + the rotation of the part’s CFrame until the player is no longer holding the click.

local partsRotation = part.CFrame - part.CFrame.p
part.CFrame = partsRotation + mouse.Position + Vector3.new(0, part.Size.Y/2, 0)

You should also add a check to not move the CFrame if the mouse is not on a part (otherwise the player could place the part thousands of studs away on accident out in “space”.

2 Likes

hm, alright. ill try to see what i can do. If i run into an issue ill come back here and let you know. Thanks for your help!

1 Like

Alright so, i have somewhat a dragger. But it is nowhere near as reliable and as good as the classic dragger system. Firstly, the part being dragged doesn’t snap onto the object that the mouse is on. Secondly, It doesn’t work on models. And thirdly, when i pick up a tilted part, the orientation stays the same when dragging it (Doesn’t stay in a right angle). It also doesn’t have the Tilt and Rotate function. And as well it doesn’t have increments. Think you could help me out?

Mouse.Button1Down:Connect(function()
	if Mode.Value == 1 then
		if Mouse.Target ~= nil then
			if Mouse.Target.Locked == false then
				if Mouse.Target.Parent.ClassName == "Model" then
					-- Uncompleted part that i need help with
				else
					if Mouse.Target:IsA("BasePart") then
						if Dragging == false then
							Dragging = true
							local Part = Mouse.Target
							ObjBeingDragged = Part
							while Dragging == true do
								wait()
								if ObjBeingDragged ~= nil and Mouse.Target ~= nil then
									Part.Parent = Tool.Parent
									Part.Anchored = true
									ObjBeingDragged.CanCollide = false
									Part.Position = Mouse.Hit.p + Vector3.new(0,Part.Size.Y/2,0)
								end
							end
						end
					end
				end
			end
		end
	end
end)

Mouse.Button1Up:Connect(function()
	Dragging = false
	ObjBeingDragged.Parent = game.Workspace
	MoveObjectEvent:FireServer(ObjBeingDragged, ObjBeingDragged.Position)
	ObjBeingDragged.CanCollide = true
	ObjBeingDragged.Anchored = false
	ObjBeingDragged = nil
end)

What do you mean by “it doesn’t snap onto the object”?

For models you will have to update the position of every part, relative to the part in the model you are dragging. That or if you have a PrimaryPart for the model then you can use the :SetPrimaryPartCFrame() method to move the whole model in one line.

For increments you will need to save the first position of the part before it gets moved, and convert the new position’s x and z components to be rounded to the nearest integer based on the object space of the part’s original position. This is a 1x1 stud movement grid. To make grids for more than 1 stud, simply round to the nearest multiple of the amount of studs you want it to move (e.g. 5 studs, round to nearest multiple of 5).

To rotate and tilt the part, you need to multiply the CFrame of the part by the amount/axis you want to rotate it by. E.g.

local rotatedCFrame = CFrame.new()*CFrame.Angles(0, math.rad(90), 0) -- turns it 90 degrees, note the CFrame.Angles uses radians, so you need to use math.rad to convert degrees to radians unless you prefer to use radians

For rotating/tilting a model, all of the parts need to be rotated relative to the part of the model you are rotating, its much easier with a PrimaryPart of the model, because you can just use the :SetPrimaryPartCFrame() again to rotate it using the above line of code I just showed.

Also, I wouldn’t suggesting using wait() in that loop. I would use;

game:GetService'RunService'.RenderStepped:Wait()

Edit; If you are having trouble understanding these concepts, you should research each individually. There are tons of resources on this subject and you should not be subjecting yourself to problems that you aren’t currently equipped to solve. You should try to dissect this problem one step at a time. Your request is currently too large for me to have the time to fully help you with. You need the part/model to rotate, tilt, be draggable (with option for grid), resize (with dragging method roblox uses), and you haven’t really even started these functions. I would personally suggest starting with smaller goals;

  1. Move a part using CFrames
  2. Rotate a part using CFrames
  3. Move/Rotate a part relative to another part using CFrames
  4. Move/Rotate a part relative to another part using CFrames and locked to an increment stud amount of movement
  5. Move a part by setting it the mouse position.
  6. etc

I don’t think there are many people willing to break down every single step required to complete all the code you are trying to develop. Also, as mentioned prior, there are already people who have done these same things and posted how, and/or posted the source script(s). If you can dissect their code for what you need, and look up things you don’t understand/experiment with it, then you can learn everything you need to know. Then, when you have more specific questions about smaller portions of the code, those of us on the Developer Forum will be more than willing to help you figure that out.

If you aren’t willing to do that then I think you should consider scoping down your goals here.

2 Likes

I mean it doesn’t attach or weld onto an object. Could you also let me know if there’s anything I should consider changing or improving on my script?

Is there a reason you need it to be welded/attached? Is the part it is placed on going to be moving? Is the object not going to be anchored?

I’m making a 2008 - 2012 styled vehicle building game. Also there are no anchored parts or models that will be used for building. In other words, I just need a dragging system that is the same as the classic dragger, but can support fe

In this case I don’t see why you can’t use the building tools as a reference that I sent above. They are converted to FE by @Maximum_ADHD and they should work exactly as you are describing here. Again, if you do your best and cannot figure something out; I am more than willing to help you with that. I am just not able, at this time, to help you figure everything out.

Not sure if ive mention this already, but I just can’t work around with clonetroopers building tool script. It’s just made in a way that I cannot get my head through.

I can’t help you understand it if you aren’t willing to check it out and ask questions about parts of the code that don’t make sense. Does any of the code make any sense to you? Are there parts that do and parts that don’t? How much time did you spend checking it out? Did you look up things that you didn’t understand?

I want to help you, but I need your help to do that.

If you would like, I can/will find more resources that you can look into to understand the solution required for this system.

I did have a look at it. and i do not get 50% of the code. It uses the dragger instance and a dragger service, which i have no idea on how they work. The scripts are not in the tool (which makes it difficult to define witch tool is being used for which function is being used) And it’s buggy. I copied a few parts. and then things got weird, dragging parts would cause it to flash, and the copy tool didn’t work. I would much prefer a dragger system built from scratch.

On this topic, everything is explained. The system is 100% custom, and does everything you wanted (except resizing).

He explains placement, rotation, snapping to a surface, grid placement, saving the position in the datastore, and some other things.

You can test the code in game here.

Alright, i had a good look at it, and it did help me some what. I managed to create a better dragger, with snapping (joining surfaces) and has an increment of 1 stud. but doesn’t work correctly on walls. After that gets fixed i need to do the same for models.

Here’s a video showing what works, and what doesn’t

Almost forgot to mention that the part’s orientation resets to default (0, 0, 0) when dragging. Meaning that a rotate function won’t work.

Think you could help me with these issues?

Heres are the functions: NOTE: Not the full script, if you would like to see the full updated script, please let me know!

Mouse.Button1Down:Connect(function()
	if Mode.Value == 1 and Equipped == true then
		if Mouse.Target ~= nil then
			if Mouse.Target.Locked == false then
				SlashAnim()
				if Mouse.Target.Parent.ClassName == "Model" and Mouse.Target.Locked == false then
					-- Uncompleted part that i need help with
				else
					if Mouse.Target:IsA("BasePart") then
						if Dragging == false then
							Dragging = true
							local Part = Mouse.Target
							ObjBeingDragged = Part
							ObjBeingDragged:BreakJoints()
							StartMoveObjectEvent:FireServer(ObjBeingDragged)
							ObjBeingDragged.Parent = Tool
							
							
							local Increment = 1
							
							local function filter(number,increment)
							    number = math.floor(number)
								number = number-(number%increment)
								return number
							end
							
							while Dragging == true do
								wait()
								if ObjBeingDragged ~= nil and Mouse.Target ~= nil and Mouse.Target ~= ObjBeingDragged then
									Part.Anchored = true
									ObjBeingDragged.CanCollide = false
									Part.CFrame = CFrame.new(filter(Mouse.Hit.X,Increment),Mouse.Hit.Y + (Part.Size.Y/2),filter(Mouse.Hit.Z,Increment))
								end
							end
						end
					end
				end
			end
		end
	end
end)

function ReleaseObj()
	if ObjBeingDragged ~= nil then
		EndMoveObjectEvent:FireServer(ObjBeingDragged, ObjBeingDragged.Position, Mouse.Hit.X, Mouse.Hit.Y, Mouse.Hit.Z)
		ObjBeingDragged.Parent = game.Workspace
		ObjBeingDragged.CanCollide = true
		ObjBeingDragged = nil
		Dragging = false
	end
end

Mouse.Button1Up:Connect(function()
	if Equipped == true then
		ReleaseObj()
	end
end)

And the Server Script:

RS = game:GetService("ReplicatedStorage")
DeleteEvent = RS:WaitForChild("DeleteObjectEvent")
CloneEvent = RS:WaitForChild("CloneObjectEvent")
ScaleEvent = RS:WaitForChild("ScaleObjectEvent")
EndMoveEvent = RS:WaitForChild("EndMoveObjectEvent")
StartMoveEvent = RS:WaitForChild("StartMoveObjectEvent")
MousePosEvent = RS:WaitForChild("MousePosEvent")

DeleteEvent.OnServerEvent:Connect(function(player, Object)
	Object:Destroy()
end)

CloneEvent.OnServerEvent:Connect(function(player, Object)
	-- Uncompleted part that i need help with 
end)

ScaleEvent.OnServerEvent:Connect(function(player, Object)
	-- Uncompleted part that i need help with 
end)

MouseX = nil
MouseY = nil
MouseZ = nil

EndMoveEvent.OnServerEvent:Connect(function(player, Object, Pos, mouseX, mouseY, mouseZ)
	
	MouseX = mouseX 
	MouseY = mouseY
	MouseZ = mouseZ 
	
	if Object.Parent.ClassName == "Model" then
		-- Uncompleted part that i need help with
	else
		if Object:IsA("BasePart") then
			Object.CanCollide = true
			Object.Anchored = false
			Object.Parent = game.Workspace
			Object:BreakJoints()
			
			local Increment = 1
							
			local function filter(number,increment)
			    number = math.floor(number)
				number = number-(number%increment)
				return number
			end
			
			Object.CFrame = CFrame.new(filter(MouseX,Increment),MouseY + (Object.Size.Y/2),filter(MouseZ,Increment))
			Object:MakeJoints()
		end	
	end
end)

StartMoveEvent.OnServerEvent:Connect(function(player, Object, Pos)
	if Object.Parent.ClassName == "Model" then
		-- Uncompleted part that i need help with
	else
		if Object:IsA("BasePart") then
			Object.CanCollide = false
			Object.Anchored = true
		end	
	end
end)