I’m lerping a value that maxes at 360 degrees, and since i’m lerping it when it’s currently at 360 and needs to reach a number below 180, instead of switching to 0 and continuing from there, it will lerp all the way from 360 down to said number. This can cause the value to snap around instead of rotating smoothly to its destination.
This is my current code, which works fine except for the issue stated above.
I’m confused, do you mean that the rotation goes the wrong direction, so the lerp goes a lot faster? A video would help to elaborate what you’re saying.
I believe the issue is coming from your usage of CFrame:ToOrientation and handling the rotation as a Vector3 Orientation then, not necessarily from the lerp function.
Yeah its a bit confusing as @WovenBreaker said I would suggest to improve the post with the video next time in the beginning of the post.
On the other hand I have had the same experience with a turret system. The issue is that the value caps as you have said.
Using CFrame:Lerp might fix it because CFrame:Lerp is special and it uses slerp so it moves using the shortest path, ex: y orientation in degrees: - 160 → -180 → +180 → + 160, instead of normal number lerp which goes -160 → 0 – > +160.
If that is the case then the other solution is to uncap your value.
For my y orientation example instead of the target being +160 degrees of y orientation from -160 degrees the goal target should instead be - 200 degrees.
self._PreviousGoalCFrameRelativeToBase = CFrame.new()
self._TargetY = 0 --Initial target goal 0 degrees
--Within loop code:
local yGoalCFOnly = CFrame.fromOrientation(0, yTarget, 0)
local _, previosYGoalOnly, _ = self._PreviousGoalCFrameRelativeToBase:ToOrientation()
local differenceCF = CFrame.fromOrientation(0, previosYGoalOnly, 0):Inverse()*yGoalCFOnly
local _, addedY, _ = differenceCF:ToOrientation()
self._TargetY += addedY
self._PreviousGoalCFrameRelativeToBase = relativeToTurretBase
--Prevents excess rotation towards goal from current position
local difference = self._TargetY - newY
if abs(difference) > TAU then
self._TargetY -= math.sign(self._TargetY)*TAU
end
ySpring.Target = self._TargetY
Relooking at your GIF you just need to rotate the camera towards a target position, you can just use CFrame from axis angles for that.
local target = workspace.Rig.Head
local function AngleBetween(vectorA, vectorB)
return math.acos(math.clamp(vectorA:Dot(vectorB), -1, 1))
end
local camera = workspace.CurrentCamera
while true do
local dt = task.wait()
local currentLookVector = camera.CFrame.LookVector
local targetLookVector = (target.Position-camera.CFrame.Position).Unit
local angleTowardsTarget = AngleBetween(currentLookVector, targetLookVector)
local rotationAngleTowardsTarget = math.min(angleTowardsTarget, dt*1) --Rotate 1 radian per second towards target, or the minimum distance to complete goal (prevent overshoot)
local axis = currentLookVector:Cross(targetLookVector)
camera.CFrame = CFrame.fromAxisAngle(axis, rotationAngleTowardsTarget)*camera.CFrame
end
I’m not actually changing the cameras CFrame, the cameras CFrame is being updated by a MouseX and MouseY variable, which is what im updating to move the camera to my desired position.
The issue i’m having is with gimbal locks, since my variables are numbers and not CFrames I can’t use CFrame Lerp to get past this.