Allowing the camera to freely rotate to any orientation when panned?

Im making a project were I would like the players to be able to rotate their camera any direction.

if you pan the camera up or down and try to keep going, you wont be able to rotate any further as the camera appears to be “Stuck” on the Y axis, keeping the entire game view leveled.

I don’t want this as seeing the map from any angle is intentional and will add to the overall experience of the game.

to be honest I don’t even know were to start, the simplest way would be to fix the camera to the players head, but to keep an explanation at a minimum, the character will often be spinning freely which means if the camera is fixed to the head it will spin wildly.

could it be as simple as disabling/enabling something or will I have to get really mathematical to achieve this behavior?

1 Like

Could you go into more detail or like give an example of what your trying to achieve a reference if you will.

I found a good example of the camera behavior Im trying to replicate

the player is able to rotate their camera with complete freedom, if you rotate 180 degrees up, your camera will be on the other side of your character, but will be upside down, in a normal roblox game you could not do this as the camera just wont go past the top of your head.

Ill help you out tommorow I have to go right now sorry

while u were away I created an exact example of what Im trying to do:

robloxapp-20200725-1052237.wmv (2.5 MB)

in this example, the camera is attached to a part in a model that will use CFrame.Angles to rotate itself, the red ball represents the characters model, the model rotating represents the player panning their camera.
in the example the camera can freely rotate in any direction. it will of course always face the character but its orientation (such as appearing upside down) on any other axis doesn’t matter.

To make the custom camera like what was shown in that game you need to make your own camera behavior. After setting the the camera type to Enum.CameraType.Scriptable so that you have full control of the camera’s movement.

Then by using UserInputService:GetMouseDelta you can use that Vector2 value to determine how the mouse has moved from the last rendered frame. Using those to modify the current CFrame of the camera.

wait, just curious but aside from causing the camera to begin panning how does the mouse affect the camera and how would it solve the problem?

If I remember correctly that mouse delta lets you know how much the mouse has moved since the last render frame. The reason it’s important is since the you have your camera set to Scriptable their is no limits in any rotational axis allowing you to do full rotation.

ive got this so far:

local plr = game.Players.LocalPlayer
local uis = game:GetService("UserInputService")
local rs = game:GetService("RunService")


function updatecam()
local delta = uis:GetMouseDelta()
print(delta)
end




rs:BindToRenderStep("MeasureMouseMovement",Enum.RenderPriority.Input.Value,updatecam)

so If im doing this correctly, I assume all I need to do now is make the camera scriptable and then change the CFrame of the camera to the vector2 I just printed.
but how do I convert a Vector2 into a CFrame?

You will need to separate the Vector2 into it’s different components and add those back into the 2 diffrent rotation axises of the camera’s CFrame.

local plr = game.Players.LocalPlayer
local uis = game:GetService("UserInputService")
local rs = game:GetService("RunService")
local cam = workspace.CurrentCamera
cam.CameraType = "Scriptable"

function updatecam()
local delta = uis:GetMouseDelta()
print(delta)
local x = delta.X
local y = delta.Y
cam.CFrame = cam.CFrame * CFrame.new(Vector3.new(x,y,0))
end




rs:BindToRenderStep("MeasureMouseMovement",Enum.RenderPriority.Input.Value,updatecam)

while I think I got some of the rotation right, I noticed an issue.
when I make the camera scriptable, the camera wont pan like the default camera, while this is expected, getmousedelta will no longer print anything more than 0,0. it looks like if the camera isnt moving in the first place, then those numbers wont increase at all.
I tried seeing if this was true by keeping the camera at default, and it began printing more than 0,0 again. am I doing something wrong?

Well youll def be using CFrame.Angles, hm well how about you check when you cant go past a certain Y of the Camera’s CFrame you override it and keep going Im not sure

Make sure you do Enum.CameraType.Scriptable. This just ensures that the game knows what you are trying to do here.

same results, no change in behavior after that change.

And you need to covert that Vector2 into CFrame.Angles. Right now you are just moving the camera’s position.

local plr = game.Players.LocalPlayer
local uis = game:GetService("UserInputService")
local rs = game:GetService("RunService")
local cam = workspace.CurrentCamera
cam.CameraType = Enum.CameraType.Scriptable

function updatecam()
local delta = uis:GetMouseDelta()
print(delta)
local x = delta.X
local y = delta.Y
cam.CFrame = cam.CFrame * CFrame.Angles(math.rad(x),math.rad(y),0)
end




rs:BindToRenderStep("MeasureMouseMovement",Enum.RenderPriority.Input.Value,updatecam)

movement is still non existent. but when it prints the vector2 its empty, its 0,0.
it looks like as long as the camera isnt moving, the vector2 will always be 0,0.
doesnt this mean that getmousedelta is useless when trying to use it to move the camera?

found the problem, the mouse had to be locked but since scriptable prevents that behavior I had to do it manually:

local plr = game.Players.LocalPlayer
local uis = game:GetService("UserInputService")
local rs = game:GetService("RunService")
local cam = workspace.CurrentCamera
local mouse = plr:GetMouse()
cam.CameraType = Enum.CameraType.Scriptable
cam.CFrame = plr.Character.HumanoidRootPart.CFrame * CFrame.new(plr.Character.HumanoidRootPart.CFrame.LookVector * -15,plr.Character.HumanoidRootPart.Position)

mouse.Button2Down:Connect(function()
uis.MouseBehavior = Enum.MouseBehavior.LockCurrentPosition
end)
mouse.Button2Up:Connect(function()
uis.MouseBehavior = Enum.MouseBehavior.Default
end)



function updatecam()
local delta = uis:GetMouseDelta()
print(delta)
local x = delta.X
local y = delta.Y
cam.CFrame = cam.CFrame * CFrame.Angles(math.rad(-y),math.rad(-x),math.rad(0))
end




rs:BindToRenderStep("MeasureMouseMovement",Enum.RenderPriority.Input.Value,updatecam)

I still need to find a way to get the camera to pan around the character as right now it just rotates.

7 Likes

did you find out how to make it pan around the character yet? i know its been 3 years lol but im trying to acomplish this same this right now.

1 Like