local players = game:GetService("Players")
local RunService = game:GetService("RunService")
local player = players.LocalPlayer
local mouse = player:GetMouse()
local part = workspace:WaitForChild("Part")
local walldata = {
oldposition = part.Position
}
function raycast()
local unitray = mouse.UnitRay
local params = RaycastParams.new()
params.FilterDescendantsInstances = {part}
params.FilterType = Enum.RaycastFilterType.Exclude
local result = workspace:Raycast(unitray.Origin, unitray.Direction * 1000)
return result
end
RunService.Heartbeat:Connect(function()
local result = raycast()
if result == nil then
return
end
local distance = (result.Position - walldata.oldposition).Magnitude
local newposition = Vector3.new(result.Position.X, walldata.oldposition.Y, result.Position.Z)
local newsize = Vector3.new(part.Size.X, part.Size.Y, distance)
local cf = CFrame.lookAt(walldata.oldposition, newposition) * CFrame.new(0, 0, -distance / 2)
part.Size = part.Size:Lerp(newsize, 0.2)
part.CFrame = part.CFrame:Lerp(cf, 0.2)
end)
It might be the lerps that you do?
Try removing them to see if that helps.
If that doesn’t help try not having the extra function for the raycast and just include it in your Heartbeat loop. The raycast function might be taking an extra heartbeat or 2 to return the numbers you want, but by then you’ve already calculated the movements in the loop.
This is because when lerping both the size and the CFrame, there isn’t any guarantee that they’ll play nice and lerp in just the right way for the inner edge of the wall to remain at the center.
If you moved your cursor around such that the wall rotated but remained the same size, in order to get the behavior you’re looking for, the CFrame would need to interpolate in a circular motion (red curve), but Lerp will make it interpolate in a linear position instead (blue line). That’s because you’re interpolating the central position of the wall too, rather than just interpolating its rotation.
A much simpler way to do it would be to only interpolate the size, and then update the CFrame according to the resulting size.
But this makes the CFrame update instantly rather than interpolate too. If you still want the angle to update smoothly, you should only update the angle, and then move it forward according to the new interpolated size anyway:
part.CFrame *= CFrame.new(0, 0, part.Size.Z / 2) --Move the CFrame back so the center of the wall is at cf's origin
local cf = CFrame.lookAt(walldata.oldposition, newposition)
part.Size = part.Size:Lerp(newsize, 0.2)
part.CFrame = part.CFrame:Lerp(cf, 0.2) --The position of both CFrames is the same, so only the angle is interpolated.
part.CFrame *= CFrame.new(0, 0, -part.Size.Z / 2) --Move the CFrame forward again, according to the wall's size
ah so basically lerping the angle separately is better because lerping the cframe position will cause that wobbling at then end of the wall since its trying to lerp % to the next position that cframe being the offset to fix the wall and make it fit between the 2 vector3’s