3D Zieherkennung

*Dieser Inhalt wurde mit KI (Beta) übersetzt und kann Fehler enthalten. Um diese Seite auf Englisch zu sehen, klicke hier.

Die Instanz DragDetector erleichtert und fördert die Interaktion mit 3D-Objekten in einer Erfahrung, wie das Öffnen von Türen und Schubladen, das Verschieben eines Teils, das Greifen und Werfen eines Bowlingballs, das Zurückziehen und Abfeuern einer Schleuder und vieles mehr. Zu den wichtigsten Funktionen gehören:

  • Platziere einen DragDetector unter jedem BasePart oder Model, um es über alle Eingaben (Maus, Touch, Gamepad und VR) ziehbar zu machen, und das ganz ohne eine einzige Zeile Code.

  • Wähle aus verschiedenen Ziehen-Stilen, definiere, wie das Objekt auf Bewegungen reagiert, und wende optional Achsen- oder Bewegungsgrenzen an.

  • Skripts können auf die Manipulation gezogener Objekte reagieren, um die Benutzeroberfläche zu steuern oder logische Entscheidungen zu treffen, wie z. B. das Anpassen der Lichtstärke in einem Raum basierend auf einem schiebenden Wandschalterdimmer.

  • Spieler können verankerte Teile oder Modelle manipulieren, und sie bleiben genau dort, wo du sie bei der Freigabe platziert hast.

  • DragDetectors funktionieren im Studio, solange du die Werkzeuge Auswählen, Bewegen, Skalieren oder Drehen nicht verwendest, wodurch es einfacher ist, ziehbare Objekte während der Bearbeitung zu testen und anzupassen.

Objekte ziehbar machen

Um ein Teil oder Modell ziehbar zu machen, füge einfach einen DragDetector als direkten Nachfolger hinzu.

  1. Im Fenster Explorer, fahre mit der Maus über das Part, MeshPart oder Model und klicke auf die ⊕ Schaltfläche. Ein Kontextmenü wird angezeigt.

  2. Wähle im Menü einen DragDetector ein.

  3. Standardmäßig wird das Objekt jetzt im Bodenbereich ziehbar sein, aber du kannst seinen DragStyle anpassen, definieren, wie es auf Bewegungen reagiert und optional Achsen- oder Bewegungsgrenzen anwenden.

Zieherkennung anpassen

Ziehstil

DragDetectors ordnen die Cursorbewegung virtuellen Linien und Ebenen zu, um vorgeschlagene 3D-Bewegungen zu berechnen. Über die Eigenschaft DragStyle kannst du aus verschiedenen Zuordnungen wählen, die deinen Bedürfnissen entsprechen. Zum Beispiel erzeugt TranslatePlane eine Translation in einer virtuellen Ebene, während RotateAxis eine Rotation um eine virtuelle Achse erzeugt.

EinstellungBeschreibung
TranslateLine1D-Bewegung entlang der Achse des Detektors Axis, standardmäßig die Weltachse Y.
TranslatePlane2D-Bewegung in der Ebene, die senkrecht zur Achse des Detektors Axis steht, standardmäßig die Welt-Ebene XZ.
TranslatePlaneOrLine2D-Bewegung in der Ebene senkrecht zur Achse des Detektors Axis und, wenn der Modifier aktiv ist, 1D-Bewegung entlang der Achse des Detektors Axis.
TranslateLineOrPlane1D-Bewegung entlang der Achse des Detektors Axis und, wenn der Modifier aktiv ist, 2D-Bewegung in der Ebene senkrecht zur Achse des Detektors Axis.
TranslateViewPlane2D-Bewegung in der Ebene senkrecht zur Ansicht der Kamera. In diesem Modus wird die Ebene ständig aktualisiert, selbst während des Ziehens, und wird immer der aktuellen Ansicht der Kamera zugewandt.
RotateAxisRotation um die Achse des Detektors Axis, standardmäßig die Weltachse Y.
RotateTrackballTrackball-Rotation, die weiter angepasst wird durch die Eigenschaften TrackballRadialPullFactor und TrackballRollFactor.
BestForDeviceTranslatePlaneOrLine für Maus und Gamepad; TranslatePlane für Touch; 6DOF für VR.
ScriptableBerechnet die gewünschte Bewegung über eine benutzerdefinierte Funktion, die über SetDragStyleFunction() bereitgestellt wird.

Ziehrichtung

Standardmäßig sind 3D-Bewegungen und die zugehörige DragStyle auf den Weltbereich abgebildet. Du möchtest möglicherweise die ReferenceInstance, Orientation oder Axis ändern, beispielsweise beim Erstellen von Zieherkennungen für Modelle mit verstellbaren Teilen.

EigenschaftBeschreibungStandard
ReferenceInstanceEine Instanz, deren Pivot den Referenzrahmen für den Zieherkennung bereitstellt. Der DragFrame wird relativ zu diesem Referenzrahmen ausgedrückt, der über GetReferenceFrame() abgerufen werden kann. Wenn der Referenzrahmen nil ist, erfolgt die Translation in Richtung der Eigenschaft Axis im Weltbereich (oder in der Ebene senkrecht dazu).nil
OrientationBestimmt die YXZ-Rotation der Bewegungsachsen relativ zum Referenzrahmen (ändert nicht die Ausrichtung des Referenzrahmens selbst). Lineare Translation und axiale Rotation finden auf dieser neu orientierten Y-Achse statt, und die planare Translation erfolgt in der XZ-Ebene. Eine Änderung dieses Wertes aktualisiert automatisch Axis und umgekehrt.(0, 0, 0)
AxisDie primäre Bewegungsachse, ausgedrückt relativ zum Referenzrahmen. Eine Änderung dieses Wertes aktualisiert automatisch Orientation und umgekehrt.(0, 1, 0)

Reaktion auf Bewegung

Die Eigenschaft ResponseStyle gibt an, wie ein Objekt auf die vorgeschlagene Bewegung reagiert, abhängig davon, ob das Objekt Anchored ist oder nicht.

EinstellungAngekettetes VerhaltenUnangekettetes Verhalten
GeometricSowohl innerhalb der laufenden Erfahrung als auch im Studio-Bearbeitungsmodus wird die Position/Ausrichtung eines angestellten Objekts genau aktualisiert, um die vorgeschlagene Bewegung widerzuspiegeln.Für ein unangestelltes Objekt ist das Verhalten dasselbe wie bei einem angestellten Objekt. Jedoch wird in einer laufenden Erfahrung das Objekt zu Beginn des Ziehens angestellt und nach der Freigabe des Ziehens wieder unangestellt.
PhysicalEin angestelltes Objekt wird standardmäßig auf Geometric-Verhalten eingestellt, da es nicht von Kräften beeinflusst wird.Ein unangestelltes Objekt wird durch Zwangskräfte bewegt, die versuchen, es in die gewünschte Position und/oder Ausrichtung zu bringen, die durch die vorgeschlagene Bewegung gegeben ist.
CustomDas Objekt wird sich überhaupt nicht bewegen, aber DragFrame wird weiterhin aktualisiert und du kannst auf die Ziehmanipulation reagieren, wie du möchtest.(gleich wie angestellt)

Achsen- & Bewegungsgrenzen

Standardmäßig gibt es keine Grenzen für 3D-Bewegungen, außer den inhärenten Einschränkungen der DragStyle. Wenn notwendig, kannst du minimale und maximale Grenzen für sowohl Translation als auch Rotation anwenden. Beachte jedoch, dass dies keine Einschränkungen sind; sie behindern lediglich die Versuche des Zieherkennungs, Bewegungen zu generieren, um innerhalb der Grenzen zu bleiben.

EigenschaftenBeschreibungStandard

MinDragTranslation
MaxDragTranslation

Begrenzt die Ziehtranslation in jeder Dimension. Wenn MaxDragTranslation größer ist als MinDragTranslation, wird die Translation innerhalb dieses Bereichs eingeengt.(0, 0, 0)

MinDragAngle
MaxDragAngle

Nur relevant, wenn DragStyle auf RotateAxis eingestellt ist. Wenn MaxDragAngle größer ist als MinDragAngle, wird die Rotation innerhalb dieses Bereichs eingeengt.0

Zieherlaubnisse

Die Erlaubnis von Spielern, mit einer bestimmten Instanz der Zieherkennung zu interagieren, kann über die Eigenschaft PermissionPolicy festgelegt werden. Dies ist standardmäßig auf Enum.DragDetectorPermissionPolicy.Everybody eingestellt und kann auch geändert werden, um scripted Berechtigungssteuerungen zu unterstützen, wie im Codebeispiel gezeigt.

EinstellungBeschreibung
NobodyKeine Spieler können mit der DragDetector interagieren.
EverybodyAlle Spieler können mit der DragDetector interagieren.
ScriptableDie Zieherlaubnisse der Spieler werden durch eine Funktion bestimmt, die über SetPermissionPolicyFunction() registriert ist. Unter dieser Einstellung wird die Registrierung einer Funktion oder die Rückgabe eines ungültigen Ergebnisses alle Spieler am Ziehen hindern.
DragDetector - Scripted Drag Permission

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)

Physikalische Reaktion

Vorausgesetzt, der Reaktionsstil eines Ziehers ist auf Physical eingestellt und wird auf ein unangestelltes Objekt angewendet, wird dieses Objekt durch Zwangskräfte bewegt, die versuchen, es in die Position/Ausrichtung zu bringen, die durch die vorgeschlagene Bewegung gegeben ist. Du kannst die physikalische Antwort weiter anpassen durch die folgenden Eigenschaften:

EigenschaftBeschreibungStandard
ApplyAtCenterOfMassWenn falsch, wird die Ziehkraft an dem Punkt angewendet, auf den der Benutzer klickt. Wenn wahr, wird die Kraft am Schwerpunkt des Objekts angewendet.false
MaxForceMaximale Kraft, die angewendet wird, damit das Objekt sein Ziel erreicht.10000000
MaxTorqueMaximales Drehmoment, das angewendet wird, damit das Objekt sein Ziel erreicht.10000
ResponsivenessHöhere Werte führen dazu, dass das Objekt schneller sein Ziel erreicht.10

Modifier-Eingabe

Einige DragStyle-Modi erlauben es Benutzern, eine Modifier-Taste/-Taste gedrückt zu halten, um das gezogene Objekt auf verschiedene Weise zu manipulieren. Standardmäßig ist der Modifier auf LeftControl auf PC, ButtonR1 auf Gamepad oder ButtonL2 auf VR. Du kannst diese Modifier durch die Eigenschaften KeyboardModeSwitchKeyCode, GamepadModeSwitchKeyCode oder VRSwitchKeyCode der Instanz der Zieherkennung anpassen.

Replikation

Wenn die Eigenschaft RunLocally falsch (Standard) ist, interpretiert der Client alle Eingaben, um Daten zu erzeugen, die er an den Server sendet, um das Ziehen durchzuführen. In diesem Modus müssen alle benutzerdefinierten Ereignissignale und registrierten Funktionen im Server Scripts sein.

Wenn die Eigenschaft RunLocally wahr ist, werden keine Ereignisse an den Server repliziert. Alle benutzerdefinierten Ereignissignale und registrierten Funktionen müssen im Client LocalScripts sein und du musst Remote-Events verwenden, um notwendige Änderungen an den Server zu übertragen.

Skriptreaktionen auf Klicken und Ziehen

Durch Ereignissignale, Eigentumsänderungen, Scriptable Ziehstil und benutzerdefinierte Funktionen können Skripte auf die Manipulation gezogener Objekte reagieren, um die Benutzeroberfläche zu steuern oder logische Entscheidungen zu treffen, beispielsweise um das Lichtniveau in einem Raum basierend auf einem schiebenden Wandschalterdimmer anzupassen.

Ereignissignale

Durch die folgenden Ereignissignale kannst du erkennen, wann ein Benutzer mit dem Ziehen eines Objekts beginnt, fortfährt und aufhört.

EreignisBeschreibung
DragStartAusgelöst, wenn ein Benutzer mit dem Ziehen des Objekts beginnt.
DragContinueAusgelöst, wenn ein Benutzer das Ziehen des Objekts fortsetzt, nachdem DragStart initiiert wurde.
DragEndAusgelöst, wenn ein Benutzer aufhört, das Objekt zu ziehen.
DragDetector - Ereignissignale

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)

Änderungen des Ziehrrahmens

Zusätzlich zu Ereignissignalen kannst du Änderungen am DragFrame des Detektors direkt überwachen.

DragDetector - DragFrame Änderungen

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

Scripted Ziehstil

Wenn du den DragStyle eines Detektors auf Scriptable einstellst, kannst du deine eigene Funktion bereitstellen, die einen Ray annimmt und eine Weltkoordinate CFrame zurückgibt. Der Detektor wird die Bewegung so anpassen, dass das gezogene Objekt dorthin gelangt.

DragDetector - Scripted DragStyle

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)
-- Exclude dragged object from raycast detection
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)

Benutzerdefinierte Einschränkungsfunktion

Zieherkennung hat keine eingebauten Bewegungsregeln für Raster und Schnappen, aber du kannst benutzerdefinierte Einschränkungsfunktionen registrieren, um das DragFrame des Detektors zu bearbeiten, bevor es angewendet wird. Zum Beispiel kannst du die Bewegung auf einem Raster halten, indem du Positionen auf Vielfache des Rasterincremente rundest oder ein Schachspiel mit erlaubten Bewegungsregeln für jede Figur simulieren.

DragDetector - Benutzerdefinierte Einschränkungsfunktion

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()

Beispielverwendung

Unangestellte physikalische Objekte

Eine grundlegende Implementierung der Zieherkennung ist ein Turmbalance-Spiel, bei dem die Spieler vorsichtig Teile entfernen müssen und versuchen, den Turm aufrecht zu halten. In der folgenden Turmstruktur hat jedes Teil einen untergeordneten DragDetector mit dem Standard DragStyle von TranslatePlane, sodass die Spieler die Teile nach außen ziehen, jedoch nicht nach oben oder unten.

Angekettete Modelle mit verstellbaren Teilen

Du kannst leicht Modelle erstellen und teilen, die hauptsächlich angestellt sind, aber eines oder mehrere untergeordnete Teile/Modelle haben, die Spieler ziehen können. Zum Beispiel hat der folgende Schreibtisch zwei Schubladen, die die Spieler öffnen können, um zu inspizieren, was darin ist.

Zieherkennung und Einschränkungen

Du kannst Zieherkennung mit Constraints kombinieren, zum Beispiel bei einer Marionettenpuppe. In der folgenden Konfiguration sind die Steuergriffe verankert, die Körperteile sind unangekettet, und Einschränkungen halten die Marionette zusammen. Das Bewegen der Griffe mit dem TranslateViewPlane DragStyle lässt die Marionette tanzen, und die einzelnen Körperteile können ebenfalls mit Zieherkennung bewegt werden, während das Modell seine Integrität behält.

3D-Benutzerschnittstellen

3D-Benutzerschnittstellen sind leicht durch Zieherkennung erreichbar, wie das Anpassen der Helligkeit eines SpotLight basierend auf einem schiebenden Schalterdimmer. Du kannst auch die X- und Z-Achsen einzeln erkennen, um zwei verschiedene Aspekte einer 3D-Benutzerschnittstelle zu steuern, beispielsweise die Size, Speed und Color eines ParticleEmitter.

DragDetector - 3D-Benutzerschnittstelle

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
-- Passen Sie die Partikelgröße und -geschwindigkeit basierend auf dem X-Faktor des Ziehdetektors an
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)
-- Passen Sie die Partikelfarbe basierend auf dem Z-Faktor des Ziehdetektors an
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, das Roblox-Logo und "Powering Imagination" gehören zu unseren eingetragenen und nicht eingetragenen Markenzeichen in den USA und anderen Ländern.