How can I make the camera have the same behaviour as in the video (0:15-0:22) https://www.youtube.com/watch?v=3fDuCU1-5J4
create a part, then set the camerasubject to this part
in a function bound to render step with camera.priority + 1:
lerp the part to rootPart.Position + rootPart.CFrame.LookVector * offset
(adjust offset as needed)
or you can also look into camera spring modules i think ive seen before
--untested pseudocode
local RunService = game:GetService("RunService")
local cameraPart = Instance.new("Part", workspace)
cameraPart.Size = Vector3.new(1,1,1)
RunService:BindToRenderStep(Enum.RenderPriorty.Camera.Value + 1, function()
local targetPosition = rootPart.Position + rootPart.CFrame.LookVector * 2 -- adjust the 2 as needed
local newPosition = cameraPart.Position:Lerp(targetPosition, 0.5) -- adjust the 0.5 as needed
cameraPart.Position = newPosition
end)
I would look into a custom camera controller since it is pretty hard to have this effect with the default camera.
I’ll try to make a custom camera script but it’s pretty complicated.
EDIT: Just finished the script but I gotta eat lunch, will post soon!
Ok, this method uses a custom camera controller to kind of create the effect you wanted. It does have a few issues such as the camera being able to phase through walls and welded objects (like seats) moving with the player. It wouldn’t be too difficult to fix them though.
Here’s a video of the script:
It has to be short because the file size was too large :(
And here’s the script itself:
local Players = game:GetService("Players")
local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
-- Settings (quite a lot) --
local MAX_ZOOM = 128
local MIN_ZOOM = 4
local DEFAULT_ZOOM = 16
local SCROLL_SPEED = 10
local CAMERA_OFFSET_Y = 3
local ROTATION_SPEED_X = 10
local ROTATION_SPEED_Y = 10
local CAMERA_FX_OFFSET = 3 -- This is the setting you wanted
local CAMERA_SMOOTH_FACTOR = 0.25 -- This is the smoothing for that setting
local CAMERA_ROTATE_MAX_ANGLE = 50
local player = Players.LocalPlayer
local camera = workspace.CurrentCamera
camera.CameraType = Enum.CameraType.Scriptable
-- Get Character --
local character = player.Character or player.CharacterAdded:Wait()
local humanoidRootPart: Part = character:WaitForChild("HumanoidRootPart")
local humanoid: Humanoid = character:FindFirstChild("Humanoid")
-- Internal Properties --
local zoom = DEFAULT_ZOOM
local rotateOffset = Vector3.zero
local cameraRotateOffset = Vector3.zero
local cameraOffset = Vector3.zero
-- Make Camera Follow Character --
-- Updates the position of the camera
local function UpdateCamera()
-- Rotate the character
humanoidRootPart.CFrame = CFrame.new(humanoidRootPart.CFrame.Position) * CFrame.Angles(rotateOffset.X, rotateOffset.Y, rotateOffset.Z)
local cameraRotateOffsetCFrame = CFrame.Angles(cameraRotateOffset.X, cameraRotateOffset.Y, cameraRotateOffset.Z)
local rotatedHumanoidRootPartCFrame = humanoidRootPart.CFrame * cameraRotateOffsetCFrame
local lookVector = rotatedHumanoidRootPartCFrame.ZVector * zoom -- Technically actually uses Z Vector, not look vector
local extraOffset = Vector3.new(0, CAMERA_OFFSET_Y, 0) + cameraOffset
camera.CFrame = (humanoidRootPart.CFrame * cameraRotateOffsetCFrame) + lookVector + extraOffset
end
-- Camera Zoom --
UserInputService.InputChanged:Connect(function(input: InputObject)
if input.UserInputType == Enum.UserInputType.MouseWheel then
local zoomAmount = -input.Position.Z
local zoomDelta =
zoomAmount *
SCROLL_SPEED *
(0.2 + (math.map(zoom, MIN_ZOOM, MAX_ZOOM, 0, 1) * 0.8)) -- Smoothing factor
zoom = math.clamp(zoom + zoomDelta, MIN_ZOOM, MAX_ZOOM)
end
end)
-- Character Turn --
local isRightClicking = false
UserInputService.InputBegan:Connect(function(input: InputObject)
if input.UserInputType == Enum.UserInputType.MouseButton2 then
isRightClicking = true
UserInputService.MouseBehavior = Enum.MouseBehavior.LockCurrentPosition
end
end)
UserInputService.InputEnded:Connect(function(input: InputObject)
if input.UserInputType == Enum.UserInputType.MouseButton2 then
isRightClicking = false
UserInputService.MouseBehavior = Enum.MouseBehavior.Default
end
end)
UserInputService.InputChanged:Connect(function(input: InputObject)
if UserInputService.MouseBehavior == Enum.MouseBehavior.LockCenter then
isRightClicking = true
end
if input.UserInputType == Enum.UserInputType.MouseMovement and isRightClicking then
local mouseDeltaX = -input.Delta.X / camera.ViewportSize.X
local mouseDeltaY = -input.Delta.Y / camera.ViewportSize.Y
rotateOffset += Vector3.new(0, mouseDeltaX * ROTATION_SPEED_X, 0)
cameraRotateOffset += Vector3.new(mouseDeltaY * ROTATION_SPEED_Y, 0, 0)
-- Clamp the X
cameraRotateOffset = Vector3.new(
math.rad(math.clamp(math.deg(cameraRotateOffset.X), -CAMERA_ROTATE_MAX_ANGLE, CAMERA_ROTATE_MAX_ANGLE)),
cameraRotateOffset.Y,
cameraRotateOffset.Z
)
end
end)
-- Camera Strafe/Walk FX --
-- Run this before UpdateCamera() for strafe FX
local function UpdateCameraOffset(deltaTime: number)
-- Average the inverse move vector and the camera offset
local moveVector = -humanoid.MoveDirection
-- Returns the weighted average between 2 vector3s
local function AverageWeightedVectors(firstVector: Vector3, firstWeight: number, secondVector: Vector3, secondWeight: number)
local AXES = {"X", "Y", "Z"}
local newVectorParameters = {}
for index, axis in AXES do
newVectorParameters[index] = ((firstVector[axis] * firstWeight) + (secondVector[axis] * secondWeight)) / (firstWeight + secondWeight)
end
local newVector = Vector3.new(table.unpack(newVectorParameters))
return newVector
end
cameraOffset = AverageWeightedVectors(cameraOffset, CAMERA_SMOOTH_FACTOR, moveVector * CAMERA_FX_OFFSET, deltaTime)
end
-- Run Service Events --
RunService.PreRender:Connect(function(deltaTime: number)
UpdateCameraOffset(deltaTime)
UpdateCamera()
end)
There’s a bunch of settings you can change to make this work to your liking!
Forgot to mention, the only way the camera moves is when you right click and drag so you would have to modify this to make it mobile friendly.