3D-Zieherdetektoren

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

Die DragDetector Instanz erleichtert und fördert die Interaktion mit 3D-Objekten in einem Erlebnis, wie das Öffnen von Türen und Schubladen, das Gleiten eines Teils, das Greifen und Werfen einer Bowlingkugel, das Zurückziehen und Feuern einer Schleuder und vieles mehr.Die wichtigsten Funktionen umfassen:

  • Platziere ein DragDetector unter jedem BasePart oder Model um es ziehbar zu machen über alle Eingänge (Maus, Touch, Gamepad und VR), alles ohne eine einzige Zeile Codes.

  • Wählen Sie aus mehreren Ziehstilen, definieren Sie, wie das Objekt auf Bewegung reagiert und wenden Sie optional Achsen- oder Bewegungslimiten an.

  • Skripte können auf die Manipulation von gezogenen Objekten reagieren, um die Benutzeroberfläche zu steuern oder logische Entscheidungen zu treffen, wie die Anpassung des Lichtniveaus in einem Raum basierend auf einem gleitenden Wandschalter-Dimmer.

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

  • Arbeite in Studio, solange du nicht die Werkzeuge Auswählen, Bewegen, Skalieren oder Drehen verwendest, was es einfacher macht, ziehbare Objekte während der Bearbeitung zu testen und anzupassen.

Objekte ziehbar machen

Um jedes Teil oder Modell ziehbar zu machen, füge einfach einen DragDetector als direkten Nachfolgerhinzu.

  1. In dem Explorer-Fenster bewegen Sie den Mauszeiger über die Part, MeshPart oder Model und klicken Sie auf die Schaltfläche ⊕. Ein Kontextmenü wird angezeigt.

  2. Aus dem Menü, füge einen DragDetector ein.

  3. Standardmäßig wird das Objekt jetzt in der Bodenebene ziehbar sein, aber du kannst seine anpassen, definieren, wie es auf Bewegung reagiert, und optional Achsen- oder Bewegungslimiten anwenden.

Anpassen von Drag-Detektoren

Ziehstil

DragDetectors Kursorbewegung auf virtuelle Linien und Flächen, um die vorgeschlagene 3D-Bewegung zu berechnen.Mit der EigenschaftenDragStyle kannst du aus verschiedenen Mappings wählen, um deinen Bedürfnissen gerecht zu werden.Zum Beispiel produziert TranslatePlane Übersetzung in einer virtuellen Fläche, während RotateAxis Rotation über eine virtuelle Achse erzeugt.

EinstellungBeschreibung
TranslateLine1D-Bewegung entlang der Axis des Detektors, standardmäßig die Welt Y -Achse.
TranslatePlane2D-Bewegung in der Ebene, die perpendikulär zum Detektor ist Axis , standardmäßig die Welt XZ -Fläche.
TranslatePlaneOrLine2D-Bewegung in der Ebene, die perpendikulär zum Detektor ist Axis und, wenn der Modifikator aktiv ist, 1D-Bewegung entlang des Detektors Axis .
TranslateLineOrPlane1D-Bewegung entlang der Axis des Detektors und, wenn der Modifikator aktiv ist, 2D-Bewegung in der Ebene, die parallel zur Ebene des Detektors Axis liegt.
TranslateViewPlane2D-Bewegung in der Fläche, die parallel zur Sicht der Kamera ist.In diesem Modus wird das Flugzeug ständig aktualisiert, auch während des Ziehens, und wird immer die aktuelle Ansicht der Kamera gegenüberstehen.
RotateAxisDrehung um die Achse des Detektors Axis, standardmäßig die Welt Y .
RotateTrackballTrackball-Rotation, weiter angepasst durch die TrackballRadialPullFactor und TrackballRollFactor Eigenschaften.
BestForDevice TranslatePlaneOrLine 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, 3D-Bewegung und die zugeordnete DragStyle-Karte in den Platz.Sie möchten jedoch möglicherweise die ReferenceInstance , Orientation oder Axis ändern, zum Beispiel beim Bau von Drag Detektoren in Modellen mit verstellbaren Teilen .

EigenschaftBeschreibungStandardmäßig
ReferenceInstanceEine Instanz, deren Drehpunkt den Referenzrahmen für den Dragdetektor liefert.Die DragFrame wird relativ zu diesem Referenzrahmen zum Ausdruck gebracht, der über GetReferenceFrame() abgerufen werden kann.Wenn der Referenzrahmen nil ist, wird die Übersetzung in Richtung (oder in der Ebene parallel zu) der Axis Eigenschaft in der Welt sein.nil
OrientationGibt die YXZ -Drehung der Bewegungsachsen im Vergleich zum Referenzrahmen an (ändert nicht die Orientierung des Referenzrahmens selbst).Lineare Translation und axiale Rotation werden auf dieser umorientierten Y -Achse und planare Translation in der XZ -Ebene sein.Das Ändern dieses Werts aktualisiert automatisch Axis und umgekehrt.(0, 0, 0)
AxisDie primäre Bewegungsachse, ausgedrückt in Bezug auf den Referenzrahmen. Ändern dieses Werts aktualisiert automatisch Orientation und umgekehrt.(0, 1, 0)

Antwort 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.

EinstellungVerankertes VerhaltenUnverankertes Verhalten
GeometricSowohl innerhalb des laufenden Erlebnisses als auch im Bearbeitungsmodus von Studio wird die Position/Ausrichtung eines angekerzten Objekts aktualisiert, um genau die vorgeschlagene Bewegung zu reflektieren.Für ein unverankertes Objekt ist das Verhalten das gleiche wie für ein verankertes Objekt.Bei einer laufenden Erlebniswird das Objekt jedoch am Beginn des Ziehens angeankert und bei Ziehfreigabe unverankert wiederhergestellt.
PhysicalEin angekerter Objekt wird standardmäßig auf Geometrisches Verhalten zurückgreifen, da es nicht von Kräften beeinflusst wird.Ein nicht verankertes Objekt wird durch Einschränkungskräfte verschoben, die versuchen, es an die gewünschte Position und/oder Orientierung zu bringen, die vom vorgeschlagenen Vorschlag gegeben wird.
CustomDas Objekt bewegt sich Allenicht, aber DragFrame wird immer noch aktualisiert und Sie können auf die Drag-Manipulation antworten, wie Sie möchten.(gleich wie angeankert)

Achsen- und Bewegungslimits

Standardmäßig gibt es keine Einschränkungen für 3D-Bewegung über die inhärenten Einschränkungen von DragStyle.Wenn nötig, kannst du sowohl für die Übersetzung als auch für die Rotation minimale und maximale Grenzen festlegen.Beachten Sie jedoch, dass dies keine Einschränkungen sind; sie hindern nur die Versuche des Ziehdetektors, Bewegung zu generieren, um innerhalb der Grenzen zu bleiben.

EigenschaftenBeschreibungStandardmäßig
Class.DragDetector.MinDragTranslation|MinDragTranslation``Class.DragDetector.MaxDragTranslation|MaxDragTranslationBegrenzungen für das Ziehen der Übersetzung in jeder Dimension. Wenn MaxDragTranslation größer als MinDragTranslation ist, wird die Übersetzung innerhalb dieses Bereichs gekappt.(0, 0, 0)
Class.DragDetector.MinDragAngle|MinDragAngle``Class.DragDetector.MaxDragAngle|MaxDragAngleNur relevant, wenn DragStyle auf RotateAxis eingestellt ist.Wenn MaxDragAngle größer als MinDragAngle ist, wird die Rotation innerhalb dieses Bereichs gekappt.0

Ziehe Berechtigungen

Die Berechtigung von Spielern, mit einer bestimmten Drag-Detektor-Instanz zu interagieren, kann durch die EigenschaftenPermissionPolicy angegeben werden.Dies wird standardmäßig auf Enum.DragDetectorPermissionPolicy.Everybody festgelegt und kann auch geändert werden, um skriptgesteuerte Berechtigungskontrollen zu unterstützen, wie im Codebeispiel gezeigt.

EinstellungBeschreibung
NobodyKeine Spieler können mit der DragDetector interagieren.
EverybodyAlle Spieler können mit dem DragDetector interagieren.
ScriptableDie Ziehberechtigungen der Spieler werden durch eine Funktion bestimmt, die über SetPermissionPolicyFunction() registriert wurde.Unter dieser Einstellung verhindert ein Fehler beim Registrieren einer Funktion oder das Rückgeben eines ungültigen Ergebnisses, dass alle Spieler ziehen.
DragDetector - Skriptierte Drag-Berechtigung

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)

Physikantwort

Angenommen, die Reaktionsweise eines Ziegers wird auf Physisch eingestellt, und sie wird auf ein unverankertes Objekt angewendet, wird dieses Objekt durch Einschränkungskräfte verschoben, die versuchen, es in die von der vorgeschlagenen Bewegung angegebene Position/Ausrichtung zu bringen.Sie können die physische Antwort weiter anpassen durch die folgenden Eigenschaften:

EigenschaftBeschreibungStandardmäßig
ApplyAtCenterOfMassWenn falsch, wird beim Klicken auf den Punkt Kraft angewendet. Wenn wahr, wird Kraft am Zentrum der Masse des Objekts angewendet.falsch
MaxForceMaximale Kraft, die für das Objekt angewendet wird, um sein Ziel zu erreichen.10000000
MaxTorqueMaximales Drehmoment für das Objekt, um sein Ziel zu erreichen.10000
ResponsivenessHöhere Werte veranlassen das Objekt, sein Ziel schneller zu erreichen.10

Modifikator-Eingabe

Einige DragStyle-Modi ermöglichen es Benutzern, eine Modifizierungstaste gedrückt zu halten, um das zu ziehende Objekt auf unterschiedliche Weise zu manipulieren.Standardmäßig ist der Modifizierer auf dem PC LeftControl, auf dem Gamepad ButtonR1 oder auf der VR ButtonL2.Du kannst diese Modifizierer durch die KeyboardModeSwitchKeyCode , GamepadModeSwitchKeyCode oder VRSwitchKeyCode Eigenschaften der Drag-Detektor-Instanz anpassen.

Replikation

Wenn die Eigenschaft RunLocally falsch ist (Standard), interpretiert der Client alle Eingabe, 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 auf dem Server Scripts sein.

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

Skriptantworten auf Klicken und Ziehen

Durch Ereignissignale, Eigenschaftsänderungen, Scriptable Drag-Stil und benutzerdefinierte Funktionen können Skripte auf die Manipulation von gezogenen Objekten reagieren, um die Benutzeroberfläche zu steuern oder logische Entscheidungen zu treffen, wie das Anpassen des Lichtniveaus in einem Raum basierend auf einem gleitenden Wandschalter-Dimmer.

Ereignissignale

Mit den folgenden Ereignissignalen kannst du erkennen, wann ein Benutzer beginnt, weiterzieht und beendet, ein Objekt zu ziehen.

EreignisBeschreibung
DragStartFeuert, wenn ein Benutzer beginnt, das Objekt zu ziehen.
DragContinueFeuert, wenn ein Benutzer das Objekt weiter zieht, nachdem DragStart initiiert wurde.
DragEndFeuert, 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)

Ziehe Rahmenänderungen

Zusätzlich zu Ereignissignalen kannst du Änderungen am Detektor DragFrame.

DragDetector - DragFrame-Änderungen

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

Skriptgesteuerte Ziehstil

Wenn du einen Detektor DragStyle auf Skriptbar einstellst, kannst du deine eigene Funktion bereitstellen, die einen Ray einschließt und eine Welt空间 CFrame zurückgibt.Der Detektor bewegt die Bewegung, damit das zugezogene Objekt an diese benutzerdefinierte Position/Ausrichtung gelangt.

DragDetector - Skriptgesteuerter 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)
-- Ausschließen des gedrückten Objekts aus der Raycast-Erkennung
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

Ziehbox-Detektoren haben keine integrierten Bewegungsregeln über Raster und Einstellung, aber du kannst benutzerdefinierte Einschränkungsfunktionen registrieren, um den Detektor DragFrame vor der Anwendung zu bearbeiten.Zum Beispiel können Sie die Bewegung auf einem Raster beibehalten, indem Sie Positionen auf Richtwerte für das Raster multiplizieren oder ein Schachspiel mit Regeln der Bewegung simulieren, die für jedes Element legal sind.

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

Unverankerte physische Objekte

Eine einfache Umsetzung von Drag Detektoren ist ein Turmgleichgewichtsspiel, bei dem Spieler Teile sorgfältig entfernen und versuchen müssen, den Turm aufrecht zu erhalten.In der folgenden Turmstruktur hat jedes Element ein Kind DragDetector mit einem Standard DragStyle von TranslatePlane , so dass Spieler die Teile nach außen ziehen können, aber nicht nach oben oder nach unten.

Verankerte Modelle mit verstellbaren Teilen

Du kannst leicht Modelle erstellen und teilen, die vor allem verankert sind, aber die ein oder mehrere Kinderteile/Modelle haben, die Spieler ziehen können.Zum Beispiel hat der folgende Schreibtisch zwei Schubladen, die Spieler öffnen können, um zu überprüfen, was sich darin befindet.

Ziehe Detektoren und Einschränkungen

Du kannst Drag-Detektoren mit Constraints kombinieren, zum Beispiel eine Marionettenpuppe.Im folgenden Setup sind die Steuergriffe angeankert, die Körperteile unangekört, und Einschränkungen halten die Marionette zusammen.Das Verschieben der Griffe mit der TranslateViewPlane macht das Marionetten-Tanz, und die einzelnen Körperteile können auch mit Drag-Detektoren verschoben werden, alles während das Modell seine Integrität behält.

3D-Benutzeroberflächen

3D-Benutzeroberflächen sind durch Drag-Detektoren leicht zu erreichen, wie das Anpassen der Helligkeit eines SpotLight basierenden Schiebereichsdimmers.Du kannst auch die X und Z Achsen einzeln erkennen, um zwei verschiedene Aspekte einer 3D-Benutzeroberfläche zu kontrollieren, wie die Size, Speed und Color eines ParticleEmitter.

DragDetector - 3D-Benutzeroberfläche

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
-- Zur Anpassung der Partikelgröße und Geschwindigkeit basierend auf Dragdetektor-X-Faktor
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)
-- Anpassen der Partikelfarbe basierend auf Drag-Detektor-Z-Faktor
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)