I have created a smooth shiftlock system and when initially activitating shiftlock it works fine.
- Smoothy Lerps to the desired offset
- Character smoothly lerps as well.
The issue resides when unshiftlocking, I am trying to make it smoothly transition back to Roblox’s custom camera type. While it does smoothly lerp back into place, the position is all off, especially when the player moves around.
Code:
local ContextActionService = game:GetService("ContextActionService")
local RunService = game:GetService("RunService")
local UserInputService = game:GetService("UserInputService")
local TweenService = game:GetService("TweenService")
local CurrentCamera = workspace.Camera
local Player = game.Players.LocalPlayer
local Character = game.Players.LocalPlayer.Character
local Humanoid = Character:WaitForChild("Humanoid")
local HumanoidRootPart = Character:WaitForChild("HumanoidRootPart")
xAngle = 0
yAngle = 0
local Previous
local Offset = Vector3.new(3,2,7)
local ShiftLock = false
local CameraFunctions = {}
function CameraFunctions.ShiftLock()
if not ShiftLock then
ShiftLock = true
-- storing the last camera cframe here
Previous = HumanoidRootPart.CFrame:ToObjectSpace(CurrentCamera.CFrame)
CurrentCamera.CameraType = Enum.CameraType.Scriptable
local function PlayerInput(actionName, inputState, inputObject)
if inputState == Enum.UserInputState.Change then
local deltaX = inputObject.Delta.X
local deltaY = inputObject.Delta.Y
xAngle = xAngle - deltaX * 0.3
yAngle = math.clamp(yAngle - deltaY * 0.3, -75, 75)
end
end
local x, y = CurrentCamera.CFrame:ToOrientation()
xAngle = math.deg(y)
yAngle = math.deg(x)
Humanoid.AutoRotate = false
Humanoid.WalkSpeed = 16
if Character and HumanoidRootPart then
ContextActionService:BindAction("PlayerInput", PlayerInput, false, Enum.UserInputType.MouseMovement)
RunService:BindToRenderStep("CameraUpdate", Enum.RenderPriority.Camera.Value, function()
UserInputService.MouseBehavior = Enum.MouseBehavior.LockCenter
local StartRootCFrame = CFrame.new(HumanoidRootPart.CFrame.Position) *
CFrame.Angles(0, math.rad(xAngle), 0) *
CFrame.Angles(math.rad(yAngle), 0, 0)
local CameraCFrame = StartRootCFrame:PointToWorldSpace(Offset)
local CameraFocus = StartRootCFrame:PointToWorldSpace(Vector3.new(Offset.X, Offset.Y, -100000))
CurrentCamera.CFrame = CurrentCamera.CFrame:Lerp(CFrame.lookAt(CameraCFrame, CameraFocus), .3)
local LookingCFrame = CFrame.lookAt(HumanoidRootPart.Position, CurrentCamera.CFrame:PointToWorldSpace(Vector3.new(0,0,-100000)))
HumanoidRootPart.CFrame = HumanoidRootPart.CFrame:Lerp(CFrame.fromMatrix(HumanoidRootPart.Position, LookingCFrame.XVector, HumanoidRootPart.CFrame.YVector),0.5)
end)
end
elseif ShiftLock then -- unlocking the camera
ShiftLock = false
print(ShiftLock)
print("lerping")
RunService:UnbindFromRenderStep("CameraUpdate")
ContextActionService:UnbindAction("PlayerInput")
local TimePassed = 0
local MaxTime = .4
local b
b = RunService.RenderStepped:Connect(function(DT)
TimePassed += DT
local targetCFrame = HumanoidRootPart.CFrame * Previous
CurrentCamera.CFrame = CurrentCamera.CFrame:Lerp(targetCFrame, 0.3)
print("lerping")
if TimePassed >= MaxTime then
print("finished")
CurrentCamera.CameraType = Enum.CameraType.Custom
Humanoid.AutoRotate = true
Humanoid.WalkSpeed = 16
UserInputService.MouseBehavior = Enum.MouseBehavior.Default
b:Disconnect()
print(b.Connected)
b = nil
print("lerped")
end
end)
end
end
return CameraFunctions
Here is a video on the issue.
Some clear issues is that if you rotate the camera, shiftlock, then unshiftlock, it lerps back to when I initially rotated the camera, I understand that issue resides in when I store the last Camera CFrame in the local Previous variable at the top of the script, and whenever I enable shiftlock it stores it. However I do not know a solution to this
The minor issue that can be observed is when moving, the camera lerps a little behind the character, and then snaps into place which is not what I want to do.