Un CFrame, abreviatura de Marco de Coordenadas, es un tipo de dato utilizado para rotar y posicionar objetos 3D. Como propiedad de un objeto o una unidad independiente, un CFrame contiene coordenadas globales X, Y y Z así como datos de rotación para cada eje. Además, CFrames contienen funciones útiles para trabajar con objetos en el espacio 3D.
Posicionar un CFrame
Puedes crear un CFrame vacío en la posición predeterminada de (0, 0, 0) usando CFrame.new(). Para posicionar un CFrame en un punto específico, proporciona coordenadas X, Y y Z como argumentos a CFrame.new(). En el siguiente ejemplo, la propiedad CFrame de la parte redBlock cambia a newCFrame, reubicándola en (-2, 2, 4).
local Workspace = game:GetService("Workspace")local redBlock = Workspace.RedBlock-- Crear nuevo CFramelocal newCFrame = CFrame.new(-2, 2, 4)-- Sobrescribir el CFrame actual del bloque rojo con el nuevo CFrameredBlock.CFrame = newCFrame


Alternativamente, puedes proporcionar una nueva posición Vector3 a CFrame.new() y lograr el mismo resultado:
local Workspace = game:GetService("Workspace")local redBlock = Workspace.RedBlock-- Crear nuevo CFramelocal newVector3 = Vector3.new(-2, 2, 4)local newCFrame = CFrame.new(newVector3)-- Sobrescribir el CFrame actual del bloque rojo con el nuevo CFrameredBlock.CFrame = newCFrame
Rotar un CFrame
Para crear un CFrame rotado, usa el constructor CFrame.fromEulerAnglesXYZ(), proporcionando un ángulo de rotación en radianes para los ejes deseados. Los parámetros de CFrame.fromEulerAnglesXYZ() están en radianes, no en grados; si prefieres grados, usa math.rad() para convertir grados a radianes. En el siguiente ejemplo, la parte redBlock rota 45 grados en sentido antihorario sobre su eje Y.
local Workspace = game:GetService("Workspace")local redBlock = Workspace.RedBlock-- Crear nuevo CFrame rotadolocal newCFrame = CFrame.fromEulerAnglesXYZ(0, math.rad(45), 0)-- Sobrescribir el CFrame actual del bloque rojo con el nuevo CFrameredBlock.CFrame = newCFrame


Orientar un CFrame hacia un punto
Puedes usar CFrame.lookAt() para apuntar la superficie frontal de un CFrame a un punto específico en el mundo. El siguiente ejemplo posiciona redBlock en (0, 3, 0) y apunta su superficie frontal, marcada por el círculo blanco, hacia la parte blueCube.
local Workspace = game:GetService("Workspace")local redBlock = Workspace.RedBlocklocal blueCube = Workspace.BlueCuberedBlock.Position = Vector3.new(0, 3, 0)-- Apuntar la superficie frontal del bloque rojo hacia el cubo azulredBlock.CFrame = CFrame.lookAt(redBlock.Position, blueCube.Position)


Desplazar un CFrame
Para desplazar un objeto por un número específico de studs desde su posición actual, suma o resta un Vector3 a o desde un nuevo CFrame en la posición del objeto. Para obtener una posición Vector3 adecuadamente formateada de un objeto para usar con CFrame.new(), como se ve aquí, su propiedad Position (redBlock.Position) es un atajo conveniente.
local Workspace = game:GetService("Workspace")local redBlock = Workspace.RedBlockredBlock.CFrame = CFrame.new(redBlock.Position) + Vector3.new(0, 1.25, 0)


Puedes usar la misma técnica para desplazar un objeto desde la posición de otro objeto. En el siguiente ejemplo, un Vector3 se suma a un nuevo CFrame creado en la posición del cubo azul en lugar de la posición del bloque.
local Workspace = game:GetService("Workspace")local redBlock = Workspace.RedBlocklocal blueCube = Workspace.BlueCuberedBlock.CFrame = CFrame.new(blueCube.Position) + Vector3.new(0, 2, 0)


Orientación dinámica del CFrame
Los constructores CFrame.new() y CFrame.fromEulerAnglesXYZ() reposicionan o rotan un objeto en una orientación específica dentro del mundo, pero a veces no puedes confiar en una posición y un ángulo de rotación fijos. Por ejemplo:
- Colocar un tesoro flotante directamente frente a un jugador que puede estar de pie en cualquier lugar del mundo, mirando en cualquier dirección.
- Hacer que un genio mágico aparezca directamente sobre el hombro derecho de un jugador.
En estos casos, usa los métodos de CFrame en lugar de sus constructores.
Posición relativa
La función CFrame:ToWorldSpace() transforma el CFrame de un objeto — respetando su propia orientación local — a una nueva orientación mundial. Esto lo hace ideal para desplazar una parte con respecto a sí misma o a otro objeto, independientemente de cómo esté posicionada/rotada actualmente.
En el siguiente ejemplo, la parte redBlock se desplaza 2 studs con respecto al eje Y del cubo azul (la flecha verde que lo atraviesa) y no con respecto al eje Y global que apunta directamente hacia arriba.
local Workspace = game:GetService("Workspace")local redBlock = Workspace.RedBlocklocal blueCube = Workspace.BlueCubelocal offsetCFrame = CFrame.new(0, 2, 0)redBlock.CFrame = blueCube.CFrame:ToWorldSpace(offsetCFrame)


Rotación relativa
También puedes usar CFrame:ToWorldSpace() para rotar un objeto en relación consigo mismo. En el siguiente ejemplo, la parte redBlock rota 70 grados en sentido antihorario sobre su eje Y y 20 grados en sentido horario sobre su eje Z.
local Workspace = game:GetService("Workspace")local redBlock = Workspace.RedBlocklocal rotatedCFrame = CFrame.fromEulerAnglesXYZ(0, math.rad(70), math.rad(20))redBlock.CFrame = redBlock.CFrame:ToWorldSpace(rotatedCFrame)


Orientar una superficie específica hacia un punto
Puedes hacer que el frente de un objeto mire hacia otro objeto proporcionando un punto Vector3 como segundo parámetro de CFrame.new(). También puedes usar rotación relativa para hacer que cualquier cara del objeto apunte hacia un punto Vector3. El siguiente ejemplo realiza dos operaciones consecutivas de CFrame:
- Apuntar la superficie frontal, marcada por el círculo blanco, hacia el objetivo.
- Rotar el CFrame para que la superficie superior, marcada por el círculo negro, apunte hacia el objetivo.
local Workspace = game:GetService("Workspace")local redBlock = Workspace.RedBlocklocal blueCube = Workspace.BlueCube-- Apuntar la superficie frontal del bloque rojo hacia el cubo azulredBlock.CFrame = CFrame.lookAt(redBlock.Position, blueCube.Position)-- Rotar CFrame en relación a sí mismo para que la superficie superior (no frontal) apunte hacia el cubo azullocal rotatedCFrame = CFrame.fromEulerAnglesXYZ(math.rad(-90), 0, 0)redBlock.CFrame = redBlock.CFrame:ToWorldSpace(rotatedCFrame)


Encontrar un punto entre puntos
Puedes usar interpolación lineal, o lerp, para posicionar un CFrame entre dos puntos. En el siguiente ejemplo, la parte redBlock se reposiciona entre las partes greenCube y cyanCube. El valor de 0.7 lo coloca al 70% de la distancia del cubo verde.
local Workspace = game:GetService("Workspace")local redBlock = Workspace.RedBlocklocal greenCube = Workspace.GreenCubelocal cyanCube = Workspace.CyanCuberedBlock.CFrame = greenCube.CFrame:Lerp(cyanCube.CFrame, 0.7)

