Detektory przeciągania 3D

*Ta zawartość została przetłumaczona przy użyciu narzędzi AI (w wersji beta) i może zawierać błędy. Aby wyświetlić tę stronę w języku angielskim, kliknij tutaj.

Instancja DragDetector ułatwia i zachęca do interakcji z obiektami 3D w grze, takimi jak otwieranie drzwi i szuflad, przesuwanie części, chwytanie i rzucanie piłką do kręgli, naciąganie i strzelanie z procy i wiele więcej. Kluczowe cechy obejmują:

Uczyń obiekty przeciągalnymi

Aby uczynić dowolną część lub model przeciągalnym, wystarczy dodać DragDetector jako bezpośredniego potomka.

  1. W oknie Eksploratora najedź na Part, MeshPart lub Model i kliknij przycisk ⊕. Wyświetli się menu kontekstowe.

  2. Z menu wstaw DragDetector.

  3. Domyślnie obiekt będzie teraz przeciągalny w płaszczyźnie podłogi, ale możesz dostosować jego DragStyle, zdefiniować, jak reaguje na ruch i opcjonalnie zastosować ograniczenia osi lub ruchu.

Dostosuj detektory przeciągania

Styl przeciągania

DragDetectors mapują ruch kursora na wirtualne linie i płaszczyzny, aby obliczyć proponowany ruch 3D. Dzięki właściwości DragStyle możesz wybierać spośród różnych mapowań, aby dostosować je do swoich potrzeb. Na przykład, TranslatePlane produkuje translację w wirtualnej płaszczyźnie, podczas gdy RotateAxis produkuje rotację wokół wirtualnej osi.

UstawienieOpis
TranslateLineRuch 1D wzdłuż Axis detektora, domyślnie wzdłuż osi Y świata.
TranslatePlaneRuch 2D w płaszczyźnie prostopadłej do Axis detektora, domyślnie w płaszczyźnie XZ świata.
TranslatePlaneOrLineRuch 2D w płaszczyźnie prostopadłej do Axis detektora, a gdy modyfikator jest aktywny, ruch 1D wzdłuż Axis detektora.
TranslateLineOrPlaneRuch 1D wzdłuż Axis detektora, a gdy modyfikator jest aktywny, ruch 2D w płaszczyźnie prostopadłej do Axis detektora.
TranslateViewPlaneRuch 2D w płaszczyźnie prostopadłej do widoku kamery. W tym trybie płaszczyzna jest stale aktualizowana, nawet podczas przeciągania, i zawsze będzie zwrócona w kierunku aktualnego widoku kamery.
RotateAxisRotacja wokół Axis detektora, domyślnie wzdłuż osi Y świata.
RotateTrackballRotacja trackball, dodatkowo dostosowywana przez właściwości TrackballRadialPullFactor i TrackballRollFactor.
BestForDeviceTranslatePlaneOrLine dla myszy i kontrolera; TranslatePlane dla dotyku; 6DOF dla VR.
ScriptableOblicza pożądany ruch za pomocą funkcji niestandardowej dostarczonej przez SetDragStyleFunction().

Kierunek przeciągania

Domyślnie ruch 3D i związany z nim DragStyle mapują się na przestrzeń świata. Możesz jednak chcieć zmienić ReferenceInstance, Orientation lub Axis, na przykład podczas budowania detektorów przeciągania w modelach z regulowanymi częściami.

WłaściwośćOpisDomyślnie
ReferenceInstanceInstancja, której pivot zapewnia ramkę odniesienia dla detektora przeciągania. DragFrame jest wyrażona w odniesieniu do tej ramki odniesienia, którą można uzyskać za pomocą GetReferenceFrame(). Jeśli ramka odniesienia jest nil, translacja będzie w kierunku (lub w płaszczyźnie prostopadłej do) właściwości Axis w przestrzeni świata.nil
OrientationOkreśla YXZ rotację osi ruchu w odniesieniu do ramki odniesienia (nie zmienia orientacji samej ramki odniesienia). Translacja liniowa i rotacja osiowa będą na tej zreorientowanej osi Y, a translacja płaszczyzny w płaszczyźnie XZ. Zmiana tej wartości automatycznie aktualizuje Axis i odwrotnie.(0, 0, 0)
AxisGłówna oś ruchu, wyrażona w odniesieniu do ramki odniesienia. Zmiana tej wartości automatycznie aktualizuje Orientation i odwrotnie.(0, 1, 0)

Reakcja na ruch

Właściwość ResponseStyle określa, jak obiekt reaguje na proponowany ruch, w zależności od tego, czy obiekt jest Anchored, czy nie.

UstawienieZachowanie zakotwiczoneZachowanie niezwiązane
GeometricZarówno w działającej grze, jak i w trybie edycji Studio, pozycja/orientacja zakotwiczonego obiektu będzie aktualizowana, aby dokładnie odzwierciedlać proponowany ruch.Dla niezwiązanego obiektu zachowanie jest takie samo jak dla zakotwiczonego obiektu. Jednak w działającej grze obiekt będzie zakotwiczony na początku przeciągania i przywrócony do niezwiązanego po zwolnieniu przeciągania.
PhysicalZakotwiczony obiekt domyślnie będzie miał zachowanie Geometric, ponieważ nie jest pod wpływem sił.Niezwiązany obiekt będzie poruszany przez siły ograniczające, które próbują przynieść go do pożądanej pozycji i/lub orientacji określonej przez proponowany ruch.
CustomObiekt w ogóle się nie poruszy, ale DragFrame nadal będzie aktualizowany, a Ty możesz reagować na manipulację przeciąganiem w dowolny sposób.(tak samo jak zakotwiczony)

Ograniczenia osi i ruchu

Domyślnie nie ma ograniczeń dla ruchu 3D poza wrodzonymi ograniczeniami DragStyle. W razie potrzeby możesz zastosować minimalne i maksymalne ograniczenia zarówno dla translacji, jak i rotacji. Należy jednak pamiętać, że nie są to ograniczenia; jedynie utrudniają próby detektora przeciągania generowania ruchu, aby pozostać w granicach.

WłaściwościOpisDomyślnie
MinDragTranslation
MaxDragTranslation
Ograniczenia dla translacji przeciągania w każdej osi. Jeśli MaxDragTranslation jest większe niż MinDragTranslation, translacja będzie ograniczona w tym zakresie.(0, 0, 0)
MinDragAngle
MaxDragAngle
Relewantne tylko wtedy, gdy DragStyle jest ustawione na RotateAxis. Jeśli MaxDragAngle jest większe niż MinDragAngle, rotacja będzie ograniczona w tym zakresie.0

Uprawnienia do przeciągania

Uprawnienia graczy do interakcji z danym instancją detektora przeciągania można określić za pomocą właściwości PermissionPolicy. Domyślnie jest ustawione na Enum.DragDetectorPermissionPolicy.Everybody, a także można je zmienić, aby wspierać skryptowe kontrole uprawnień, jak pokazano w przykładzie kodu.

UstawienieOpis
NobodyŻaden gracz nie może interagować z DragDetector.
EverybodyWszyscy gracze mogą interagować z DragDetector.
ScriptableUprawnienia do przeciągania graczy będą określane przez funkcję zarejestrowaną za pomocą SetPermissionPolicyFunction(). W tym ustawieniu brak rejestracji funkcji lub zwrócenie nieprawidłowego wyniku uniemożliwi wszystkim graczom przeciąganie.
DragDetector - Skryptowane uprawnienia do przeciągania
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)

Reakcja fizyczna

Zakładając, że styl reakcji detektora jest ustawiony na Physical i jest zastosowany do niezwiązanego obiektu, ten obiekt będzie poruszany przez siły ograniczające, które próbują przynieść go do pozycji/orientacji określonej przez proponowany ruch. Możesz dodatkowo dostosować reakcję fizyczną za pomocą następujących właściwości:

WłaściwośćOpisDomyślnie
ApplyAtCenterOfMassGdy fałsz, siła przeciągania jest stosowana w punkcie, w którym użytkownik klika. Gdy prawda, siła jest stosowana w centrum masy obiektu.false
MaxForceMaksymalna siła stosowana, aby obiekt osiągnął swój cel.10000000
MaxTorqueMaksymalny moment obrotowy stosowany, aby obiekt osiągnął swój cel.10000
ResponsivenessWyższe wartości powodują, że obiekt szybciej osiąga swój cel.10

Modyfikator wejściowy

Niektóre tryby DragStyle pozwalają użytkownikom przytrzymać klawisz/przycisk modyfikatora, aby manipulować przeciąganym obiektem w różny sposób. Domyślnie modyfikator to LeftControl na PC, ButtonR1 na kontrolerze lub ButtonL2 na VR. Możesz dostosować te modyfikatory za pomocą właściwości KeyboardModeSwitchKeyCode, GamepadModeSwitchKeyCode lub VRSwitchKeyCode instancji detektora przeciągania.

Replikacja

Gdy właściwość RunLocally jest fałszywa (domyślnie), klient interpretuje wszystkie wejścia, aby wygenerować dane, które wysyła do serwera w celu wykonania przeciągania. W tym trybie wszystkie niestandardowe sygnały zdarzeń i zarejestrowane funkcje muszą znajdować się w serwerowych Scripts.

Gdy właściwość RunLocally jest prawdziwa, żadne zdarzenia nie są replikowane do serwera. Wszystkie niestandardowe sygnały zdarzeń i zarejestrowane funkcje muszą znajdować się w lokalnych LocalScripts, a Ty musisz używać zdarzeń zdalnych, aby propagować niezbędne zmiany do serwera.

Odpowiedzi skryptów na klikanie i przeciąganie

Dzięki sygnałom zdarzeń, zmianom właściwości, stylowi przeciągania Scriptable i funkcjom niestandardowym, skrypty mogą reagować na manipulację przeciąganymi obiektami, aby sterować interfejsem użytkownika lub podejmować logiczne decyzje, takie jak dostosowywanie poziomu światła w pomieszczeniu w zależności od suwaka ściennego.

Sygnały zdarzeń

Dzięki następującym sygnałom zdarzeń możesz wykryć, kiedy użytkownik zaczyna, kontynuuje i kończy przeciąganie obiektu.

ZdarzenieOpis
DragStartWywoływane, gdy użytkownik zaczyna przeciągać obiekt.
DragContinueWywoływane, gdy użytkownik kontynuuje przeciąganie obiektu po zainicjowaniu DragStart.
DragEndWywoływane, gdy użytkownik przestaje przeciągać obiekt.
DragDetector - Sygnały zdarzeń
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)

Zmiany w ramce przeciągania

Oprócz sygnałów zdarzeń możesz monitorować zmiany w DragFrame detektora bezpośrednio.

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

Skryptowany styl przeciągania

Jeśli ustawisz DragStyle detektora na Scriptable, możesz dostarczyć własną funkcję, która przyjmuje Ray i zwraca CFrame w przestrzeni świata. Detektor przeniesie ruch tak, aby przeciągany obiekt trafił w to niestandardowe miejsce/orientację.

DragDetector - Skryptowany 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)
-- Wyklucz przeciągany obiekt z detekcji raycast
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)

Niestandardna funkcja ograniczająca

Detektory przeciągania nie mają wbudowanych zasad ruchu dotyczących siatek i przyciągania, ale możesz zarejestrować niestandardowe funkcje ograniczające, aby edytować DragFrame detektora przed jego zastosowaniem. Na przykład możesz utrzymać ruch na siatce, zaokrąglając pozycje do wielokrotności przyrostu siatki lub symulować grę w szachy z zasadami ruchu legalnymi dla każdego figury.

DragDetector - Niestandardowa funkcja ograniczająca
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)
-- Gdy to konieczne, usuń funkcję ograniczającą, wywołując connection:Disconnect()

Przykład użycia

Niezwiązane obiekty fizyczne

Podstawowa implementacja detektorów przeciągania to gra w równowagę wieży, w której gracze muszą ostrożnie usuwać elementy i próbować utrzymać wieżę w pionie. W poniższej strukturze wieży każdy element ma dziecko DragDetector z domyślnym DragStyle ustawionym na TranslatePlane, aby gracze mogli ciągnąć elementy na zewnątrz, ale nie w górę lub w dół.

Zakotwiczone modele z regulowanymi częściami

Możesz łatwo tworzyć i udostępniać modele, które są głównie zakotwiczone, ale mają jedną lub więcej części/modeli, które gracze mogą przeciągać. Na przykład, poniższe biurko ma dwie szuflady, które gracze mogą otworzyć, aby sprawdzić, co jest w środku.

Detektory przeciągania i ograniczenia

Możesz łączyć detektory przeciągania z Constraints, na przykład marionetką. W poniższym ustawieniu uchwyty kontrolne są zakotwiczone, części ciała są niezwiązane, a ograniczenia trzymają marionetkę razem. Przesuwanie uchwytów za pomocą DragStyle TranslateViewPlane sprawia, że marionetka tańczy, a poszczególne części ciała mogą być również przesuwane za pomocą detektorów przeciągania, wszystko to podczas gdy model zachowuje swoją integralność.

Interfejsy użytkownika 3D

Interfejsy użytkownika 3D są łatwe do osiągnięcia dzięki detektorom przeciągania, na przykład dostosowywaniu jasności SpotLight w zależności od suwaka. Możesz również wykrywać osie X i Z indywidualnie, aby kontrolować dwa różne aspekty interfejsu użytkownika 3D, takie jak Size, Speed i Color emitera cząsteczek.

DragDetector - Interfejs użytkownika 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
-- Dostosuj rozmiar cząsteczek i prędkość na podstawie czynnika X detektora przeciągania
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)
-- Dostosuj kolor cząsteczek na podstawie czynnika Z detektora przeciągania
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. Nazwa Roblox, logo Roblox oraz hasło „Powering Imagination” należą do naszych zarejestrowanych i niezarejestrowanych znaków towarowych na terenie Stanów Zjednoczonych oraz w innych krajach.