How do roleplay games achieve this type of camera, where the camera shifts to the left (or right), while still allowing the player to rotate around their character?
I’ve tried to simply set the Humanoid.CameraOffset but it results in the camera pivoting around the new camera offset rather than the player, I’m just looking for the shifting of the camera left, while still pivoting around the character
Would be grateful is anyone had any ideas , is this done by humanoid camera offset, or something with the camera subject or camera state??
However, this is inconsistent on different size screens, and the players camera is still fixed, so I’m looking for a way to make the player able to pivot around their camera such as the video in the original post.
The screen space module is as attached btw ScreenSpace.lua (6.7 KB)
Currently, this is the best I’ve got. However it’s really buggy, the camera always seems to be colliding with something and this weird black circle appears in the sky when I look up. Anyone know what’s going on here, or how I could achieve this a different way?
Here’s a module I found from here
-- black frames not included
local RunService = game:GetService("RunService")
local Workspace = game:GetService("Workspace")
local Camera = Workspace.CurrentCamera
local Module = {}
Module.Position = UDim2.new(0, 0, 0, 0)
Module.Size = UDim2.new(1, 0, 1, 0)
local function UDim2Absolute(udim2)
local viewSize = Camera.ViewportSize
return Vector2.new(
(udim2.X.Scale * viewSize.X) + udim2.X.Offset,
(udim2.Y.Scale * viewSize.Y) + udim2.Y.Offset
)
end
--- Compute offset
function Module._computePosition()
local viewSize = Camera.ViewportSize
local aspectRatio = viewSize.X / viewSize.Y
local offset = UDim2Absolute(Module.Position)
local position = offset / viewSize
-- Taken from ScreenSpace
local hFactor = math.tan(math.rad(Camera.FieldOfView) / 2)
local wFactor = hFactor * aspectRatio
return -position.X * wFactor * 2, position.Y * hFactor * 2
end
function Module._computeSize()
local size = UDim2Absolute(Module.Size) / Camera.ViewportSize
return size.X, size.Y
end
function Module._getOffset()
local x, y = Module._computePosition()
local w, h = Module._computeSize()
return CFrame.new(
0, 0, 0,
w, 0, 0,
0, h, 0,
x, y, 1
)
end
--- Handler
function Module.Start()
RunService:BindToRenderStep("ViewportCamera", Enum.RenderPriority.Camera.Value + 1, function()
Camera.CFrame = Camera.CFrame * Module._getOffset()
end)
end
function Module.Stop()
RunService:UnbindFromRenderStep("ViewportCamera")
end
return Module
You need to parent the sun rays to nil while using the camera like this otherwise those black circles appear. A bit of a workaround but I’m fine with it.
Clamping the X value seemed to do most of the trick though! x = math.clamp(x, -0.663, 0.663)
Heres the full modified version of that module
local RunService = game:GetService("RunService")
local Workspace = game:GetService("Workspace")
local Camera = Workspace.CurrentCamera
local Module = {}
Module.Position = UDim2.new(0, 0, 0, 0)
Module.Size = UDim2.new(1, 0, 1, 0)
local function UDim2Absolute(udim2)
local viewSize = Camera.ViewportSize
return Vector2.new(
(udim2.X.Scale * viewSize.X) + udim2.X.Offset,
(udim2.Y.Scale * viewSize.Y) + udim2.Y.Offset
)
end
--- Compute offset
function Module._computePosition()
local viewSize = Camera.ViewportSize
local aspectRatio = viewSize.X / viewSize.Y
local offset = UDim2Absolute(Module.Position)
local position = offset / viewSize
-- Taken from ScreenSpace
local hFactor = math.tan(math.rad(Camera.FieldOfView) / 2)
local wFactor = hFactor * aspectRatio
return -position.X * wFactor * 2, position.Y * hFactor * 2
end
function Module._computeSize()
local size = UDim2Absolute(Module.Size) / Camera.ViewportSize
return size.X, size.Y
end
function Module._getOffset()
local x, y = Module._computePosition()
local w, h = Module._computeSize()
x = math.clamp(x, -0.663, 0.663) -- this line was vital
return CFrame.new(
0, 0, 0,
w, 0, 0,
0, h, 0,
x, y, 1
)
end
--- Handler
local lighting = game:GetService("Lighting")
local sunRay = nil
local beforeFovMode = Camera.FieldOfViewMode -- keep track of whatever our existing fov mode is
function Module.Start()
Module.Position = UDim2.new(-0.25, 0, 0, 0)
Module.Size = UDim2.new(1, 0, 1, 0)
local ray= lighting:FindFirstChildWhichIsA("SunRaysEffect")
if ray then
sunRay = ray
ray.Parent = nil
end
Camera.FieldOfViewMode = Enum.FieldOfViewMode.MaxAxis
RunService:BindToRenderStep("ViewportCamera", Enum.RenderPriority.Camera.Value + 1, function()
Camera.CFrame = Camera.CFrame * Module._getOffset()
end)
end
function Module.Stop()
RunService:UnbindFromRenderStep("ViewportCamera")
Camera.FieldOfViewMode = beforeFovMode
if sunRay then
sunRay .Parent = lighting
end
end
return Module