Smooth Shiftlock Out

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.

https://streamable.com/s8fmfa

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.

Bump, Still havent found a solution

When the player unshiftlocks, update the angle of the Previous variable to the current camera before the camera is moving. We will use CFrame.fromEulerAnglesXYZ() and CFrame:ToEulerAnglesXYZ()

local cameraRotation = CurrentCamera.CFrame:ToEulerAnglesXYZ()
Previous = CFrame.new(Previous.Position) * CFrame.fromEulerAnglesXYZ(cameraRotation)

-- update camera afterwards

This didn’t work, it just messed up the lerp function somehow and positioned the camera like 10 feet above the character.
I was able to come to a minor solution, here is what I changed

elseif ShiftLock then -- unlocking the camera
		ShiftLock = false

		print(ShiftLock)
		print("lerping")

		Offset = Vector3.new(0, 1.5, 8.5)
		
		task.wait(.07)
		CurrentCamera.CameraType = Enum.CameraType.Custom
		Humanoid.AutoRotate = true
		Humanoid.WalkSpeed = 16
		UserInputService.MouseBehavior = Enum.MouseBehavior.Default
		RunService:UnbindFromRenderStep("CameraUpdate")
		ContextActionService:UnbindAction("PlayerInput")

		
		Offset = Vector3.new(1.5,2,7)

Instead of lerping the camera cframe again, I kept the BindedRenderStep since it was already lerping the camera and changed the offset that was being used to a different offset that replicated the custom camera position, then in order to let the lerp animation play, before unbinding and setting all the other values back I added a wait then I unbinded everything, and set the offset value back to normal.

The only small issue is that you can see it kind of snap back into place which is a little annoying but it’s not too noticeable

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.