When I run my camera script it stutters with each frame. I am not sure what else to do to prevent the stuttering from occurring and could use some guidance and an explanation on why it is doing what it is.
local UserInputService = game:GetService('UserInputService')
local RunService = game:GetService('RunService')
local CollectionService = game:GetService('CollectionService');
RunService:UnbindFromRenderStep("cameraRenderUpdate");
local player = game.Players.LocalPlayer
local mouse = player:GetMouse();
local character = player.Character or player.CharacterAdded:Wait()
local humanoid = character:WaitForChild("Humanoid")
local camera = workspace.CurrentCamera
camera.CameraType = Enum.CameraType.Scriptable
local zoomSpeed = 1
local rotateSpeed,defaultRotationSpeed = 0.175,0.1;
local minZoom = 6
local maxZoom = 16
local offsetDistance = 15
local velocityMultiplier = 8
local currentZoom = 10
local currentRotation = Vector2.new(0, 0)
local weight = 1
local maxAngularSpeed = 5
local m2RotationSpeed = .2;
local mobileRotationSpeed = .01;
local maxSpeed = 10000;
local maxDelta = 4000
local maxBlur = 10
--spring
-- 20 too slow..? 100 slow
local springConstant = 100
local velocity = Vector3.new(0, 0, 0)
local position = camera.CFrame.Position
local angularVelocity = 0
local rotation = Vector3.new()
--
local blur = game.Lighting:FindFirstChild("FastBlur") or Instance.new("BlurEffect",game.Lighting);
blur.Size = 0;
local targetCFrame = camera.CFrame
humanoid.CameraOffset = Vector3.new(0,1,0);
local function updateWeight()
--TODO: add weight if flash banged/time dialation slower
end
local function createTestPart(pos)
local part = Instance.new("Part",workspace)
part.Name = "TestPart"
part.Size = Vector3.new(1,1,1)
part.CFrame = pos
part.Anchored = true
part.BrickColor = BrickColor.new("Bright red")
return part
end
local function singleDigitLerp(a,b,t)
return a + (b - a) * t
end
UserInputService.InputChanged:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseWheel then
currentZoom = math.clamp(currentZoom - input.Position.Z * zoomSpeed, minZoom, maxZoom)
end
end)
--UserInputService:IsMouseButtonPressed(Enum.UserInputType.MouseButton2)
local lastHadAction = nil;
local lastPos;
local lastMouseDelta = Vector2.new(mouse.X,mouse.Y)
local rayparams = RaycastParams.new();
rayparams.FilterType = Enum.RaycastFilterType.Exclude
local override = true;
local function hasNaN(cframe)
local components = {cframe:GetComponents()}
for _, value in ipairs(components) do
if value ~= value then
return true
end
end
return false
end
local function computeAngularVelocity(current, target, dt)
local axis, angle = current:ToObjectSpace(target):ToAxisAngle()
if math.abs(angle) < 0.001 then -- dead-zone
return Vector3.new(0, 0, 0)
end
angle = math.clamp(angle, -maxAngularSpeed * dt, maxAngularSpeed * dt)
return axis * angle / dt
end
UserInputService.InputBegan:Connect(function(input)
if input.KeyCode == Enum.KeyCode.LeftControl then
local lockCenter = (UserInputService.MouseBehavior == Enum.MouseBehavior.LockCenter);
UserInputService.MouseBehavior = (lockCenter) and Enum.MouseBehavior.Default or Enum.MouseBehavior.LockCenter;
humanoid.CameraOffset = (lockCenter) and Vector3.new(0,1,0) or Vector3.new(1,1,0);
end
end)
local touchPadVelocity;
if UserInputService.TouchEnabled then
local guiFrameVariable = player.PlayerGui:WaitForChild("TouchGui"):WaitForChild("TouchControlFrame"):WaitForChild("DynamicThumbstickFrame")
local function isTouchInside(point, frame)
local framePosition = frame.AbsolutePosition
local frameSize = frame.AbsoluteSize
local frameLeft = framePosition.X
local frameRight = framePosition.X + frameSize.X
local frameTop = framePosition.Y
local frameBottom = framePosition.Y + frameSize.Y
local pointX = point.X
local pointY = point.Y
return pointX >= frameLeft and pointX <= frameRight and pointY >= frameTop and pointY <= frameBottom
end
local function allPointsInGui(touchPositions)
local bool = true;
for i,v in pairs(touchPositions) do
if not isTouchInside(v,guiFrameVariable) then
bool = false;
end
end
return bool;
end
local function diversePointsInGui(touchPositions)
local bools = {};
for i,v in pairs(touchPositions) do
table.insert(bools, isTouchInside(v,guiFrameVariable))
end
local last = nil
for i,v in pairs(bools) do
if not last then
v = last;
elseif last ~= v then
return true;
end
end
return false;
end
UserInputService.TouchPan:Connect(function(touchPositions, totalTranslation, velocity, state, gpe)
if allPointsInGui(touchPositions) then
touchPadVelocity = Vector2.new();
elseif diversePointsInGui(touchPositions) then
touchPadVelocity = velocity*2
else
touchPadVelocity = velocity;
end
end)
end
local function lockCharacter()
local mousePos = UserInputService:GetMouseLocation()
local mouseRay = camera:ScreenPointToRay(mousePos.X, mousePos.Y)
local mouseWorldPos = mouseRay.Origin + mouseRay.Direction*50
local lookVector = Vector3.new(mouseWorldPos.X, character.HumanoidRootPart.Position.Y, mouseWorldPos.Z) - character.HumanoidRootPart.Position
character.HumanoidRootPart.CFrame = CFrame.lookAt(character.HumanoidRootPart.Position, lookVector + character.HumanoidRootPart.Position)
humanoid.AutoRotate = false;
end
local check = false;
local hadBlock = false;
RunService:BindToRenderStep("run",Enum.RenderPriority.Camera.Value+1,function(dt)
if CollectionService:HasTag(character,"Action") then
check = true;
lockCharacter()
lastHadAction = tick();
end
if CollectionService:HasTag(character,"Blocking") then
hadBlock = true
lockCharacter();
elseif hadBlock then
humanoid.AutoRotate = true;
hadBlock = false;
end
if lastHadAction and (tick()-lastHadAction) >= .5 and check then
check = false;
humanoid.AutoRotate = true;
end
rayparams.FilterDescendantsInstances = {character};
updateWeight()
local delta = Vector2.new(UserInputService:GetMouseDelta().X, UserInputService:GetMouseDelta().Y)
local speed = delta.Magnitude / dt
local targetBlurSize = math.min(speed / maxDelta * maxBlur, maxBlur)
blur.Size = singleDigitLerp(blur.Size, targetBlurSize, .1)
if delta.X == 0 and delta.Y == 0 and not UserInputService.TouchEnabled then
delta = Vector2.new(mouse.X, mouse.Y)-lastMouseDelta
weight = .1;
else
weight = 1;
end
--currentRotation = currentRotation + delta * rotateSpeed * weight
if (UserInputService.TouchEnabled and touchPadVelocity) then
currentRotation = currentRotation + touchPadVelocity * mobileRotationSpeed;
touchPadVelocity -= touchPadVelocity * (mobileRotationSpeed*2);
elseif not UserInputService.TouchEnabled then
if UserInputService:IsMouseButtonPressed(Enum.UserInputType.MouseButton2) and (UserInputService.MouseBehavior == Enum.MouseBehavior.Default or UserInputService.MouseBehavior == Enum.MouseBehavior.LockCurrentPosition) then
UserInputService.MouseBehavior = Enum.MouseBehavior.LockCurrentPosition
currentRotation = currentRotation + delta * m2RotationSpeed
else
if UserInputService.MouseBehavior == Enum.MouseBehavior.LockCurrentPosition then
UserInputService.MouseBehavior = Enum.MouseBehavior.Default
end
currentRotation = currentRotation + delta * rotateSpeed * weight
end
end
currentRotation = Vector2.new(currentRotation.X,math.clamp(currentRotation.Y,-60,60));
local verticalRotation = CFrame.Angles(math.rad(currentRotation.Y), 0, 0)
local horizontalRotation = CFrame.Angles(0, -math.rad(currentRotation.X), 0)
local newCFrame = CFrame.new(character.PrimaryPart.Position) * horizontalRotation * verticalRotation * CFrame.new(0, 0, -currentZoom)
local ray = workspace:Raycast(character.PrimaryPart.Position, (character.PrimaryPart.Position- newCFrame.Position).Unit*-currentZoom, rayparams);
if ray then
newCFrame = CFrame.new(character.PrimaryPart.Position) * horizontalRotation * verticalRotation * CFrame.new(0,0,-math.clamp((character.PrimaryPart.Position-ray.Position).Magnitude*.95,minZoom,maxZoom));
end
if override then
override = false;
targetCFrame = CFrame.new(newCFrame.Position,character.PrimaryPart.Position)
else
local desiredCFrame = CFrame.new(newCFrame.Position,character.PrimaryPart.Position)
local displacement = position - desiredCFrame.Position
local springAcceleration = -2 * math.sqrt(springConstant) * velocity - springConstant * displacement
velocity = velocity + springAcceleration * dt
position = position + velocity * dt
local desiredRotation = (desiredCFrame - desiredCFrame.Position)
local axis, angle = desiredRotation:ToAxisAngle()
local currentLookVector = targetCFrame.LookVector
local desiredLookVector = (character.PrimaryPart.Position - targetCFrame.Position).Unit
local cosAngularDisplacement = currentLookVector:Dot(desiredLookVector)
local angularDisplacement = math.acos(cosAngularDisplacement)
local angularAcceleration = -2 * math.sqrt(100) * angularVelocity - 100 * angularDisplacement
if angularAcceleration ~= angularAcceleration then
print("Warning: angularAcceleration is NaN")
else
if angularVelocity ~= angularVelocity then
print("Warning: angularVelocity is NaN")
else
angularVelocity = angularVelocity + angularAcceleration * dt
end
end
local rotation = CFrame.fromAxisAngle(axis, angle + angularVelocity * dt)
local v = CFrame.new(position + velocity * dt) * rotation;
if not hasNaN(v) then
targetCFrame = v;
end
end
camera.CFrame = targetCFrame * CFrame.new(humanoid.CameraOffset)
lastMouseDelta = Vector2.new(mouse.X,mouse.Y)
end)
External Media