Does anyone have any video or article that explains how custom cameras work?
I’m interested in making a decent OTS camera or other 3rd person camera to replace the default Roblox one but I’m having difficulties understanding how some games make them look the way they do.
I’m assuming there’s some mathematics involved that I’m missing, unless I’m just not properly understanding the properties of a camera.
For reference, I can make a camera that sits on the player’s shoulder or follows the player around using the basic camera settings but it’s turning this into a camera that feels good for the user that I’m struggling with.
Games like ( ✦ ) SCP: Roleplay - Roblox with their gun camera that feels similar to default Roblox but somehow isn’t the same is an example to this.
Sorry for being vague, part of my problem is that I’m not sure which features make different game’s cameras different.
I’ve noticed that, in the SCP game linked, the camera movements are smoother (maybe even slower/delayed?) and that the camera swings more, especially when moving at high speeds, two effects that I’m not sure how to replicate.
I’ve attached a video showing the camera in this.
I recommend using RunService.Stepped since sometimes if you adjust the camera before the physics simulation steps it causes a bit of lag and snappiness. make sure the Camera.CameraType is set to Enum.CameraType.Scriptable.
Then you’ll need to get the mouse delta in order to calculate the movement of the camera with local mouseDelta = UserInputService:GetMouseDelta(), this would only work if the mouse is locked which you can do by setting the UserInputService.MouseBehavior to either Enum.MouseBehavior.LockCenter or Enum.MouseBehavior.LockCurrentPosition, so if you’d like to replicate the base third person camera you would have to set it to lockcurrentposition whenever you hold down the right mouse button. You can also multiply the mouseDelta with UserSettings().GameSettings.MouseSensitivity in order to adjust with the user’s current sensitivty settings.
after that I’ll Just Give The Code I’m Using Because I Can’t Be Bothered To Explain It Like This The Whole Way Through, Sorry It’s My First Time Posting On The Forum.
local Constants = {}
Constants.FieldOfView = 80
Constants.ZRotationDampening = 4
Constants.CameraOffset = Vector3.new(2, 4, 8) --X = side offset, Y = height offset, Z = distance from camera
Constants.LerpIntensity = 15
Constants.HorizontalMouseMovementLimit = 33 --otherwise it it has weird snappy behavior when you move the camera too fast, i have no idea why this happens
Constants.YLimit = 85 --limits how high you can look up or down
Constants.ZLimit = 20 --this just makes the camera tilt whenever you move it horizontally, set to zero if u dont like dat
local SteppedFunctions = {}
local CameraOrientation = Vector3.new()
local function UpdateOrientation()
local mouseDelta = UserInputService:GetMouseDelta() * GameSettings.MouseSensitivity
CameraOrientation = Vector3.new(
math.clamp(CameraOrientation.X - mouseDelta.Y, -Constants.YLimit, Constants.YLimit),
CameraOrientation.Y - math.clamp(mouseDelta.X, -Constants.HorizontalMouseMovementLimit, Constants.HorizontalMouseMovementLimit),
math.clamp(mouseDelta.X / Constants.ZRotationDampening, -Constants.ZLimit, Constants.ZLimit))
end
SteppedFunctions.UpdateCameraCFrame = function(deltaTime)
UpdateOrientation()
local newCameraCFrame = CFrame.new(Character.PrimaryPart.Position) *
Camera.CFrame.Rotation:Lerp(CFrame.fromOrientation(
math.rad(CameraOrientation.X),
math.rad(CameraOrientation.Y),
math.rad(CameraOrientation.Z)),
math.clamp(deltaTime * Constants.LerpIntensity, 0, 1)) *
CFrame.new(Constants.CameraOffset)
Camera.CFrame = newCameraCFrame
Camera.Focus = newCameraCFrame
end
SteppedFunctions.HandleCameraIntersection = function(deltaTime)
local raycastParameters = RaycastParams.new()
if LocalPlayer.Character then
raycastParameters.FilterDescendantsInstances = {LocalPlayer.Character}
end
local partsObstructing = workspace:GetPartBoundsInBox(Camera.CFrame, Vector3.one*.1)
local newPositionRaycast = workspace:Raycast(CameraAttachment.WorldPosition, CFrame.new(CameraAttachment.WorldPosition, Camera.CFrame.Position).LookVector*Constants.CameraOffset.Z, raycastParameters)
if newPositionRaycast then
Camera.CFrame = (Camera.CFrame - Camera.CFrame.Position) + newPositionRaycast.Position
end
end
Camera.CameraType = Enum.CameraType.Scriptable
Camera.FieldOfView = Constants.FieldOfView
RunService.Stepped:Connect(function(time, deltaTime)
SteppedFunctions.UpdateMouseBehavior()
SteppedFunctions.UpdateCameraCFrame(deltaTime)
SteppedFunctions.HandleCameraIntersection(deltaTime)
end)
This is great, thank you, is there any way to make the camera fall behind slightly depending on the camera’s or player’s acceleration?
I assumed that was the LerpIntensity but it didn’t affect that when I decreased it.