Camera/Body gets rotated 180 degrees when facing downwards and upwards

I’m making realistic camera movement for my game, but my body (or camera, but I’m pretty sure it’s my body) rotates 180 degrees whenever I look straight down or straight up. From what I’ve managed to figure out so far, I know that the issue lies in the CameraMotion local script, and that removing the line that creates view bobbing fixes the whole problem, with the downside being I no longer get view bobbing. I’m wondering if there is a way I can keep my calculations for view bobbing while also fixing my body spasming out.

The code:

--{Services}--
local RunService = game:GetService("RunService")
local UserInputService = game:GetService("UserInputService")

--{Variables}--
local  player = game.Players.LocalPlayer
local Character = player.Character or player.CharacterAdded:Wait()
local RootPart = Character:FindFirstChild("HumanoidRootPart")

local Camera = workspace.CurrentCamera
local CameraSettings = require(script.Settings)

local Rotation = 0
local CurrentVelocity = 0
local Drift = 0
local t, x, y, z : number

--{Functions}--
local function Lerp(a, b, t)
	return a + (b - a) * t
end

local function GetVelocityMagnitude()
	return math.round(Vector2.new(RootPart.AssemblyLinearVelocity.X, RootPart.AssemblyLinearVelocity.Z).Magnitude)
end

local function CalculateCurve(Base : number, Set : number) : number
	return math.sin(os.clock() * Base) * Set
end

local function GetSwayVal(x:number, y:number) : CFrame
	return CFrame.new(Vector3.new(x, y, 0), Vector3.new(x*.95, y*.95, -10)) + Camera.CFrame.Position
end

local function GetMouseDrift(Drift : number, MouseDelta : Vector2, dt : number) : number
	return Lerp(Drift, math.clamp(MouseDelta.X, CameraSettings.DriftMin, CameraSettings.DriftMax), (CameraSettings.BaseMult * dt))
end

local function ConvCFrameToOrientation(_CFrame: CFrame, Velocity)
	local setX, setY, setZ = _CFrame:ToOrientation()
	setZ -= 0.02 * (1 + (Velocity / 16) * (Velocity / 16)) --offset
	--setZ += 0.1
	
	return Vector3.new(math.deg(setX), math.deg(setY), math.deg(setZ))
end

local function CameraMotionFunction(deltaTime)
	local MouseDelta = UserInputService:GetMouseDelta()
	
	t = os.clock()
	
	x = math.cos(t * CameraSettings.BaseSway) * CameraSettings.SetSway
	y = math.sin(t * CameraSettings.BaseSway) * CameraSettings.SetSway
	local sway = GetSwayVal(x,y)
	
	local Velocity = Lerp(CurrentVelocity, GetVelocityMagnitude(), CameraSettings.BaseNumLerp)
	Drift = GetMouseDrift(Drift, MouseDelta, deltaTime)
	
	CurrentVelocity = Velocity
	Rotation = Lerp(Rotation, math.clamp(MouseDelta.X, CameraSettings.CustomSwayZVal, 10), 10 * deltaTime)
	Camera.CFrame *= CFrame.Angles(0, 0, math.rad(Rotation))
	
	Camera.CFrame = Camera.CFrame
		* CFrame.new(0, CalculateCurve(CameraSettings.BaseFreq, CameraSettings.SetFreq) * Velocity / CameraSettings.BaseMult, 0) -- Removing this line fixes the problem but discards the calculations for view bobbing
		* CFrame.Angles(0, 0, math.rad(CalculateCurve(CameraSettings.BaseRot / 2, CameraSettings.SetRot * 2) * Velocity / CameraSettings.BaseMult) + math.rad(Drift))

	Character.Humanoid.CameraOffset = ConvCFrameToOrientation(sway, Velocity)
end

--{Signals}--
RunService:BindToRenderStep("CameraSway", Enum.RenderPriority.Camera.Value + 1, CameraMotionFunction)

I put a comment beside the line for view bobbing

Try setting the camera slightly in front of your characters cframe so the camera isn’t staring down the middle.

I’ve tried many offsets to see if that was the problem, but all it does is expand how far my character gets flipped. It’s like the camera is the pivot point of where my character flips.

It’s just a visual glitch in my mind, are you able to limit the camera’s directional range so they can’t look at their feet?

I can probably figure out a way to do that, but I’m planning to allow players to pick things up later on in development, and that also includes things on the ground. For now, I have the view bobbing set to very little because somehow that avoids the glitch while making the camera movement somewhat how I wanted it to.

1 Like