Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
1

How can I make the camera always look at one face of a block?

Asked by 7 years ago

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.

0
What exactly are you trying to do? Do you want to have the camera near the part looking at a particular face of it? LightningRoMan 100 — 7y
0
@LightningRoMan I want to make a main menu for a game with the camera facing at a structure Activatted 47 — 7y
0
the lookVector property of a CFrame might help. Try with camera.CFrame = CFrame.new(somePos, structurePart.CFrame.lookVector) LightningRoMan 100 — 7y

1 answer

Log in to vote
3
Answered by 7 years ago

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
Ad

Answer this question