Class.DragDetector 實例可以在體驗中與 3D 對象互動,例如開門和抽屜、滑動零件、抓取和扔出保齡球、拉動並發射彈跳、和扔出石油射擊,以及更多。 鑰匙功能包括:
將 DragDetector 放置在任何 BasePart 或 Model 下,以 2>所有輸入方式 (滑鼠、觸摸、遊戲手柄和 VR) 來拖曳它,5>無論是單擊、觸摸、遊戲手柄或 VR,8>都不需要一行代碼8>。
可以對拖曳對象進行操作 來駕駛使用者介面或做出合理的決定,例如調整室內燈光水平,根據滑動牆開關的陰暗調整器。
玩家可以操作錨定的零件或模型,並且在釋放時保持正確位置。
Class.DragDetector|DragDetectors 在 Studio 工作,直到你不是使用 選擇 、 移動 、0> 調整0> 或 DragDetectors3> 工具來測試和調整拖動對象時更容易。
讓對象可拖曳
要將任何零件或模型拖曳可移動,只需要將 DragDetector 作為直接後代。
在 Explorer 窗口中,將鼠標擺動到 Class.Part 、 Class.MeshPart 或 1>Class.Model1> 上,或按一下 ⊕ 按鈕。一個上下文菜單顯示。
從選單中,插入 拖曳偵測器 。
預設值下,對象現在會在地面飛機中拖動,但您可以自訂其 DragStyle ,定義其 對運動的反應 ,並且可以選擇 軸或運動限制。
自訂拖曳偵測器
拖曳風格
DragDetectors 以計算所需的 3D 動作為目的,通過 DragStyle 屬性,您可以選擇從不同的地圖選擇適合您需求的動作。例如, TranslatePlane 在一個虛擬飛機上產
設置 | 說明 |
---|---|
TranslateLine | 1D 移動在探測器的 Axis 上,預設為世界上的 Y 軸。 |
TranslatePlane | 2D 運動在飛機上的平面,與探測器的 Axis ,默認為世界上的飛機 XZ 。 |
TranslatePlaneOrLine | 2D 運動在飛機上的平面與探測器的 Axis 和, 當 modifier 啟用時, 1D 運動沿探測器的 Axis . |
TranslateLineOrPlane | 1D 移動沿探測器的 Axis ,當 修改器 啟用時,在飛機上平行於探測器的 Axis 上 2D 移動。 |
TranslateViewPlane | 2D 動作在飛機上平行於攝影機的檢視野。在此模式中,飛機將會持續更新,即使拖曳,仍會面向攝影機的目前檢視窗。 |
RotateAxis | 在探測器的 Axis 上旋轉,預設世界的 Y 軸。 |
RotateTrackball | 軌道球旋轉,進一步自訂通過 TrackballRadialPullFactor 和 TrackballRollFactor 屬性。 |
BestForDevice | 翻譯飛機或線路 為滑鼠和遊戲手柄; 翻譯觸摸為Touch ; 6DOF 為 VR。 |
Scriptable | 以 SetDragStyleFunction() 提供的自訂函數計算所需動作。 |
拖曳方向
由預設值 3D 動作和相關的 DragStyle 地圖到世界空間。 您可以變更 ReferenceInstance , Orientation 或 1> Class.
屬性 | 說明 | 預設 |
---|---|---|
ReferenceInstance | 其中 pivot 提供拖曳偵測器的 參考框架 的引用。 DragFrame 是以此參考框架來表示的,可以通過 Class.DragDetector:GetReferenceFrame() | nil |
Orientation | 指定關鍵框相對於參考框的移動軸的旋轉 Y 度(不會變更參考框自身的方向)。線性翻譯和軸向旋轉將在此重新定向 Y 軸上,並且在 X 平面上(1>XZ1>平面)的平移中更新。變更此值會自動 | (0, 0, 0) |
Axis | 將運動的主軸表示為與參考框架相對的值。變更此值會自動更新 Orientation 和 vice versa。 | (0、1、0) |
運動回應
Class.DragDetector.ResponseStyle|ResponseStyle 屬性指定對象在接受建議的動作時如何回應,這取決於對象是否 Anchored 或不是。
設置 | 錨定行為 | 未錨定行為 |
---|---|---|
Geometric | 在執行體驗和 Studio 編輯模式中,錨定對象的位置/方向會在正確反映所提供的動作。 | 對於未錨定的對物件,行為與錨定的對物件相同。但在執行體驗時,對象將在拖曳時開始錨定,並在拖曳時釋放時恢復為未錨定。 |
Physical | 錨定的對象將以 幾何學 行為預設,因為它不受力學影響。 | 一個未錨定的對象將被移動 by 限制力 嘗試將它移至所提供的動作所指定位置和/或方向。 |
Custom | 對象將不會移全部 所有,但 DragFrame 仍會更新,並且你可以 回應拖曳操作 ,無論你喜歡。 | (與錨定相同) |
軸和移動限制
預設情況下,DragStyle 中沒有 3D 動作的限制。如果需要,您可以對翻譯和旋轉兩個方面都應用最低和最大限制。注意,這些都不是限制;它們只是阻止拖訪器嘗試在限制內生成動作。
屬性 | 說明 | 預設 |
---|---|---|
MinDragTranslation MaxDragTranslation | 限制在每個次元拖曳翻譯。如果MaxDragTranslation大於MinDragTranslation,翻譯將在該範圍內被壓縮。 | (0, 0, 0) |
MinDragAngle MaxDragAngle | 只有在 DragStyle 設為 RotateAxis 時。如果 MaxDragAngle 大於 1> Class.DragDetorer.MinDragAngle|MinDragAngle1>,旋轉將在該範圍內受到捕鎖。 | 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 |
輸入修改器
一些 Class.DragDetector.Drag
重複
當 RunLocally 屬性為假 (預設) 時,客戶端會以解釋所有輸入,以產生發送給服務器的資料,以執行拖動。在此模式中,所有自訂事件信號和註冊功能必須位於服務器 Scripts 中。
當 RunLocally 屬性是真的時,沒有事件會複製到伺服器務伺服器。 所有自訂事件信號和註冊函數必須在客戶端 LocalScripts 中,並且您必須使用 遠端事件 來傳播必要的變更。
點擊和拖曳的回應
通過 事件信號、屬性變更、Scriptable拖式 style、和自訂功能,拖曳式技術文件 可以回應拖曳對象操作駕駛 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)
已編寫拖曳風格
如果您將偵測器的 DragStyle 設為 Scriptable ,您可以提供自己的程式碼,它會接受 Ray 並且返回世界空間 1> Datatype.CFrame1>。 探測器會將運動移動到那個自訂位置/方向。
拖曳偵測器 - 已編寫的拖曳式
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 之前。例如,您可以將動作在網格上圓形位置至多位網格增量,或者模擬一個棋遊戲,並且使用規則的動作對每個
拖動偵測器 - 自訂約束功能
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 = math.floor(SNAP_INCREMENT)
if snapIncrement < 1 then
return proposedMotion
end
local newWorldPosition = startPartPosition + proposedMotion.Position
local roundedX = math.floor(newWorldPosition.X / snapIncrement + 0.5) * snapIncrement
local roundedY = math.floor(newWorldPosition.Y / snapIncrement + 0.5) * snapIncrement
local roundedZ = math.floor(newWorldPosition.Z / snapIncrement + 0.5) * 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()
範例使用
未錨定的物理對象
拖曳偵測器的基本實現是一個塔平衡遊戲,在這裡玩家必須小心移除零件並嘗試保持塔盤上升。 在下一個塔結構中,每個零件都有一個兒子 DragDetector 用預設 DragStyle 的 TranslatePlane
附有可調整零件的錨定模型
您可以創建並分享具有主要錨定的模型,但有一個或多個兒童零件/模型,玩家可以拖曳。 舉例如下桌子,有兩個抽屜,玩家可以打開來檢查內部的內容。
拖曳偵測器和限制器
您可以將拖檯偵測器結合使用 Constraints ,例如丟籃子的偶像。在下一個設定中,控制手柄錨定,身體部位未錨定,限制可以錨定馬ionette。移動手柄使用 Trans
3D 使用者介面
3D 用戶界面可以通過拖曳偵測器簡單地達到,例如調整滑動切換器的亮度。您也可以單獨檢測 <
拖動偵測器 - 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)