3D 드래그 감지기

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

인스턴스는 문 및 서랍 열기, 부품 슬라이드, 볼링 공 잡기 및 던지기, 활 당겨 및 발사, 그리고 훨씬 더 많은 경험에서 3D 개체와의 상호 작용을 용이하게 하고 장려합니다.주요 기능은 다음과 같습니다:

개체 끌기 가능 만들기

어떤 부품이나 모델을 드래그할 수 있도록 하려면 직접 하위로 DragDetector를 추가하면 됩니다.

  1. 탐색기 창에서 , Part 또는 MeshPart 을 가리키고 Model 버튼을 클릭하십시오. 컨텍스트 메뉴가 표시됩니다.

  2. 메뉴에서 드래그 감지기 를 삽입합니다.

  3. 기본적으로 개체는 이제 지상 평면에서 드래그할 수 있지만, 를 사용자 정의하고, 모션에 어떻게 응답하는지 정의하고, 선택적으로 축이나 이동 제한을 적용할 수 있습니다.

드래그 감지기 사용자 정의

스타일 끌기

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 터치용; 6DOF VR용.
Scriptable원하는 움직임을 SetDragStyleFunction()를 통해 제공된 사용자 지정 함수로 계산합니다.

방향 끌기

기본적으로, 3D 이동과 관련된 DragStyle 세계 공간 맵.그러나 드래그 검색기를 조정 가능한 부품이 있는 모델에 빌드할 때 예를 들어 또는 을 변경하려는 경우가 있을 수 있습니다.

속성설명기본
ReferenceInstance피벗이 드래그 검색기에 대한 참조 프레임 을 제공하는 인스턴스.DragFrame 는 검색할 수 있는 이 참조 프레임에 대해 표현되며, GetReferenceFrame() 를 통해 검색할 수 있습니다.참조 프레임이 nil 이면 번역은 세계 공간의 Axis 속성으로 향하거나 평행하게 이동합니다.nil
Orientation참조 프레임과 관련된 운동 축의 YXZ 회전을 지정하여(참조 프레임 자체의 방향은 변경되지 않음) 참조 프레임의 방향을 변경하지 않습니다.선형 번역과 축 회전은 이 재설정된 Y 축에서 수행되며, 평면 번역은 XZ 평면에서 수행됩니다.이 값을 자동으로 변경하면 Axis이 업데이트되고 반대로도 마찬가지입니다.(0, 0, 0)
Axis참조 프레임에 대해 표현된 기본 이동 축. 이 값을 변경하면 Orientation가 자동으로 업데이트되고 반대로도 마찬가지입니다.(0, 1, 0)

모션에 대한 응답

ResponseStyle 속성은 개체가 Anchored인지 여부에 따라 제안된 동작에 대해 개체가 응답하는 방법을 지정합니다.

설정고정된 행동고정되지 않은 동작
Geometric실행 경험 내부와 Studio 편집 모드 모두에서 고정된 개체의 위치/방향은 제안된 동작을 정확하게 반영하도록 업데이트됩니다.고정되지 않은 개체의 경우 동작은 고정된 개체와 동일합니다.그러나 실행 중인 경험에서는 개체가 드래그 시작 시 고정되고 드래그 해제 시 고정 해제되어 복원됩니다.
Physical고정된 개체는 힘의 영향을 받지 않으므로 기본적으로 기하학적 동작으로 설정됩니다.고정되지 않은 개체는 제안된 동작으로 인해 원하는 위치와/또는 방향으로 이동되는 제약 조건 힘에 의해 이동됩니다.
Custom개체는 전체이동하지 않지만, 는 여전히 업데이트되고 원하는 대로 드래그 조작에 응답할 수 있습니다.(고정과 동일)

축 및 이동 제한

기본적으로, 3D 이동에는 DragStyle의 내재적 제한을 넘어서는 제한이 없습니다.필요한 경우 번역과 회전에 최소값과 최대값을 적용할 수 있습니다.그러나 이들은 아니다 제약 조건이며, 단지 제한 내에 머무르기 위해 드래그 검출기의 움직임 생성 시도를 방해합니다.

속성설명기본
Class.DragDetector.MinDragTranslation|MinDragTranslation``Class.DragDetector.MaxDragTranslation|MaxDragTranslation각 차원에서 번역을 드래그하는 제한. MaxDragTranslation이 MinDragTranslation보다 크면 번역이 해당 범위 내에 클램핑됩니다.(0, 0, 0)
Class.DragDetector.MinDragAngle|MinDragAngle``Class.DragDetector.MaxDragAngle|MaxDragAngle관련성이 있으려면 DragStyle회전 축 으로 설정되어 있어야 합니다.MaxDragAngleMinDragAngle 보다 크면 회전이 해당 범위 내에서 제한됩니다.0

권한 끌기

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

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

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)

물리 응답

드래거의 응답 스타일이 물리적으로 설정되고 고정되지 않은 개체에 적용되면, 그 개체는 제안된 동작으로 지정된 위치/방향으로 제약 조건에 의해 이동됩니다.다음 속성을 통해 물리적 응답을 추가로 사용자 지정할 수 있습니다:

속성설명기본
ApplyAtCenterOfMass거짓일 경우, 사용자가 클릭하는 지점에 드래그 힘이 적용됩니다. 참일 경우, 힘이 개체의 중량 중심에 적용됩니다.거짓
MaxForce목표에 도달하기 위해 개체에 적용된 최대 힘.10000000
MaxTorque목표에 도달하기 위해 개체에 적용된 최대 토크.10000
Responsiveness더 높은 값은 개체가 목표에 더 빨리 도달하도록 합니다.10

모디파이어 입력

일부 DragStyle 모드는 사용자가 다양한 방식으로 끌어온 개체를 조작하기 위해 모디파이어 키/버튼을 길게 누를 수 있습니다.기본적으로 모디파이어는 PC에서 LeftControl, 게임패드에서 ButtonR1, VR에서 ButtonL2입니다.드래그 검색기 인스턴스의 KeyboardModeSwitchKeyCode , GamepadModeSwitchKeyCode 또는 VRSwitchKeyCode 속성을 통해 이러한 모디파이어를 사용자 지정할 수 있습니다.

복제

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

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

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

이벤트 신호, 속성 변경, 드래그 스타일, 사용자 지정 함수를 통해 스크립트는 슬라이딩 벽 스위치 밝기를 조정하여 방의 조명 수준을 조정하거나 UI를 조작하여 논리적인 결정을 내릴 수 있습니다.

이벤트 신호

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

이벤트설명
DragStart사용자가 개체를 드래그하기 시작할 때 발생합니다.
DragContinue사용자가 DragStart 이후에 개체를 계속 끌어다 놓으면 발생합니다.
DragEnd사용자가 개체를 끌기를 중지하면 발생합니다.
드래그 탐지기 - 이벤트 신호

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 변경 사항을 직접 모니터링할 수 있습니다

드래그 탐지기 - 드래그프레임 변경

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

스크립트 드래그 스타일

탐지기의 를 스크립트 가능 으로 설정하면 세계 공간 을 가져와 반환하는 자체 함수를 제공할 수 있습니다.감지기는 움직임을 이동하여 끌어온 개체가 해당 사용자 지정 위치/방향으로 이동합니다.

드래그 탐지기 - 스크립트된 드래그 스타일

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)

사용자 지정 제약 조건 함수

드래그 감지기에는 그리드 및 스냅에 대한 내장 된 규칙이 없지만, 검색기의 기능을 편집하기 위해 사용자 지정 제약 조건을 등록할 수 있습니다. before it is applied.예를 들어, 위치를 그리드 증가량의 배수로 반올림하여 그리드에서 움직임을 유지하거나, 각 조각에 적용되는 움직임 규칙으로 체스 게임을 시뮬레이션할 수 있습니다.

드래그 탐지기 - 사용자 지정 제약 함수

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)
-- When applicable, remove the constraint function by invoking connection:Disconnect()

예시 사용법

고정되지 않은 물리적 개체

드래그 검색기의 기본 구현은 플레이어가 조각을 신중하게 제거하고 타워를 세우려고 시도해야 하는 타워 밸런스 게임입니다.다음 타워 구조에서 각 조각에는 기본 의 번역 평면 을 가진 자식이 있으므로 플레이어가 조각을 외부로 당길 수 있지만 위쪽이나 아래쪽으로는 할 수 없습니다.

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

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

검출기 및 제약 조건 끌기

예를 들어, 마리오네트 인형과 드래그 탐지기를 결합할 수 있습니다. Constraints .다음 설정에서는 컨트롤 핸들이 고정되고, 바디 부품은 고정되지 않으며, 제약 조건이 마리오네트를 함께 유지합니다.TranslateViewPlane의 핸들을 이동하면 마리오네트가 춤을 추고, 개별 신체 부위도 드래그 감지기로 이동할 수 있으며, 모델의 무결성은 유지됩니다.

3D 사용자 인터페이스

3D 사용자 인터페이스는 슬라이딩 스위치 디밸러에 따라 밝기를 조정하여 쉽게 달성할 수 있습니다. SpotLight 기반의 조명 밝기를 조정하여 슬라이딩 스위치 디밸러에 따라 달성할 수 있습니다.또한 XZ 축을 개별적으로 감지하여 3D 사용자 인터페이스의 두 가지 다른 측면을 제어할 수 있습니다, 예를 들어 Size , SpeedColorParticleEmitter .

드래그 탐지기 - 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)