How to make a part move at an increment

Hey developers,

Today I’m really just experimenting so its not very important if you dont know how to make it work. :slight_smile:

I’m trying to make a VERY simple “placement system” that won’t be used long term, just trying to get a grasp on how it would work. I’m not an amazing programmer, I’m also not the worlds worst, but I genuinely have no clue how to make this code follow the increment… If you know how to help, thanks! If not, thank you for reading. :slight_smile:

My Code (Local, obviously | non FE):

local plr = game.Players.LocalPlayer
local mouse = plr:GetMouse()
local increment = 1

local part = Instance.new('Part', workspace)
part.Anchored = true
while wait() do
	if mouse.Target ~= part then -- to avoid the part coming torwards itself, cause idk how to make it not..
		part.CFrame = mouse.Hit -- this moves in no increment
	end
end

I want to use the “increment” variable, it isnt there for no reason. :slight_smile:
Thank you!

2 Likes

There are quite a few ways to make it increment, but i’ll just list one thats probably pretty easy.

You can use math.floor to make an increment.

part.CFrame = CFrame.new(math.floor(mouse.Hit.X),math.floor(mouse.Hit.Y),math.floor(mouse.Hit.Z))
2 Likes

Would I have to add increment to math.floor(mouse.Hit.X)?

Like have the variable affect it? Something like this would work if you want a variable to control the increment.

part.CFrame = CFrame.new(math.floor(math.floor(mouse.Hit.X)/increment),math.floor(math.floor(mouse.Hit.Y)/increment),math.floor(math.floor(mouse.Hit.Z)/increment))

Thank you! Helps alot! :slight_smile:

I’d recommend setting the Mouse TargetFilter to the part - that’d fix your issue with the part coming towards itself.

1 Like

Actually, that didnt quite work, that made the block go 2 studs behind my mouse, aswell at it still moves in one stud increments.

My code:

local plr = game.Players.LocalPlayer
local mouse = plr:GetMouse()
local increment = 2

local part = Instance.new('Part', workspace)
part.Anchored = true
while wait() do
	part.CFrame = CFrame.new(math.floor(math.floor(mouse.Hit.X)/increment),math.floor(math.floor(mouse.Hit.Y)/increment),math.floor(math.floor(mouse.Hit.Z)/increment))
end

What I’d recommend you do is populate a grid of values, and then try and figure out which grid point your mouse is closest to. It’s probably the safest way to do it.

local function filter(number,increment)
    number = math.floor(number)
	number = number-(number%increment)
	return number
end
--in the loop
part.CFrame = CFrame.new(filter(mouse.Hit.X,increment),filter(mouse.Hit.Y,increment),filter(mouse.Hit.Z,increment))

Nope, gave this error,

Players.wayIxn.PlayerScripts.LocalScript:10: attempt to perform arithmetic on local ‘increment’ (a nil value)

local plr = game.Players.LocalPlayer
local mouse = plr:GetMouse()
local increment = 2

local part = Instance.new('Part', workspace)
mouse.TargetFilter = part
part.Anchored = true
local function filter(number,increment)
    number = math.floor(number)
	number = number-(number%increment)
	return number
end
--in the loop

while wait() do
	part.CFrame = CFrame.new(filter(mouse.Hit.X,increment),filter(mouse.Hit.Y),filter(mouse.Hit.Z))
end

Gonna be honest here I’m absolutely horrible with math so I really have no clue how to do that. :stuck_out_tongue:

Try this place I created, it makes use of the methods provided in this thread:

Placement.rbxl (15.0 KB)

I also don’t quite understand placement systems :stuck_out_tongue: but this place file works as intended except where the part stays within the bounds of the plot.

5 Likes

I’ll take a look at it! This thread was moreso on how to understand it, but I’ll try to see what I can learn out of it! :slight_smile:

1 Like

Wow! This actually did help alot! :slight_smile: Thank you so much!

I updated the OnMove function to only show the part when the mouse if pointed over the top of the plot, this is to avoid the part going lower than the plot surface when the side is pointed, just change the function to this:

local function OnMove()
	if Mouse.Target then
		if Mouse.Target == Platform and Mouse.TargetSurface == Enum.NormalId.Top then
			Part.Parent = WorkspaceService
			Part.CFrame = CFrame.new(filter(Mouse.Hit.X,Increment),Mouse.Hit.Y + (Part.Size.Y/2),filter(Mouse.Hit.Z,Increment))
		else
			Part.Parent = nil
		end
	end
end
1 Like

The script is done!

If anyone needs a very simple, not efficient for big games (w/o alot of editing) placement script here it is!

local PlayersService = game:GetService("Players")
local WorkspaceService = game:GetService("Workspace")

local Player = PlayersService.LocalPlayer
local Mouse = Player:GetMouse()
local Part = Instance.new("Part")
local Platform = WorkspaceService:WaitForChild("Plot")

local Increment = 1

--Setup
Mouse.TargetFilter = Part
Part.Anchored = true
Part.CanCollide = false
Part.Transparency = 0.5
Part.Name = 'HitPart'

local function filter(number,increment)
    number = math.floor(number)
	number = number-(number%increment)
	return number
end

local function OnMove()
	if Mouse.Target then
		if Mouse.Target == Platform and Mouse.TargetSurface == Enum.NormalId.Top then
			Part.Parent = WorkspaceService
			Part.CFrame = CFrame.new(filter(Mouse.Hit.X,Increment),Mouse.Hit.Y + (Part.Size.Y/2),filter(Mouse.Hit.Z,Increment))
		else
			Part.Parent = nil
		end
	end
end

Mouse.Button1Down:Connect(function()
	if workspace:FindFirstChild('HitPart') then
		local part = Instance.new('Part', workspace)
		part.Anchored = true
		part.CFrame = Part.CFrame
	end
end)
Mouse.Move:Connect(OnMove)

This will require ALOT of editing

Sorry, didnt mean to reply to you, wevetments!

Hey dude, I have a better solution, year ago I was searching for such a thing and I found a simple mathematical function

local function round(number, factor)
     return math.floor(number/factor + 0.5)*factor
end

and so you can round the mouse hit position components and set it to your part’s position, factor is the grid step or increment

4 Likes

This works too, but I’ll be using what I currently have. Thank you for your contribution! :slight_smile:

1 Like

Just a little tip on performance, When making or cloning new elements, make sure to apply the changes that you want before setting it’s parent, because changing rendered elements properties cost more performance, according to a Roblox article !
And since it’s a building system, you don’t know how much the player will put in from parts, and this is a good step towards optimizing it!
But i think you’re just testing, but either way have a good day !

OP isn’t cloning anything though and realistically you don’t need to set the properties of parts of pre-assembled structures unless you’re modifying them pre-placement (e.g. a ghosting effect to outline where the desired placement position is).

As well, in this case, it’s necessary to set properties after the assembly is attached to the DataModel since it’s a placement system. That is, in terms of positioning.

1 Like