So, here is what I am trying to achieve in human english:
I have a sphere in zero gravity, that can move left-right-forward-backward with ‘WASD’, and tilt around its lookVector axis using ‘Q’ & ‘E’. The sphere has a ‘front’ and ‘top’, just like a spaceship. I want to create a system kind of like the ‘fly’ command found in admin commands, except instead of hitting a vertical look limit, it can rotate upward or downward indefinitely, and to the right and left, like a globe if that makes sense.
In this case, the camera would have full 360 degree rotation on the Y and X axis. The X axis being ‘looking down or up’, which would have the same orientation as the spheres RightVector.
Now, this is just the Y and X axis. Now comes the Z axis, the sphere’s ability to tilt.
I want whatever new orientation the tilting creates to be treated as a normal upright orientation, so that the camera can have the same functionality no matter what the orientation is.
And to add to that, the camera should rotate the sphere with it, like the ‘fly’ command as mentioned above.
There are probably way better ways to do this, but I wrote something for you real quick to try to give you a foundation that you can improve upon.
My script currently has editable variables in the form of:
local Target = workspace.Part can be used to modify what the Camera is looking at.
local CameraOffset = CFrame.new(0, 0, 5) can be used to change how far away the camera is from the target.
What I basically have done step by step is this:
Set the CameraType to Scriptable in order for it to be manipulated.
Set the CFrame of the Camera to the part, with an offset added so it is not inside the part. Camera.CFrame = CFrame.new(Target.Position) * CFrame.Angles(math.rad(VerticalRotationAngle), 0, 0) * CameraOffset
Used UserInputService to get input from the player, i.e W,A,S,D
If the key is W or S then we modify the vertical angle, adding if going forward and subtracting if going backwards.
Set the CFrame of the Camera based on the calculations provided by the while Held do loop and then have an event to detect when the player stops holding the key at the end of the script.
If player tries to use more than one key, the script currently has a debounce, but you can probably add a function to your script to support two axis movement at once.
-- Made by TDK on 9/20/2019
local Player = game.Players.LocalPlayer
local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local CameraOffset = CFrame.new(0, 0, 5)
local Character = Player.Character
local Target = workspace.Part
local VerticalRotationAngle = 0
local HorizontalRotationAngle = 0
Held = false
-- Set CameraType
repeat wait() until Player.Character
Camera = workspace.CurrentCamera
Camera.CameraType = "Scriptable"
Camera.CameraSubject = Target
Camera.CFrame = CFrame.new(Target.Position) * CFrame.Angles(math.rad(VerticalRotationAngle), 0, 0) * CameraOffset
-- Collect Input from Player
UserInputService.InputBegan:Connect(function(input, gpe)
if gpe or Held then return end
if input.KeyCode == Enum.KeyCode.W then
Held = true
while Held do
if Held == false then return end
Camera.CFrame = CFrame.new(Target.Position) * CFrame.Angles(math.rad(VerticalRotationAngle), math.rad(HorizontalRotationAngle), 0) * CameraOffset
VerticalRotationAngle = VerticalRotationAngle + 1
RunService.Stepped:Wait()
end
elseif input.KeyCode == Enum.KeyCode.S then
Held = true
while Held do
if Held == false then return end
Camera.CFrame = CFrame.new(Target.Position) * CFrame.Angles(math.rad(VerticalRotationAngle), math.rad(HorizontalRotationAngle), 0) * CameraOffset
VerticalRotationAngle = VerticalRotationAngle - 1
RunService.Stepped:Wait()
end
elseif input.KeyCode == Enum.KeyCode.A then
Held = true
while Held do
if Held == false then return end
Camera.CFrame = CFrame.new(Target.Position) * CFrame.Angles(math.rad(VerticalRotationAngle), math.rad(HorizontalRotationAngle), 0) * CameraOffset
HorizontalRotationAngle = HorizontalRotationAngle - 1
RunService.Stepped:Wait()
end
elseif input.KeyCode == Enum.KeyCode.D then
Held = true
while Held do
if Held == false then return end
Camera.CFrame = CFrame.new(Target.Position) * CFrame.Angles(math.rad(VerticalRotationAngle), math.rad(HorizontalRotationAngle), 0) * CameraOffset
HorizontalRotationAngle = HorizontalRotationAngle + 1
RunService.Stepped:Wait()
end
end
end)
-- Handle player letting go of input
UserInputService.InputEnded:Connect(function(input, gpe)
if gpe then return end
Held = false
end)
I really appreciate your great response. Unfortunately, that wasn’t what I was looking for exactly. I managed to figure it out on my own eventually. I want to give you the solution for trying so hard to help me out. Thank you.