I’m currently making a simple crouching system for my game. The crouching works fine! Animation plays, camera moves down and you can fit under tighter spaces. However, while the camera is moving downwards there is a weird jitter to it that is really jarring and nearly always happens when both crouching and un-crouching.
Here’s a clip of it happening
I have tried looking through the code to find any general issues, trying to change the camera type and looking through the output for any errors but there aren’t any.
Here’s the code I use:
--Variables--
local UIS = game:GetService('UserInputService')
local RunService = game:GetService("RunService")
local TweenService = game:GetService("TweenService")
local Player = game.Players.LocalPlayer
local Character = Player.Character
local Humanoid = Character:WaitForChild("Humanoid")
local IntoRunTweeninfo = TweenInfo.new(0.25, Enum.EasingStyle.Sine, Enum.EasingDirection.Out)
local OutRunTweenInfo = TweenInfo.new(0.5, Enum.EasingStyle.Sine, Enum.EasingDirection.Out)
local CrouchTweenInfo = TweenInfo.new(0.6, Enum.EasingStyle.Sine, Enum.EasingDirection.Out)
local Camera = workspace.CurrentCamera
local CrouchCamPosition = Camera.CFrame * CFrame.new(0, -1.5, -0.9)
local DefaultFoV = 85
local IntroRunProperties = {FieldOfView = DefaultFoV + 10}
local OutOfRunProperties = {FieldOfView = DefaultFoV - 10}
local CrouchIntoProperties = {CameraOffset = Vector3.new(0,-1.5,0)}
local CrouchOutOfProperties = {CameraOffset = Vector3.new(0, 0,0)}
local RunTween = TweenService:Create(game.Workspace.CurrentCamera, IntoRunTweeninfo, IntroRunProperties)
local OutOfRunTween = TweenService:Create(game.Workspace.CurrentCamera, OutRunTweenInfo, OutOfRunProperties)
local IntoCrouchTween = TweenService:Create(Humanoid, CrouchTweenInfo, CrouchIntoProperties)
local OutCrouchTween = TweenService:Create(Humanoid, CrouchTweenInfo, CrouchOutOfProperties)
local RunAnim = script:WaitForChild("RunAnim")
local RunAnimationTrack = Humanoid:LoadAnimation(RunAnim)
local CrouchIdleAnim = script:WaitForChild("CrouchIdleAnim")
local CrouchIdleAnimationTrack = Humanoid:LoadAnimation(CrouchIdleAnim)
local CrouchWalkAnim = script:WaitForChild("CrouchWalkingAnim")
local CrouchWalkAnimationTrack = Humanoid:LoadAnimation(CrouchWalkAnim)
local Running = false
local Crouching = false
local HumanoidMoving = false
local WalkSpeed = 16
local CrouchSpeed = 10
local RunSpeed = 24
local JumpHeight = 7.2
local CrouchJumpHeight = 0
local RunJumpHeight = 8.7
local RunKey = Enum.KeyCode.LeftShift or Enum.KeyCode.ButtonL2
local CrouchKey = Enum.KeyCode.C or Enum.KeyCode.ButtonB
local StaminaAmount = 150
StaminaAmount = math.clamp(StaminaAmount, 0, 150)
--Detecting Input--
UIS.InputBegan:Connect(function(input)
if input.KeyCode == RunKey then -- Input running
if StaminaAmount > 0 then
Running = true
Crouching = false
Humanoid.JumpHeight = RunJumpHeight
Character.Head.CanCollide = true
RunTween:Play()
Humanoid.CameraOffset = Vector3.new(0, 0,- 0.9)
while StaminaAmount > 0 and Running == true do -- Stamina decrease
StaminaAmount = StaminaAmount - 1
wait(0.1)
if StaminaAmount <= 0 then -- Ran out of Stamina
OutOfRunTween:Play()
Running = false
Humanoid.JumpHeight = JumpHeight
end
end
end
elseif input.KeyCode == CrouchKey then -- Input crouch
Running = false
Crouching = true
Character.Head.CanCollide = false
Humanoid.JumpHeight = CrouchJumpHeight
IntoCrouchTween:Play()
wait(0.1)
Humanoid.CameraOffset = Vector3.new(0, -1.5, -0.9)
end
end)
--Stopped Input--
UIS.InputEnded:Connect(function(input)
if input.KeyCode == RunKey then -- Input stopped running
Running = false
Humanoid.JumpHeight = JumpHeight
Character.Head.CanCollide = true
OutOfRunTween:Play()
while StaminaAmount < 150 and Running == false do
StaminaAmount = StaminaAmount + 0.5
wait(0.1)
if StaminaAmount <= 0 then
Running = false
Humanoid.JumpHeight = JumpHeight
end
end
elseif input.KeyCode == CrouchKey then -- Input stopped crouching
Crouching = false
Humanoid.JumpHeight = JumpHeight
CrouchIdleAnimationTrack:Stop()
Character.Head.CanCollide = true
OutCrouchTween:Play()
wait(0.1)
Humanoid.CameraOffset = Vector3.new(0, 0, -0.9)
end
end)
--Detecting Movement--
local function DetectMovement()
if Humanoid.MoveDirection.Magnitude > 0 then
HumanoidMoving = true
if Running == true then -- Player is running
Humanoid.WalkSpeed = RunSpeed
elseif Crouching == true then -- Player is crouching
Humanoid.WalkSpeed = CrouchSpeed
elseif Running == false and Crouching == false then -- Player is walking
RunAnimationTrack:Stop()
CrouchWalkAnimationTrack:Stop()
CrouchIdleAnimationTrack:Stop()
Humanoid.WalkSpeed = WalkSpeed
end
elseif Humanoid.MoveDirection.Magnitude == 0 then -- Player is not moving
RunAnimationTrack:Stop()
CrouchWalkAnimationTrack:Stop()
HumanoidMoving = false
Humanoid.WalkSpeed = WalkSpeed
end
end
RunService.Heartbeat:Connect(DetectMovement)
--Animation--
RunService.Heartbeat:Connect(function()
if HumanoidMoving == true then
if Running == true then -- Running
if not RunAnimationTrack.IsPlaying then
RunAnimationTrack:Play()
CrouchWalkAnimationTrack:Stop()
CrouchIdleAnimationTrack:Stop()
end
elseif Crouching == true then --Crouching
if not CrouchWalkAnimationTrack.IsPlaying then
CrouchWalkAnimationTrack:Play()
RunAnimationTrack:Stop()
end
end
elseif HumanoidMoving == false then -- Idle
if Crouching == true then
if not CrouchIdleAnimationTrack.IsPlaying then
CrouchIdleAnimationTrack:Play()
end
end
else
RunAnimationTrack:Stop()
CrouchWalkAnimationTrack:Stop()
CrouchIdleAnimationTrack:Stop()
end
end)
while true do
wait(1)
end
I’m not the best with coding so sorry if I’m just being stupid, thank you!! ^^;