BallSocketConstraint on a moving vehicle broken when it's CFrame is set

Basically, what is happening is that I have a tank turret using a “Swivel System”, which uses a BallSocketConstraint to stay along with the vehicle, and then it uses CFrame to rotate itself towards the “Target” position bassed to it on a loop set to RunService Heartbeat. This whole system wors ks totally fine when the vehicle is not moving, but when it starts moving the part starts lagging behiout, nd the rest of the vehicle and glitching out, when I stop moving it slowly moves back into place. I know it’s due to the CFrame being set per heartbeat because removing my swivel script causes the BallSocketConstraint to work correctly.
Is there anything I can do to fix this? I can’t figure out how to make a HingeConstraint face the mouse properly, so this is my preffered option. Swivel script code:

function NormalizeAngle(value) 
	if value <= -180 then
		return value + 360
	elseif value > 180 then
		return value - 360
	else
		return value
	end
end

function ConstraintRotation(value, constraint, add)
	value = NormalizeAngle(math.deg(value) - add)
	if constraint.X < constraint.Y then
		if value < constraint.X then
			return constraint.Y
		elseif value > constraint.Y then
			return constraint.X
		else
			return NormalizeAngle(value + add)
		end
	elseif constraint.Y < constraint.X then
		-- TODO: Make it check which constraint the value is closer to and round to that
		if value < constraint.X and value > constraint.Y then
			return constraint.X
		else
			return NormalizeAngle(value + add)
		end
	elseif (constraint.X == -180 and constraint.Y == 180) or (constraint.X == 180 and constraint.Y == -180) then
		return NormalizeAngle(value + add)
	else
		return 0
	end
end

local function Face(step)
	local setXDir, setYDir, setZDir = CFrame.new(script.Parent.Position, Target):ToOrientation()
	-- Calculate difference between them and current dir values
	local curXDir, curYDir, curZDir = script.Parent.CFrame:ToOrientation()
	script.Parent.CFrame = CFrame.new(script.Parent.Position) * CFrame.fromOrientation(
		math.rad(ConstraintRotation(setXDir, Info.ConstraintX, Vehicle.Model.MainSeat.Orientation.X)),
		math.rad(ConstraintRotation(setYDir, Info.ConstraintY, Vehicle.Model.MainSeat.Orientation.Y)),
		math.rad(ConstraintRotation(setZDir, Info.ConstraintZ, Vehicle.Model.MainSeat.Orientation.Z))
	)
end

(Face is called per frame) I can send a video if needed of it breaking and lagging behind. If I only run Face when the mouse moves, this still happens, as it glitches behind every time the mouse moves while the vehicle moving instead of continually while the vehicle moves, but I prefer it being per frame because that way the position stays updated because the vehicle is moving forward.

1 Like

Instead of using constraints, try using cframes to get it from a base position (an attachment relative to the tanks position) then towards the target position

It should not lag behind then

I just tried that and it works very poorly, due to it not constantly updating (or at least from what I can tell), it still happens to lag behind. I think the best solution I could do here because of this would be using a HingeConstraint.

HingeContraints will probably do the same thing. and dont use Heartbeat use .Stepped or .RenderStepped