3D 드래그 감지기

*이 콘텐츠는 AI(베타)를 사용해 번역되었으며, 오류가 있을 수 있습니다. 이 페이지를 영어로 보려면 여기를 클릭하세요.

DragDetector 인스턴스는 게임 내 3D 객체와의 상호작용을 촉진하고 장려하며, 예를 들어 문과 서랍을 여는 것, 부품을 이동시키는 것, 볼링공을 잡고 던지는 것, 슬링샷을 당기고 발사하는 것 등 다양한 작업을 수행할 수 있습니다. 주요 기능은 다음과 같습니다:

  • 모든 입력(마우스, 터치, 게임패드, VR)을 통해 드래그 가능하게 하려면 BasePart 또는 Model 아래에 DragDetector를 배치하면 됩니다. 이 모든 작업은 코드 한 줄 없이 가능합니다.

  • 여러 가지 드래그 스타일 중에서 선택하고, 객체가 모션에 반응하는 방식을 정의하며, 선택적으로 축 또는 이동 제한을 적용할 수 있습니다.

  • 스크립트는 드래그된 객체의 조작에 반응하여 UI를 조작하거나 논리적 결정을 내릴 수 있습니다. 예를 들어, 슬라이딩 벽 스위치 조명 조절에 따라 방의 조명 수준을 조정할 수 있습니다.

  • 플레이어는 고정된 부품이나 모델을 조작할 수 있으며, 놓을 때 정확히 그 위치에 유지됩니다.

  • DragDetectorsSelect, Move, Scale, 또는 Rotate 도구를 사용하지 않는 한 Studio에서 작동하므로, 편집 중 드래그 가능한 객체를 테스트하고 조정하기가 더 쉽습니다.

객체를 드래그 가능하게 만들기

어떤 부품이나 모델을 드래그 가능하게 만들려면, 단순히 DragDetector를 직접 자식으로 추가하면 됩니다.

  1. Explorer 창에서 Part, MeshPart, 또는 Model 위에 마우스를 올리고 ⊕ 버튼을 클릭합니다. 컨텍스트 메뉴가 표시됩니다.

  2. 메뉴에서 DragDetector를 삽입합니다.

  3. 기본적으로 객체는 이제 지면 평면에서 드래그 가능하지만, DragStyle을 사용자 정의하고, 모션에 반응하는 방식을 정의하며, 선택적으로 축 또는 이동 제한을 적용할 수 있습니다.

드래그 감지기 사용자 정의

드래그 스타일

DragDetectors는 커서 모션을 가상 선과 평면에 매핑하여 제안된 3D 모션을 계산합니다. DragStyle 속성을 통해 필요에 맞는 다양한 매핑 중에서 선택할 수 있습니다. 예를 들어, TranslatePlane는 가상 평면에서의 변환을 생성하고, RotateAxis는 가상 축을 중심으로 회전을 생성합니다.

설정설명
TranslateLine감지기의 Axis를 따라 1D 모션, 기본적으로 세계 Y 축을 따릅니다.
TranslatePlane감지기의 Axis에 수직인 평면에서의 2D 모션, 기본적으로 세계 XZ 평면을 따릅니다.
TranslatePlaneOrLine감지기의 Axis에 수직인 평면에서의 2D 모션과, 수정자가 활성화된 경우 감지기의 Axis를 따라 1D 모션.
TranslateLineOrPlane감지기의 Axis를 따라 1D 모션과, 수정자가 활성화된 경우 감지기의 Axis에 수직인 평면에서의 2D 모션.
TranslateViewPlane카메라의 뷰에 수직인 평면에서의 2D 모션. 이 모드에서는 평면이 드래그 중에도 지속적으로 업데이트되며, 항상 카메라의 현재 뷰를 향합니다.
RotateAxis감지기의 Axis를 중심으로 회전, 기본적으로 세계 Y 축을 따릅니다.
RotateTrackball트랙볼 회전, TrackballRadialPullFactorTrackballRollFactor 속성을 통해 추가로 사용자 정의됩니다.
BestForDevice마우스 및 게임패드의 경우 TranslatePlaneOrLine; 터치의 경우 TranslatePlane; VR의 경우 6DOF.
Scriptable사용자가 제공한 사용자 정의 함수를 통해 원하는 모션을 계산합니다.

드래그 방향

기본적으로 3D 모션과 관련된 DragStyle는 세계 공간에 매핑됩니다. 그러나 드래그 감지기를 조정 가능한 부품이 있는 모델에 통합할 때 ReferenceInstance, Orientation, 또는 Axis를 변경할 수 있습니다.

속성설명기본값
ReferenceInstance드래그 감지기의 기준 프레임을 제공하는 피벗을 가진 인스턴스. DragFrame은 이 기준 프레임에 상대적으로 표현되며, GetReferenceFrame()를 통해 검색할 수 있습니다. 기준 프레임이 nil인 경우, 변환은 세계 공간에서 Axis 속도의 방향(또는 수직 평면)으로 이루어집니다.nil
Orientation기준 프레임에 대한 모션 축의 YXZ 회전을 지정합니다(기준 프레임 자체의 방향은 변경되지 않음). 선형 변환과 축 회전은 이 재정렬된 Y 축을 따라 이루어지며, 평면 변환은 XZ 평면에서 이루어집니다. 이 값을 변경하면 Axis가 자동으로 업데이트되고 그 반대도 마찬가지입니다.(0, 0, 0)
Axis기준 프레임에 상대적으로 표현된 주요 모션 축. 이 값을 변경하면 Orientation이 자동으로 업데이트되고 그 반대도 마찬가지입니다.(0, 1, 0)

모션에 대한 반응

ResponseStyle 속성은 객체가 제안된 모션에 어떻게 반응하는지를 지정합니다. 객체가 Anchored인지 여부에 따라 다릅니다.

설정고정된 동작비고정 동작
Geometric실행 중인 게임과 Studio 편집 모드 모두에서, 고정된 객체의 위치/방향은 제안된 모션을 정확히 반영하도록 업데이트됩니다.비고정 객체의 경우, 동작은 고정 객체와 동일합니다. 그러나 실행 중인 게임에서는 드래그 시작 시 객체가 고정되고 드래그 해제 시 비고정으로 복원됩니다.
Physical고정된 객체는 힘의 영향을 받지 않기 때문에 기본적으로 Geometric 동작을 따릅니다.비고정 객체는 제안된 모션에 의해 주어진 원하는 위치 및/또는 방향으로 가져가려는 제약 힘에 의해 이동됩니다.
Custom객체는 전혀 이동하지 않지만, DragFrame는 여전히 업데이트되며, 원하는 대로 드래그 조작에 반응할 수 있습니다.(고정된 객체와 동일)

축 및 이동 제한

기본적으로 DragStyle의 고유한 제한을 제외하고는 3D 모션에 대한 제한이 없습니다. 필요에 따라 변환 및 회전에 최소 및 최대 제한을 적용할 수 있습니다. 그러나 이러한 제한은 제약이 아니라 드래그 감지기가 제한 내에서 유지되기 위해 모션을 생성하려는 시도를 방해하는 것입니다.

속성설명기본값
MinDragTranslation
MaxDragTranslation
각 차원에서 드래그 변환에 대한 제한. MaxDragTranslation이 MinDragTranslation보다 크면 변환은 해당 범위 내에서 제한됩니다.(0, 0, 0)
MinDragAngle
MaxDragAngle
DragStyleRotateAxis로 설정된 경우에만 관련이 있습니다. MaxDragAngleMinDragAngle보다 크면 회전은 해당 범위 내에서 제한됩니다.0

드래그 권한

플레이어가 특정 드래그 감지기 인스턴스와 상호작용할 수 있는 권한은 PermissionPolicy 속성으로 지정할 수 있습니다. 기본값은 Enum.DragDetectorPermissionPolicy.Everybody로 설정되어 있으며, 코드 샘플에 표시된 대로 스크립트 권한 제어를 지원하도록 변경할 수 있습니다.

설정설명
Nobody어떤 플레이어도 DragDetector와 상호작용할 수 없습니다.
Everybody모든 플레이어가 DragDetector와 상호작용할 수 있습니다.
Scriptable플레이어의 드래그 권한은 SetPermissionPolicyFunction()을 통해 등록된 함수에 의해 결정됩니다. 이 설정에서는 함수를 등록하지 않거나 유효하지 않은 결과를 반환하면 모든 플레이어가 드래그할 수 없습니다.
DragDetector - 스크립트 드래그 권한
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)

물리적 반응

드래거의 반응 스타일Physical로 설정되고 비고정 객체에 적용되면, 해당 객체는 제안된 모션에 의해 주어진 위치/방향으로 가져가려는 제약 힘에 의해 이동됩니다. 다음 속성을 통해 물리적 반응을 추가로 사용자 정의할 수 있습니다:

속성설명기본값
ApplyAtCenterOfMassfalse인 경우, 드래그 힘은 사용자가 클릭한 지점에 적용됩니다. true인 경우, 힘은 객체의 질량 중심에 적용됩니다.false
MaxForce객체가 목표에 도달하기 위해 적용되는 최대 힘.10000000
MaxTorque객체가 목표에 도달하기 위해 적용되는 최대 토크.10000
Responsiveness값이 높을수록 객체가 목표에 더 빠르게 도달합니다.10

수정자 입력

일부 DragStyle 모드는 사용자가 수정자 키/버튼을 눌러 드래그된 객체를 다른 방식으로 조작할 수 있도록 허용합니다. 기본적으로 수정자는 PC에서는 LeftControl, 게임패드에서는 ButtonR1, VR에서는 ButtonL2입니다. 이러한 수정자는 드래그 감지기 인스턴스의 KeyboardModeSwitchKeyCode, GamepadModeSwitchKeyCode, 또는 VRSwitchKeyCode 속성을 통해 사용자 정의할 수 있습니다.

복제

RunLocally 속성이 false(기본값)인 경우, 클라이언트는 모든 입력을 해석하여 서버에 전송할 데이터를 생성하여 드래그를 수행합니다. 이 모드에서는 모든 사용자 정의 이벤트 신호와 등록된 함수가 서버 Scripts에 있어야 합니다.

RunLocally 속성이 true인 경우, 이벤트가 서버에 복제되지 않습니다. 모든 사용자 정의 이벤트 신호와 등록된 함수는 클라이언트 LocalScripts에 있어야 하며, 필요한 변경 사항을 서버에 전파하기 위해 원격 이벤트를 사용해야 합니다.

클릭 및 드래그에 대한 스크립트 응답

이벤트 신호, 속성 변경, Scriptable 드래그 스타일 및 사용자 정의 함수를 통해 스크립트는 드래그된 객체의 조작에 반응하여 UI를 조작하거나 논리적 결정을 내릴 수 있습니다. 예를 들어, 슬라이딩 벽 스위치 조명 조절에 따라 방의 조명 수준을 조정할 수 있습니다.

이벤트 신호

다음 이벤트 신호를 통해 사용자가 객체를 드래그하기 시작하고, 계속하고, 드래그를 종료할 때를 감지할 수 있습니다.

이벤트설명
DragStart사용자가 객체를 드래그하기 시작할 때 발생합니다.
DragContinue사용자가 DragStart가 시작된 후 객체를 계속 드래그할 때 발생합니다.
DragEnd사용자가 객체 드래그를 중지할 때 발생합니다.
DragDetector - 이벤트 신호
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)

드래그 프레임 변경

이벤트 신호 외에도 감지기의 DragFrame 변경 사항을 직접 모니터링할 수 있습니다.

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

스크립트 드래그 스타일

감지기의 DragStyleScriptable로 설정하면 Ray를 입력으로 받아 세계 공간 CFrame을 반환하는 사용자 정의 함수를 제공할 수 있습니다. 감지기는 드래그된 객체가 해당 사용자 정의 위치/방향으로 이동하도록 모션을 조정합니다.

DragDetector - 스크립트 드래그 스타일
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)
-- 드래그된 객체를 레이캐스트 감지에서 제외
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)

사용자 정의 제약 함수

드래그 감지기는 그리드 및 스냅에 대한 내장 모션 규칙이 없지만, 감지기의 DragFrame이 적용되기 전에 수정할 사용자 정의 제약 함수를 등록할 수 있습니다. 예를 들어, 위치를 그리드 증가의 배수로 반올림하여 모션을 그리드에 유지하거나, 각 조각의 모션 규칙에 따라 체스 게임을 시뮬레이션할 수 있습니다.

DragDetector - 사용자 정의 제약 함수
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)
-- 적용 가능한 경우, connection:Disconnect()를 호출하여 제약 함수를 제거합니다.

사용 예시

비고정 물리 객체

드래그 감지기의 기본 구현은 플레이어가 조심스럽게 조각을 제거하고 타워를 똑바로 유지해야 하는 타워 균형 게임입니다. 다음 타워 구조에서 각 조각은 기본 DragStyleTranslatePlane인 자식 DragDetector를 가지고 있어 플레이어가 조각을 바깥쪽으로 끌 수 있지만 위아래로는 끌 수 없습니다.

조정 가능한 부품이 있는 고정 모델

주로 고정된 모델을 쉽게 만들고 공유할 수 있으며, 플레이어가 드래그할 수 있는 하나 이상의 자식 부품/모델이 있습니다. 예를 들어, 다음 책상에는 플레이어가 열어 내부를 확인할 수 있는 두 개의 서랍이 있습니다.

드래그 감지기와 제약

드래그 감지기를 Constraints와 결합할 수 있습니다. 예를 들어, 마리오네트 인형입니다. 다음 설정에서 제어 핸들은 고정되어 있고, 몸체 부분은 비고정이며, 제약이 마리오네트를 함께 유지합니다. TranslateViewPlane DragStyle로 핸들을 이동하면 마리오네트가 춤추고, 개별 몸체 부분도 드래그 감지기로 이동할 수 있으며, 모델은 그 구조를 유지합니다.

3D 사용자 인터페이스

3D 사용자 인터페이스는 드래그 감지기를 통해 쉽게 구현할 수 있으며, 예를 들어 슬라이딩 스위치 조명 조절에 따라 SpotLight의 밝기를 조정할 수 있습니다. 또한 XZ 축을 개별적으로 감지하여 Size, Speed, 및 Color와 같은 3D 사용자 인터페이스의 두 가지 다른 측면을 제어할 수 있습니다.

DragDetector - 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
-- 드래그 감지기 X 계수에 따라 입자 크기 및 속도 조정
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)
-- 드래그 감지기 Z 계수에 따라 입자 색상 조정
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 및 Roblox 로고, 'Powering Imagination'은 미국 및 기타 국가 내 당사의 등록 및 미등록 상표입니다.