So I have a 100 by 100 part, which I want people to be able to place things on. I want it so I can create a grid so the block that is moving around would match the parts edges.
local plr = game.Players.LocalPlayer
local mouse = plr:GetMouse()
local block = game.Workspace.Block
local TweenService = game:GetService("TweenService")
mouse.Move:Connect(function()
if mouse.Target == game.Workspace.Part then
local goal = {}
goal.Position = Vector3.new(math.floor(mouse.hit.Position.X),1.5,math.floor(mouse.hit.Position.Z))
local tweenInfo = TweenInfo.new(.1)
local tween = TweenService:Create(block, tweenInfo, goal)
tween:Play()
end
end)
I tried to do that, but the edges don’t match up with the block. How can I make it so they will?
I’m assuming what you mean is when you’re attempting to create a part, it doesn’t line up like so:
Please correct me if I’m wrong.
I’ve taken your code and tried it out on a baseplate world, and I can see that the object doesn’t line up, and instead is off by a couple pixels. Can you make sure that your 100 by 100 block that people can place objects on is perfectly aligned to the stud grid?
If that doesn’t work, you can try replacing goal.Position = Vector3.new(...) in your code with this:
local Y_OFFSET = 1.5
local PLACEMENT_OFFSET = 0
local relativePosition = Vector3.new(mouse.hit.Position.X,0,mouse.hit.Position.Z) - workspace.Part.Position
relativePosition = Vector3.new(math.floor(relativePosition.X), Y_OFFSET, math.floor(relativePosition.Z))
goal.Position = workspace.Part.Position + relativePosition + Vector3.new(PLACEMENT_OFFSET, 0, PLACEMENT_OFFSET)
Allow me to explain To make this easier, I’ll be calling the part you want to place furniture and the part that you’re placing it on ground.
This script first gets the position of the furniture relative to the ground. Using that value we can then round and not be screwed over by the world grid.Then, we take that value and add it back onto the ground in order to get the offset position, and add on PLACEMENT_OFFSET in case we want to change it later.
Y_OFFSET is how far you want the object to be from your 100 by 100 part in the Y axis. If the part is instead half a stud off, you can change PLACEMENT_OFFSET to 0.5.
On an off note, you might want to consider making the function in mouse.Move:Connect() non-anonymous so you can update the position of the furniture when you move around as well.
Cheers!
EDIT In any case, this tutorial might be of use, as it’s really informative and easy to follow.
Ah, I see. As an afterthought, you can make the offset the difference between the rounded and non-rounded positions of the plate. That way it will always be aligned, assuming the plate’s size is a whole number. As well, it might be best to have 2 separate offsets for X and Z if you were to use this method.
I’ve modified your original script to reflect the changes I’ve mentioned:
local plr = game:GetService("Players").LocalPlayer
local mouse = plr:GetMouse()
local block = workspace.Block
local TweenService = game:GetService("TweenService")
mouse.Move:Connect(function()
if mouse.Target == workspace.Part then
local goal = {}
local Y_OFFSET = 1.5
local PLACEMENT_OFFSET = Vector3.new((workspace.Part.Size.X % 2 + 1) * 0.5, 0, (workspace.Part.Size.Z % 2 + 1) * 0.5)
local relativePosition = Vector3.new(mouse.hit.Position.X, 0, mouse.hit.Position.Z) - workspace.Part.Position
relativePosition = Vector3.new(math.floor(relativePosition.X), Y_OFFSET, math.floor(relativePosition.Z))
goal.Position = workspace.Part.Position + relativePosition + PLACEMENT_OFFSET
local tweenInfo = TweenInfo.new(.1)
local tween = TweenService:Create(block, tweenInfo, goal)
tween:Play()
end
end)
My apologies for the late reply, I had to make sure the script worked!
Ignore what I said before, I’m a little tired so it was not correct. Instead, since we used relative position, PLACEMENT_OFFSET should only be changed when the size of the plate changes, not the position
The anchor point of the plate changes depending on the size, which can be disorienting when the change is not even, so I’ve changed PLACEMENT_OFFSET to be completely automatic! Placement offset was only added in the chance that the plate’s size would not be even, so then the part won’t be placed half a stud off, because the anchor point would be in the center of a stud, rather than inbetween. Give this a script a try, and let me know if it works!
I’ve got it working. This shouldn’t happen, but there is a discrepancy between my world and yours. It might be the new Lua VM. I’ve fixed the issue, it was order of operations. Give this a whirl and tell me how it goes:
local plr = game:GetService("Players").LocalPlayer
local mouse = plr:GetMouse()
local block = workspace.Block
local TweenService = game:GetService("TweenService")
mouse.Move:Connect(function()
if mouse.Target == workspace.Part then
local goal = {}
local Y_OFFSET = 1
local PLACEMENT_OFFSET = Vector3.new(((workspace.Part.Size.X % 2) + 1) * 0.5, 0, ((workspace.Part.Size.Z % 2) + 1) * 0.5)
local relativePosition = Vector3.new(mouse.hit.Position.X, 0, mouse.hit.Position.Z) - workspace.Part.Position
relativePosition = Vector3.new(math.floor(relativePosition.X), Y_OFFSET, math.floor(relativePosition.Z))
goal.Position = workspace.Part.Position + relativePosition + PLACEMENT_OFFSET
local tweenInfo = TweenInfo.new(.1)
local tween = TweenService:Create(block, tweenInfo, goal)
tween:Play()
end
end)
Thanks for bearing with me. The issue in fact wasn’t order of operations but the Y offset which I borrowed from your original script.
Now, about always having it within bounds:
local plr = game:GetService("Players").LocalPlayer
local mouse = plr:GetMouse()
local block = workspace.Block
local TweenService = game:GetService("TweenService")
mouse.Move:Connect(function()
if mouse.Target == workspace.Part then
local goal = {}
local Y_OFFSET = 1
local PLACEMENT_OFFSET = Vector3.new(((workspace.Part.Size.X % 2) + 1) * 0.5, 0, ((workspace.Part.Size.Z % 2) + 1) * 0.5)
local newPosition = Vector3.new(mouse.hit.Position.X, 0, mouse.hit.Position.Z) - workspace.Part.Position
newPosition = workspace.Part.Position + Vector3.new(math.floor(newPosition.X), Y_OFFSET, math.floor(newPosition.Z)) + PLACEMENT_OFFSET
goal.Position = Vector3.new(
math.clamp(
newPosition.X,
workspace.Part.Position.X - (workspace.Part.Size.X / 2) + 0.5,
workspace.Part.Position.X + (workspace.Part.Size.X / 2) - 0.5),
newPosition.Y,
math.clamp(
newPosition.Z,
workspace.Part.Position.Z - (workspace.Part.Size.Z / 2) + 0.5,
workspace.Part.Position.Z + (workspace.Part.Size.X / 2) - 0.5)
)
local tweenInfo = TweenInfo.new(.1)
local tween = TweenService:Create(block, tweenInfo, goal)
tween:Play()
end
end)
This makes it so that it forces the position to be within half of it’s size going positive or negative, on both the X and Z axis. math.clamp makes sure that the value is within the range, so with this code hopefully no objects will escape the bounds!