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?
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.
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.
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.
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?
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
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?