Detectores de arrastre en 3D

*Este contenido se traduce usando la IA (Beta) y puede contener errores. Para ver esta página en inglés, haz clic en aquí.

La instancia DragDetector facilita y fomenta la interacción con objetos 3D en una experiencia, como abrir puertas y cajones, deslizar una pieza, agarrar y lanzar una bola de boliche, tirar hacia atrás y disparar una resortera, y mucho más. Las características clave incluyen:

Hacer objetos arrastrables

Para hacer que cualquier parte o modelo sea arrastrable, simplemente añade un DragDetector como un descendiente directo.

  1. En la ventana de Explorador, pasa el mouse sobre el Part, MeshPart o Model y haz clic en el botón ⊕. Se mostrará un menú contextual.

  2. Desde el menú, inserta un DragDetector.

  3. Por defecto, el objeto ahora será arrastrable en el plano de tierra, pero puedes personalizar su DragStyle, definir cómo responde al movimiento y opcionalmente aplicar límites de eje o movimiento.

Personalizar detectores de arrastre

Estilo de arrastre

DragDetectors mapea el movimiento del cursor a líneas y planos virtuales para calcular el movimiento 3D propuesto. A través de la propiedad DragStyle, puedes elegir entre diferentes mapeos para adaptarse a tus necesidades. Por ejemplo, TranslatePlane produce traducción en un plano virtual, mientras que RotateAxis produce rotación alrededor de un eje virtual.

AjusteDescripción
TranslateLineMovimiento 1D a lo largo del Axis del detector, por defecto el eje Y del mundo.
TranslatePlaneMovimiento 2D en el plano perpendicular al Axis del detector, por defecto el plano XZ del mundo.
TranslatePlaneOrLineMovimiento 2D en el plano perpendicular al Axis del detector y, cuando el modificador está activo, movimiento 1D a lo largo del Axis del detector.
TranslateLineOrPlaneMovimiento 1D a lo largo del Axis del detector y, cuando el modificador está activo, movimiento 2D en el plano perpendicular al Axis del detector.
TranslateViewPlaneMovimiento 2D en el plano perpendicular a la vista de la cámara. En este modo, el plano se actualiza constantemente, incluso mientras se arrastra, y siempre se orientará hacia la vista actual de la cámara.
RotateAxisRotación alrededor del Axis del detector, por defecto el eje Y del mundo.
RotateTrackballRotación de tipo trackball, además personalizada a través de las propiedades TrackballRadialPullFactor y TrackballRollFactor.
BestForDeviceTranslatePlaneOrLine para mouse y gamepad; TranslatePlane para toque; 6DOF para VR.
ScriptableCalcula el movimiento deseado a través de una función personalizada proporcionada a través de SetDragStyleFunction().

Dirección de arrastre

Por defecto, el movimiento 3D y el DragStyle asociado se asignan al espacio mundial. Sin embargo, es posible que desees cambiar la ReferenceInstance, Orientation o Axis, por ejemplo, al construir detectores de arrastre en modelos con partes ajustables.

PropiedadDescripciónPredeterminado
ReferenceInstanceUna instancia cuyo pivote proporciona el marco de referencia para el detector de arrastre. El DragFrame se expresa en relación con este marco de referencia que se puede recuperar a través de GetReferenceFrame(). Si el marco de referencia es nil, la traducción será en la dirección de (o en el plano perpendicular a) la propiedad Axis en el espacio mundial.nil
OrientationEspecifica la rotación YXZ de los ejes de movimiento en relación con el marco de referencia (no cambia la orientación del marco de referencia en sí). La traducción lineal y la rotación axial se realizarán en este eje Y reorientado, y la traducción planar en el plano XZ. Cambiar este valor actualiza automáticamente Axis y viceversa.(0, 0, 0)
AxisEl eje primario de movimiento, expresado en relación con el marco de referencia. Cambiar este valor actualiza automáticamente Orientation y viceversa.(0, 1, 0)

Respuesta al movimiento

La propiedad ResponseStyle especifica cómo un objeto responde al movimiento propuesto, dependiendo de si el objeto está Anchored o no.

AjusteComportamiento ancladoComportamiento no anclado
GeometricTanto dentro de la experiencia en ejecución como en el modo de edición de Studio, la posición/orientación de un objeto anclado se actualizará para reflejar exactamente el movimiento propuesto.Para un objeto no anclado, el comportamiento es el mismo que para un objeto anclado. Sin embargo, en una experiencia en ejecución, el objeto se anclará al inicio del arrastre y se restaurará a no anclado al soltar el arrastre.
PhysicalUn objeto anclado tendrá un comportamiento predeterminado de Geométrico, ya que no está afectado por fuerzas.Un objeto no anclado será movido por fuerzas de restricción que intentan llevarlo a la posición/orientación deseada dada por el movimiento propuesto.
CustomEl objeto no se moverá en absoluto, pero el DragFrame aún se actualizará y puedes responder a la manipulación del arrastre como desees.(igual que anclado)

Límites de eje y movimiento

Por defecto, no hay límites al movimiento 3D más allá de las restricciones inherentes de DragStyle. Si es necesario, puedes aplicar límites mínimo y máximo tanto para la traducción como para la rotación. Ten en cuenta, sin embargo, que estos no son restricciones; simplemente impiden los intentos del detector de arrastre de generar movimiento para permanecer dentro de los límites.

PropiedadesDescripciónPredeterminado

MinDragTranslation
MaxDragTranslation

Límites para la traducción de arrastre en cada dimensión. Si MaxDragTranslation es mayor que MinDragTranslation, la traducción se limitará a ese rango.(0, 0, 0)

MinDragAngle
MaxDragAngle

Solo relevante si DragStyle está configurado en RotateAxis. Si MaxDragAngle es mayor que MinDragAngle, la rotación se limitará a ese rango.0

Permisos de arrastre

El permiso de los jugadores para interactuar con una determinada instancia de detector de arrastre se puede especificar mediante la propiedad PermissionPolicy. Esto se establece en Enum.DragDetectorPermissionPolicy.Everybody por defecto, y también se puede cambiar para admitir controles de permisos programáticos como se muestra en el ejemplo de código.

AjusteDescripción
NobodyNingún jugador puede interactuar con el DragDetector.
EverybodyTodos los jugadores pueden interactuar con el DragDetector.
ScriptableLos permisos de arrastre de los jugadores serán determinados por una función registrada a través de SetPermissionPolicyFunction(). Bajo este ajuste, el fallo al registrar una función o devolver un resultado no válido evitará que todos los jugadores arrastren.
DragDetector - Permiso de Arrastre Programado

local dragDetector = script.Parent.DragDetector
dragDetector.PermissionPolicy = Enum.DragDetectorPermissionPolicy.Scriptable
dragDetector:SetPermissionPolicyFunction(function(player, part)
if player and player:GetAttribute("IsInTurn") then
return true
elseif part and not part:GetAttribute("IsDraggable") then
return false
else
return true
end
end)

Respuesta física

Suponiendo que el estilo de respuesta del arrastre está configurado en Physical y se aplica a un objeto no anclado, ese objeto será movido por fuerzas de restricción que intentan llevarlo a la posición/orientación dada por el movimiento propuesto. Puedes personalizar aún más la respuesta física a través de las siguientes propiedades:

PropiedadDescripciónPredeterminado
ApplyAtCenterOfMassCuando es falso, la fuerza de arrastre se aplica en el punto donde hace clic el usuario. Cuando es verdadero, la fuerza se aplica en el centro de masa del objeto.false
MaxForceFuerza máxima aplicada para que el objeto alcance su objetivo.10000000
MaxTorqueTorque máximo aplicado para que el objeto alcance su objetivo.10000
ResponsivenessValores más altos hacen que el objeto alcance su objetivo más rápidamente.10

Entrada de modificador

Algunos modos de DragStyle permiten a los usuarios mantener presionada una tecla/botón modificador para manipular el objeto arrastrado de diferentes maneras. Por defecto, el modificador es LeftControl en PC, ButtonR1 en gamepad o ButtonL2 en VR. Puedes personalizar estos modificadores a través de las propiedades KeyboardModeSwitchKeyCode, GamepadModeSwitchKeyCode o VRSwitchKeyCode de la instancia del detector de arrastre.

Replicación

Cuando la propiedad RunLocally es falsa (predeterminada), el cliente interpreta toda la entrada para producir datos que envía al servidor para realizar el arrastre. En este modo, todas las señales de eventos personalizadas y funciones registradas deben estar en el servidor Scripts.

Cuando la propiedad RunLocally es verdadera, no se replican eventos al servidor. Todas las señales de eventos personalizadas y funciones registradas deben estar en el cliente LocalScripts y debes usar eventos remotos para propagar los cambios necesarios al servidor.

Respuestas de scripts a clics y arrastres

A través de señales de eventos, cambios de propiedades, estilo de arrastre Scriptable, y funciones personalizadas, los scripts pueden responder a la manipulación de objetos arrastrados para manejar la interfaz de usuario o tomar decisiones lógicas, como ajustar el nivel de luz en una habitación basado en un dimmer de interruptor deslizante.

Señales de eventos

A través de las siguientes señales de eventos, puedes detectar cuándo un usuario comienza, continúa y termina de arrastrar un objeto.

EventoDescripción
DragStartSe activa cuando un usuario comienza a arrastrar el objeto.
DragContinueSe activa cuando un usuario continúa arrastrando el objeto después de que se haya iniciado DragStart.
DragEndSe activa cuando un usuario deja de arrastrar el objeto.
DragDetector - Señales de Eventos

local dragDetector = script.Parent.DragDetector
local highlight = Instance.new("Highlight")
highlight.Enabled = false
highlight.Parent = script.Parent
dragDetector.DragStart:Connect(function()
highlight.Enabled = true
end)
dragDetector.DragContinue:Connect(function()
end)
dragDetector.DragEnd:Connect(function()
highlight.Enabled = false
end)

Cambios en el marco de arrastre

Además de las señales de eventos, puedes monitorear cambios en el DragFrame del detector directamente.

DragDetector - Cambios en DragFrame

local dragDetector = script.Parent.DragDetector
dragDetector:GetPropertyChangedSignal("DragFrame"):Connect(function()
local currentDragTranslation = dragDetector.DragFrame.Position
print(currentDragTranslation)
end)

Estilo de arrastre programado

Si configuras el DragStyle de un detector en Scriptable, puedes proporcionar tu propia función que toma un Ray y devuelve un CFrame en el espacio mundial. El detector moverá el movimiento de modo que el objeto arrastrado vaya a esa ubicación/orientación personalizada.

DragDetector - Estilo de Arrastre Programado

local Workspace = game:GetService("Workspace")
local dragDetector = script.Parent.DragDetector
dragDetector.DragStyle = Enum.DragDetectorDragStyle.Scriptable
local cachedHitPoint = Vector3.zero
local cachedHitNormal = Vector3.yAxis
local function followTheCursor(cursorRay)
-- Excluir objeto arrastrado de la detección de raycast
local raycastParams = RaycastParams.new()
raycastParams.FilterDescendantsInstances = {dragDetector.Parent}
raycastParams.FilterType = Enum.RaycastFilterType.Exclude
local hitPoint = Vector3.zero
local hitNormal = Vector3.yAxis
local raycastResult = Workspace:Raycast(cursorRay.Origin, cursorRay.Direction, raycastParams)
if raycastResult then
hitPoint = raycastResult.Position
hitNormal = raycastResult.Normal.Unit
else
hitPoint = cachedHitPoint
hitNormal = cachedHitNormal
end
cachedHitPoint = hitPoint
cachedHitNormal = hitNormal
local lookDir1 = hitNormal:Cross(Vector3.xAxis)
local lookDir2 = hitNormal:Cross(Vector3.yAxis)
local lookDir = if lookDir1.Magnitude > lookDir2.Magnitude then lookDir1.Unit else lookDir2.Unit
return CFrame.lookAt(hitPoint, hitPoint + lookDir, hitNormal)
end
dragDetector:SetDragStyleFunction(followTheCursor)

Función de restricción personalizada

Los detectores de arrastre no tienen reglas de movimiento integradas sobre rejillas y encajones, pero puedes registrar funciones de restricción personalizadas para editar el DragFrame del detector antes de que se aplique. Por ejemplo, puedes mantener el movimiento en una rejilla redondeando posiciones a múltiplos del incremento de rejilla, o simular un juego de ajedrez con reglas de movimiento legales para cada pieza.

DragDetector - Función de Restricción Personalizada

local dragDetector = script.Parent.DragDetector
local startPartPosition = nil
local SNAP_INCREMENT = 4
dragDetector.DragStart:Connect(function()
startPartPosition = script.Parent.Position
end)
dragDetector.DragEnd:Connect(function()
startPartPosition = nil
end)
local function snapToWorldGrid(proposedMotion)
if startPartPosition == nil then
return proposedMotion
end
local snapIncrement = SNAP_INCREMENT // 1
if snapIncrement < 1 then
return proposedMotion
end
local newWorldPosition = startPartPosition + proposedMotion.Position
local roundedX = ((newWorldPosition.X / snapIncrement + 0.5) // 1) * snapIncrement
local roundedY = ((newWorldPosition.Y / snapIncrement + 0.5) // 1) * snapIncrement
local roundedZ = ((newWorldPosition.Z / snapIncrement + 0.5) // 1) * snapIncrement
local newRoundedWorldPosition = Vector3.new(roundedX, roundedY, roundedZ)
return proposedMotion.Rotation + (newRoundedWorldPosition - startPartPosition)
end
local connection = dragDetector:AddConstraintFunction(2, snapToWorldGrid)
-- Cuando sea aplicable, elimina la función de restricción invocando connection:Disconnect()

Ejemplo de uso

Objetos físicos no anclados

Una implementación básica de detectores de arrastre es un juego de equilibrio de torres donde los jugadores deben quitar cuidadosamente piezas y tratar de mantener la torre en pie. En la siguiente estructura de torre, cada pieza tiene un DragDetector como hijo con un DragStyle predeterminado de TranslatePlane para que los jugadores puedan tirar de las piezas hacia afuera pero no hacia arriba o hacia abajo.

Modelos anclados con partes ajustables

Puedes crear y compartir fácilmente modelos que están principalmente anclados, pero que tienen una o más partes/modelos hijos que los jugadores pueden arrastrar. Por ejemplo, el siguiente escritorio tiene dos cajones que los jugadores pueden abrir para inspeccionar lo que hay dentro.

Detectores de arrastre y restricciones

Puedes combinar detectores de arrastre con Constraints, por ejemplo, un marioneta. En la siguiente configuración, las manijas de control están ancladas, las partes del cuerpo no están ancladas, y las restricciones mantienen unidas a la marioneta. Mover las manijas con el estilo de arrastre TranslateViewPlane hace que la marioneta baile, y las partes individuales del cuerpo también pueden moverse con detectores de arrastre, todo mientras el modelo conserva su integridad.

Interfaces de usuario 3D

Las interfaces de usuario 3D son fácilmente alcanzables a través de detectores de arrastre, como ajustar el brillo de un SpotLight en función de un dimmer de interruptor deslizante. También puedes detectar los ejes X y Z individualmente para controlar dos aspectos diferentes de una interfaz de usuario 3D, como el Size, Speed, y Color de un ParticleEmitter.

DragDetector - Interfaz de Usuario 3D

local model = script.Parent
local slider = model.SliderPart
local originPart = model.OriginPart
local emitter = script.Parent.EmitterPart.ParticleEmitter
local dragDetector = slider.DragDetector
dragDetector.ReferenceInstance = originPart
dragDetector.MinDragTranslation = Vector3.zero
dragDetector.MaxDragTranslation = Vector3.new(10, 0, 10)
local dragRangeX = dragDetector.MaxDragTranslation.X - dragDetector.MinDragTranslation.X
local dragRangeZ = dragDetector.MaxDragTranslation.Z - dragDetector.MinDragTranslation.Z
local MIN_PARTICLE_SIZE = 1
local MAX_PARTICLE_SIZE = 1.5
local MIN_PARTICLE_SPEED = 2.5
local MAX_PARTICLE_SPEED = 5
local COLOR1 = Color3.fromRGB(255, 150, 0)
local COLOR2 = Color3.fromRGB(255, 0, 50)
local function updateParticles(emitter)
local dragFactorX = (dragDetector.DragFrame.Position.X - dragDetector.MinDragTranslation.X) / dragRangeX
local dragFactorZ = (dragDetector.DragFrame.Position.Z - dragDetector.MinDragTranslation.Z) / dragRangeZ
-- Ajustar el tamaño de las partículas y la velocidad en función del factor X del detector de arrastre
emitter.Size = NumberSequence.new{
NumberSequenceKeypoint.new(0, 0),
NumberSequenceKeypoint.new(0.1, MIN_PARTICLE_SIZE + ((MAX_PARTICLE_SIZE - MIN_PARTICLE_SIZE) * dragFactorX)),
NumberSequenceKeypoint.new(1, 0)
}
local speed = MIN_PARTICLE_SPEED + ((MAX_PARTICLE_SPEED - MIN_PARTICLE_SPEED) * dragFactorX)
emitter.Speed = NumberRange.new(speed, speed * 1.2)
-- Ajustar el color de las partículas en función del factor Z del detector de arrastre
local color = COLOR2:Lerp(COLOR1, dragFactorZ)
emitter.Color = ColorSequence.new{
ColorSequenceKeypoint.new(0, color),
ColorSequenceKeypoint.new(1, color)
}
end
dragDetector:GetPropertyChangedSignal("DragFrame"):Connect(function()
updateParticles(emitter)
end)
©2026 Roblox Corporation. Roblox, el logotipo de Roblox y "Powering Imagination" son algunas de nuestras marcas registradas y no registradas en los Estados Unidos y otros países.