The easiest way to do this is simply with parts on the client.
local Camera = workspace.CurrentCamera
local Part = workspace.CameraPart --your part
Camera.CameraType = Enum.CameraType.Scriptable
Camera.CFrame = Part.CFrame
Then as for moving it for cutscenes, you would simply tween your part, however you have to CFrame the camera to the part in a fast loop in order for it to follow, that should be it.
To return the camera to the player’s character is as easy as setting its CameraType to Enum.CameraType.Custom.
local RunService = game:GetService("RunService")
local playerModel = script.Parent
local humanoid = playerModel:WaitForChild("Humanoid")
local function updateBobbleEffect()
local now = tick()
if humanoid.MoveDirection.Magnitude > 0 then -- Are we walking?
local velocity = humanoid.RootPart.Velocity
local bobble_X = math.cos(now * 9) / 5
local bobble_Y = math.abs(math.sin(now * 12)) / 5
local bobble = Vector3.new(bobble_X,bobble_Y,0) * math.min(1, velocity.Magnitude / humanoid.WalkSpeed)
humanoid.CameraOffset = humanoid.CameraOffset:lerp(bobble,.25)
else
-- Scale down the CameraOffset so that it shifts back to its regular position.
humanoid.CameraOffset = humanoid.CameraOffset * 0.75
end
end
-- Update the effect on every single frame.
RunService.RenderStepped:Connect(updateBobbleEffect)
Its literally written on the dev hub. As for ur other question, localscript changes replicates only 2 client.
The reason I don’t like to stick to the devhub and don’t always look at them is because I don’t feel like their giving me much info, but when I talk to people on the devforum, they can easily help me.
I don’t understand the parts from local now = tick() to the else. Can you explain to me how that works?