Upside down camera that can still be controlled like a normal camera by the player?

Hello! I’ve been searching for a perfect answer for a while today and I decided to just give up and write a dev forum post. Thank you to everyone that responds in advance!

The Goal: Making an upside down camera that can still be controlled by the player as if it’s normal, just upside-down.

What I’ve tried and searched for: setting the script’s camera to scriptable and setting the cframe via renderstepped in runservice, which doesn’t let you control the camera, allowing the FOV with math.clamp(x,min,max) but it didn’t function and, normally, the FOV on roblox cannot go below.

The script (although I don’t think it’s neccessary and or will help that much): (also ignore the formatting of the script please, it’s probably really bad…)

local CS=game:GetService("CollectionService")
local RS=game:GetService("RunService")
local TS=game:GetService("TweenService")

for _,v in pairs(CS:GetTagged("RotateCam")) do
	local finalcf
	v.Touched:Connect(function(hit)
		if hit.Parent:FindFirstChild("Humanoid") then
			workspace.CurrentCamera.CameraType=Enum.CameraType.Follow -- this is here just to reset the players' camera
			wait()
			workspace.CurrentCamera.CameraType=Enum.CameraType.Scriptable
			local cameracfa=CFrame.Angles(math.rad(180),0,0)
			--finalcf=cameracfa+hit.Parent:FindFirstChild("HumanoidRootPart").Position+Vector3.new(0,0,-15)
			--local tween=TS:Create(workspace.CurrentCamera,TweenInfo.new(2,Enum.EasingStyle.Quad,Enum.EasingDirection.Out,0,false,0),{CFrame = finalcf}):Play()
			--tween.Completed:Connect(function()
				RS.RenderStepped:Connect(function()
				wait()
				workspace.CurrentCamera.FieldOfView=math.clamp(-130,-130,-130)
					finalcf=cameracfa+hit.Parent:FindFirstChild("HumanoidRootPart").Position+Vector3.new(0,0,-15)
					workspace.CurrentCamera.CFrame=finalcf
				end)
			--end)
		end
	end)
end

Try and help if you can, please…

1 Like

For my camera system, to get the next CFrame I would start by offsetting it in ObjectSpace so its centered at the head, then I would rotate it then offset it from the LookVector for the distance from the player. During the second step of the calculation, i apply the horizontal rotation first, and the vertical second, but for your example, we would apply a roll (CFrame.Angles(0,0,#)) first, then apply the next two transformations.

nextCFrame *= CFrame.Angles(0,0,math.rad(180)) --Flipping the camera
nextCFrame *=  CFrame.Angles(0,math.rad(-look.X),0) --Turning the camera
nextCFrame *= CFrame.Angles(math.rad(-look.Y),0,0) --Tilting the camera up and down

image
We rotate on the Z-Axis first, then turn the camera around on the Y-Axis, and finally tilt it up or down on the X-Axis.
I calculated the look.X and look.Y and incremented them from UserInputService:GetMouseDelta(). They are still in degrees, so we have to convert them into radians.

Edit:
You would have to make a new camera system, since there is no easy way to update your camera every frame. My approach was to create a Camera class with OOP, which held basic functions for making a new camera and properties, and modules under that Camera class which held functions for calculating the camera’s CFrame. Because of my approach, it made it impossible to edit the camera from other scripts, and only the local script that created the camera could edit the properties, but there are other ways to implement access from outside scripts.

2 Likes