I made a wall system well

I made my own wall placement system everything works well until you try rotating the wall or bring it to close to the base position

I save the old position in a table

@sleitnick might have a answer

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)

1 Like

What is the goal of the rotation? Do you want the wall to rotate upon the opposite edge of pressure? It looks fine to me.

the other side of the wall should not be moving or wobbling or something

its supposed to stationary

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.

1 Like

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.

image

A much simpler way to do it would be to only interpolate the size, and then update the CFrame according to the resulting size.

part.Size = part.Size:Lerp(newsize, 0.2)
part.CFrame = CFrame.lookAt(walldata.oldposition, newposition) * CFrame.new(0, 0, -part.Size.Z / 2)

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
2 Likes

thank you this gave me a better understanding of how this works I am going to learn more about this as well.

this was helpful! I mark this as the solution.

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