Weird Camera Glitch With An Enhanced Shift-Lock Module And Better Default Camera Script

  • What is my problem?
    I have a very weird camera glitch while using 2 different camera enhancement modules.

  • What solutions have I tried so far?
    I’ve tried setting the offset to 0,0,0. Checked the camera properties while using both scripts. Turns out that the problem is in the camera’s position/offset and not in the FOV since the FOV stays normal but the position gets changed about 0.5 seconds after you have toggled the shift lock back to off.

  • What do I want to achieve?
    I just want to fix this annoying bug, please look at the video at the bottom of this post to see it. Its quite hard to explain. If you didn’t understand what I meant please skip the scripts and watch the video first!

Here are the scripts and their location in my game:

  1. Shift-Lock Enhancement Module (Replicated Storage > Modules Folder): Click Here For Dev Forum Link!
--// NOTE: This module is open sourced. I do not own it, link to the original post is above! This is the original code. It was not edited in any way. All of the code is the same. The only changes I made are on line 65 and line 74, I changed the FOV from the default to 5 so the zoom effect is not that big, on line 74 I disabled the Mouse Sensitivity changer so I can get the default shift-lock sensitivity.
local ECS = {}

--- Services ---

local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local UserInputService = game:GetService("UserInputService")
local UserGameSettings = UserSettings():GetService("UserGameSettings")
local TweenService = game:GetService("TweenService")

--- Constants ---

local Player = Players.LocalPlayer
local CurrentCamera = workspace.CurrentCamera
local DefaultFieldOfView = 70
local CameraTweenInfo = TweenInfo.new(0.5, Enum.EasingStyle.Quad, Enum.EasingDirection.InOut) --Feel free to edit your desired tween style or adding more styles as you like
local MouseSensitivity = UserInputService.MouseDeltaSensitivity

--- States ---

local isAligned = false --To define the state when the character facing forward as the camera angle
local isSteppedIn = false --To define the state when moveing camera without right-clicking

--- Functions ---

function ECS:MouseIcon(Status) --To toggle mouse icon

	UserInputService.MouseIconEnabled = Status

end

function ECS:MouseLock(Status) --To toggle moving-camera-without-right-clicking mode as well as locking mouse at center of screen

	isSteppedIn = Status
	
	if Status == true then
		
		UserInputService.MouseBehavior = Enum.MouseBehavior.LockCenter	
		
	elseif Status == false then
		
		UserInputService.MouseBehavior = Enum.MouseBehavior.Default	
		
	end

end

function ECS:Alignment(Status) --To toggle character alignment to the camera

	local Character = Player.Character
	local Humanoid = Character:WaitForChild("Humanoid")

	Humanoid.AutoRotate = not Status
	isAligned = Status

end

function ECS:CameraMode(Mode) --To toggle different camera modes

	if Mode == "Aim" then

		local Character = Player.Character
		local Humanoid = Character:WaitForChild("Humanoid")

		local FieldOfView = {FieldOfView = DefaultFieldOfView - 5} --Edit the amount of FOV that you would like to substract to achieve zoom effect
		local CameraOffset = {CameraOffset = Vector3.new(2, 1, 0)} --Edit your desired camera offset

		local TweenFieldOfView = TweenService:Create(CurrentCamera, CameraTweenInfo, FieldOfView)
		local TweenCameraOffset = TweenService:Create(Humanoid, CameraTweenInfo, CameraOffset)

		TweenFieldOfView:Play()
		TweenCameraOffset:Play()

		--UserInputService.MouseDeltaSensitivity = MouseSensitivity / 2 Edit the amount you would like to lower the mouse sensitivity

	end

	if Mode == "FirstPerson" then

		if Player.CameraMode == Enum.CameraMode.Classic then --To achieve first person camera			
			Player.CameraMode = Enum.CameraMode.LockFirstPerson			
		end

	end

	if Mode == "Scope" then

		local FieldOfView = {FieldOfView = DefaultFieldOfView - 50} --Edit the amount of FOV that you would like to substract to achieve zoom effect

		local TweenFieldOfView = TweenService:Create(CurrentCamera, CameraTweenInfo, FieldOfView)

		if Player.CameraMode == Enum.CameraMode.Classic then --To achieve first person camera			
			Player.CameraMode = Enum.CameraMode.LockFirstPerson			
		end

		TweenFieldOfView:Play()

		UserInputService.MouseDeltaSensitivity = MouseSensitivity / 5 --Edit the amount you would like to lower the mouse sensitivity

	end

	if Mode == "Reset" then

		local Character = Player.Character
		local Humanoid = Character:WaitForChild("Humanoid")

		local FieldOfView = {FieldOfView = DefaultFieldOfView} --To reset FOV
		local CameraOffset = {CameraOffset = Vector3.new(0, 0, 0)} --To reset camera offset

		local TweenFieldOfView = TweenService:Create(CurrentCamera, CameraTweenInfo, FieldOfView)
		local TweenCameraOffset = TweenService:Create(Humanoid, CameraTweenInfo, CameraOffset)

		if Player.CameraMode == Enum.CameraMode.LockFirstPerson then --To reset camera mode			
			Player.CameraMode = Enum.CameraMode.Classic			
		end

		TweenFieldOfView:Play()
		TweenCameraOffset:Play()

		UserInputService.MouseDeltaSensitivity = MouseSensitivity --To reset mouse sensitivity

	end

end

--- RaycastParams ---

local Params = RaycastParams.new()
Params.FilterType = Enum.RaycastFilterType.Blacklist

--- RenderStep ---

RunService.RenderStepped:Connect(function()

	if isAligned == true then --To achieve character alignment to the camera & camera offset obstruction detection

		local Character = Player.Character
		local HumanoidRootPart = Character:WaitForChild("HumanoidRootPart")
		local Head = Character:WaitForChild("Head")

		Params.FilterDescendantsInstances = {Character} --Add the instances that you would like to ignore detection

		local Result = workspace:Raycast(Head.Position, CurrentCamera.CFrame.Position - Head.Position, Params)

		if Result ~= nil then

			---Credit to Arbeiters for below collision calculation method
			local ObstructionDisplacement = (Result.Position - Head.Position)
			local ObstructionPosition = Head.Position + (ObstructionDisplacement.Unit * (ObstructionDisplacement.Magnitude - 1))
			local x,y,z,r00,r01,r02,r10,r11,r12,r20,r21,r22 = CurrentCamera.CFrame:components()

			CurrentCamera.CFrame = CFrame.new(ObstructionPosition.x, ObstructionPosition.y, ObstructionPosition.z , r00, r01, r02, r10, r11, r12, r20, r21, r22)

		end

		local rx, ry, rz = CurrentCamera.CFrame:ToOrientation()
		HumanoidRootPart.CFrame = CFrame.new(HumanoidRootPart.CFrame.Position) * CFrame.fromOrientation(0, ry, 0)

	end

end)

return ECS
  1. Enhanced Default Camera LocalScript (StarterGUI): Click Here For The Original Video!
--// NOTE: Code was not edited in any way. All variables and settings are the same.
while wait(1) do
self = script.Parent
c = workspace.CurrentCamera

player = game.Players.LocalPlayer
char = player.Character or player.CharacterAdded:wait()
humanoid = char:WaitForChild("Humanoid")
function ok()
humanoid.CameraOffset = Vector3.new(0,0,-1.2)
end
function ok2()
humanoid.CameraOffset = Vector3.new(0,-1,-1.2)
end
function ok3()
humanoid.CameraOffset = Vector3.new(0,-3,-1.2)
end

-- Apply some properties

player.CameraMaxZoomDistance = 30
if humanoid.CameraOffset == Vector3.new(0,0,0) then
ok()
elseif humanoid.CameraOffset == Vector3.new(0,0,-1.2) then
ok()
elseif humanoid.CameraOffset == Vector3.new(0,-1,-1.2) then
ok2()
elseif humanoid.CameraOffset == Vector3.new(0,-3,-1.2) then
ok3()
end
	

function lock(part)
	if part and part:IsA("BasePart") then
		part.LocalTransparencyModifier = part.Transparency
		part.Changed:connect(function (property)
			part.LocalTransparencyModifier = part.Transparency
		end)
	end
end

for _,v in pairs(char:GetChildren()) do
	lock(v)
end

char.ChildAdded:connect(lock)

c.Changed:connect(function (property)
	if property == "CameraSubject" then
		if c.CameraSubject and c.CameraSubject:IsA("VehicleSeat") and humanoid then
			-- Vehicle seats try to change the camera subject to the seat itself. This isn't what we wan't really.
			c.CameraSubject = humanoid;
		end
	end
end)
end
  1. Enhanced Shift-Lock LocalScript (Controlling the Module, basically uses UIS to check when the user presses shift): {Code was made by me}
--// NOTE: Code was made by me, the glitch is 99% not from this script.
local ECS = require(game:GetService('ReplicatedStorage'):WaitForChild('Modules'):WaitForChild('EnhancedShiftLock'))
local UserInputService = game:GetService("UserInputService")
local active = false

UserInputService.InputBegan:Connect(function(input, isTyping)
	if isTyping then return end
	if input.KeyCode == Enum.KeyCode.LeftShift then
		if active == false then
			active = true
			ECS:MouseLock(true)
			ECS:Alignment(true)
			ECS:CameraMode("Aim")
		elseif active == true then
			active = false
			ECS:MouseLock(false)
			ECS:Alignment(false)
			ECS:CameraMode("Reset")
		end
	end
end)
  • Here is a video of the glitch. Was recorded in Roblox Studio. Sorry for bad quality.

Thanks in advance to people who are willing to help!

Edits:

  1. Changed video to MP4 so it can appear in the post correctly.
  2. Found the original creator of the better default camera script.
2 Likes

Hii This is Leo - Thank you for using the module that I created previously first :raised_hands: I have to apologized that I haven’t updated the module from time to time and Roblox’ might have new changes and updates on camera script that might have conflicts between core scripts and enhanced camera module

From the video, I’m thinking that the issue might have to do with “camerasubject” being changed (?) I would suggest if you could disable “Enhanced Default Camera” LocalScript to test with the shiftlock module only to see if the issue still persisted

2 Likes

Hey there! I’m happy to hear from you. I have already tested it, if I disable the module everything works fine. Here is a video of it. Pay attention to the camera properties in the second clip.

First clip: (Disabled Module + Camera Properties (They don’t change after the shift lock.))Second Clip: (Enabled Module + Camera Properties):

Second Clip: (Enabled Module + Cam Properties):
Uploading: 2022-11-06 18-15-07.mp4…

Edit: Sorry that the files are messed up. I’m still new to the dev forum and I have some issues with uploading files.

2 Likes

might be try further adjusting the Z axis offset in the enhanced module to match with your current local script - for example, in Aim mode, try matching -1.2 in Z axis. You might have to edit both Aim mode and Reset mode

if Mode == "Aim" then

	local Character = Player.Character
	local Humanoid = Character:WaitForChild("Humanoid")

	local FieldOfView = {FieldOfView = DefaultFieldOfView - 5} --Edit the amount of FOV that you would like to substract to achieve zoom effect
	local CameraOffset = {CameraOffset = Vector3.new(2, 1, -1.2)} --Edit your desired camera offset

	local TweenFieldOfView = TweenService:Create(CurrentCamera, CameraTweenInfo, FieldOfView)
	local TweenCameraOffset = TweenService:Create(Humanoid, CameraTweenInfo, CameraOffset)

	TweenFieldOfView:Play()
	TweenCameraOffset:Play()

	--UserInputService.MouseDeltaSensitivity = MouseSensitivity / 2 Edit the amount you would like to lower the mouse sensitivity

end

I’m suspecting the “while wait(1) do” in local script is causing the stutter after disabling the shift lock :raised_hands:

2 Likes

I will try it right now. If I get any solution I will tell you! Thanks.

2 Likes

It worked! I had to change both the Aim and Reset modes so it works. If you only change Aim you will still have the bug and it will look even worse. Now my camera moves smoothly between shift lock and normal view. Thank you so much for creating this module, its very useful. One of the reasons I wanted to use it was because of the stupid clipping glitch. When you get close to a wall ur camera starts going through it and can see whats inside it. I suggest adding a note in your resource post that to make this compatible with these types of camera modifications you have to change the Z offset as well. It’s up to you tho. Thank you so much once again!

2 Likes

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