Currently working on a placement system as a means to practice my scripting skills, however I have run into a problem. When putting my mouse over a wall, the object should snap to the wall’s rotation and move along the wall depending on the mouse position. The problem is that I am not sure how I would go about doing this because I don’t know how to assign the part’s position relative to the centre of the wall if that makes sense.
I have looked up things like Object and World space, however I can’t really seem to understand how it works and how I would go about solving this issue.
Object placement script, it snaps it to the wall but I’m not able to move the part along the wall if that makes sense:
local item
local snappedToWall = false
currentConnections[#currentConnections + 1] = runService.RenderStepped:Connect(function()
item = item or Instance.new('Part')
item.Anchored = true
local target = mouse.Target
item.Parent = ignoreParts
item.Position = snap(mouse.Hit.p) -- snaps the object to the grid, not the issue but I can post it should it be needed.
if string.find(string.lower(target.Name), 'wall') then
print('wall')
item.CFrame = target.CFrame * CFrame.new(item.Size.X / 2, 0, 0) -- offsets the part from the wall's CFrame
end
end)
Video of the problem and how far I’ve gotten:
EDIT:
I have come up with somewhat of a solution, but I still need help if anyone can help with that.
I did come up with somewhat of a solution but it comes back to snapping it to a grid which I still am having problems with.
What I have so far:
item.Position = mouse.Hit.p -- Snap it to the hit position
item.Orientation = target.Orientation -- Same orientation as the wall
item.CFrame *= CFrame.new((item.Size.X) / 2, 0, 0) -- offset it by half of the item's size
I also tried using modulus to achieve the grid snapping effect but it ended up being buggy and not really what I was looking for.
local function snapAxis(number)
return math.floor((number / gridSnap) + 0.5) * gridSnap
end
local yAxis = snapAxis(item.Position.Y)
item.Position = Vector3.new(item.Position.X, yAxis, item.Position.Z)
local posX, posZ
if item.Position.X < 0 then
posX = -item.Position.X
else
posX = item.Position.X
end
if item.Position.Z < 0 then
posZ = -item.Position.Z
else
posZ = item.Position.Z
end
local diffX = posX % gridSnap
local diffZ = posZ % gridSnap
item.CFrame -= Vector3.new(-diffX, 0, -diffZ) -- also tried multiplication
FINALLY got it!!! I was overcomplicating things way more than I had to.
local offsetCFrame = CFrame.new(snap(item.CFrame:ToObjectSpace(target.CFrame).Position)) -- find the difference between the hit position and the grid snap position relative to the mouse target
item.CFrame = target.CFrame:ToWorldSpace(CFrame.new(-offsetCFrame.Position.X, 0, -offsetCFrame.Position.Z)) -- set the new snapped position (ignore Y for now)
item.CFrame *= CFrame.new(item.Size.X / 2, 0, 0) -- offset for half of the item's size
item.Position = Vector3.new(item.Position.X, snapAxis(mouse.Hit.p.Y), item.Position.Z) -- set the final position, snap to the Y axis