I’m making a road-building system, but I’ve run into an issue with grid snapping and CFrame.lookAt(). Firstly, I’d like to place the start segment of the road, then rotate it towards the end segment. The end segment should also rotate towards the start. This is my code so far:
local xGrid = 4
local function gridSnap(pos)
return Vector3.new(
math.floor(pos.X / xGrid + 0.5) * xGrid,
pos.Y,
math.floor(pos.Z / xGrid + 0.5) * xGrid
)
end
-- (getting the start position...)
while task.wait() do
local ray = mouseRay()
if ray then
local endPos = gridSnap(ray.Position)
roadEnd.Parent = game.Workspace
roadEnd:PivotTo(CFrame.lookAt(endPos, startPos, Vector3.new(0, 0, 1)))
roadStart:PivotTo(CFrame.lookAt(startPos, endPos, Vector3.new(0, 0, 1)))
end
end
If the snapping is enabled for the start segment and disabled for the end segment, the system seems to work:
If the snapping is enabled for both the start and end segments, this happens:
The printed position of the actual model seems to be correct, though when I click on the parts within the model, the position is completely off:
local xGrid = 4
local function gridSnap(pos)
return Vector3.new(
math.floor(pos.X / xGrid + 0.5) * xGrid,
pos.Y, --keep original Y for terrain/height
math.floor(pos.Z / xGrid + 0.5) * xGrid
)
end
while task.wait() do
local ray = mouseRay()
if ray then
local snappedEndPos = gridSnap(ray.Position)
local orientation = CFrame.lookAt(snappedEndPos, startPos)
orientation = CFrame.new(orientation.Position) * CFrame.fromMatrix(
Vector3.new(0, 0, 0),
orientation.LookVector,
Vector3.new(0, 1, 0)
)
roadEnd:PivotTo(orientation)
roadStart:PivotTo(CFrame.lookAt(startPos, snappedEndPos))
end
end
Looks like endPos snaps to grid and startPos also snaps to grid.
Possibly both points are jumping suddenly, causing problems.
Your problem is that endPos ≠ startPos because when you call CFrame.lookAt(), you’re essentially saying to look at itself, which causes it to go crazy and spit out that large number. My recommendation is if they are equal, don’t call lookAt().
Here is a fixed version of your script:
local xGrid = 4
local function gridSnap(pos)
return Vector3.new(
math.floor(pos.X / xGrid + 0.5) * xGrid,
pos.Y,
math.floor(pos.Z / xGrid + 0.5) * xGrid
)
end
-- (getting the start position...)
while task.wait() do
local ray = mouseRay()
if ray then
local endPos = gridSnap(ray.Position)
roadEnd.Parent = game.Workspace
if startPos == endPos then continue end -- if positions are the same, do nothing
roadEnd:PivotTo(CFrame.lookAt(endPos, startPos, Vector3.new(0, 0, 1)))
roadStart:PivotTo(CFrame.lookAt(startPos, endPos, Vector3.new(0, 0, 1)))
end
end