I know how to make the camera scriptable and such but I don't know how to rotate it properly, only move it. help? this is what I currently got:
local target = workspace.Kek local camera = workspace.CurrentCamera camera.CameraType = Enum.CameraType.Scriptable camera.CameraSubject = target camera.CoordinateFrame = CFrame.new(target.Position) * CFrame.Angles(-.5,-.1,-.5)
I dont know how to insert the CFrame.Angles without multiplying. Is there a variable for it? Thanks in advance.
Warning: Overkill answer below. Look at the code at the bottom for a generalized solution. Read the answer below if you want to learn :)
Camera.CoordinateFrame
is the defacto way to move the camera when the CameraType is "Scriptable".
CFrame.new()
has a couple of different ways it can build a CFrame (which is just a representation of position and rotation) depending on what you put in the parenthesis.
One of these is CFrame.new(position, lookAt)
, where position
is a Vector3 representing the camera's position, and lookAt
is also a Vector3 representing the position to look towards.
I'm sure you see where we're going with this.
You can simple set position
to, say, 5 studs in front of the part (i.e. Part.Position + Vector3.new(0, 0, -5)
) and lookAt
to Part.Position
, and it will look at the part's front face. So you have:
local target = workspace.Kek local camera = workspace.CurrentCamera camera.CameraType = Enum.CameraType.Scriptable local position = target.Position + Vector3.new(0, 0, -5) local lookAt = target.Position camera.CoordinateFrame = CFrame.new(position, lookAt)
But wait! What if target
is rotated? Simply adding that offset won't work, since it's in world space, which means "not relative to anything but the sky". One way is to take advantage of CFrames being applied in object space by default:
local position = target.CFrame * CFrame.new(0, 0, -5) -- get the target's position and rotation information, add -5 in the local z axis. position = position.p + part.Position -- convert it to a Vector3 and add it
But perhaps a more intuitive-looking way is to use a method of CFrame to get the world-space representation of an object-space vector:
local position = part.Position + part.CFrame:vectorToWorldSpace(Vector3.new(0, 0, -5))
That should work for your purposes.
For completeness and because I'm bored, I packaged everything in a function that allows you to simply specify a part, a face (Enum.NormalId
or just "Right"
, "Up"
, "Back"
, etc.), and a distance from the center of the part:
local function LookAtFace(part, face, distance) face = face or Enum.NormalId.Front -- Make default face Front distance = distance or 10 -- Make default distance 10 studs if (type(face) == "string") then face = Enum.NormalId[face] -- Get face in enum form, if it isn't already end local position = part.Position local offset = part.CFrame:vectorToWorldSpace(Vector3.FromNormalId(face)) -- Gets the Vector3 from the face you put in and rotate it to world space workspace.CurrentCamera.CoordinateFrame = CFrame.new(position + distance*offset, position) end -- Example usage: workspace.CurrentCamera.CameraType = Enum.CameraType.Scriptable LookAtFace(workspace.Kek, "Front", 20) -- 20 studs away looking at front face LookAtFace(workspace.Kek, Enum.NormalId.Right, 20) -- 20 studs away looking at right face