Instancja DragDetector ułatwia i zachęca do interakcji z obiektami 3D w doświadczeniu, takimi jak otwieranie drzwi i szuflad, przesuwanie części wokół, chwytanie i rzucanie kulą do kosza, przytrzymywanie i strzelanie slingshotem, i wiele więcej. Key Features include:
Umieść DragDetector pod dowolnym BasePart lub Model aby 2> uczynić go przeciągniętym2> poprzez wszystkie wejścia (mysz, dotykaj, gamepad i VR), wszystko bez pojedynczej linii kodu.
Wybierz z kilku стилей拖动, zdefiniuj, jak obiekt reaguje na ruch i opcjonalnie zastosuj ograniczenia osi lub ruchu.
Skrypty mogą odpowiadać na manipulację przeciąganymi obiektami , aby zachęcić UI lub podejmować logiczne decyzje, takie jak dostosowywanie poziomu światła w pokoju w oparciu o przełącznik światła przesuwnej.
Gracze mogą manipulować zaczepionymi częściami lub modelami, a zostaną dokładnie tam, gdzie je umieścili po uwolnieniu.
Class.DragDetector|DragDetectors pracy w Studio tak długo, jak jesteś nie używając narzędzi Wybierz , 0>Przenieś0>, 3>Skala3> lub DragDetectors6>, aby ułatwić testowanie i dostosowywanie przeciąganych obiektów podczas edytowania.
Umożliwienie przeciągania obiektów
Aby uczynić dowolną część lub model przeciągalnym, po prostu dodaj DragDetector jako bezpośredniego potomka.
W oknie Explorer, przesuń się nad Class.Part , 2> Class.MeshPart2> lub 5> Class.Model5> i kliknij przycisk ⊕. Wyświetlony zostanie menu kontekstowe.
Z menu, wklej DragDetector .
Domyślnie obiekt będzie teraz przeciągnięty po gruntowym planie, ale możesz dostosować jego DragStyle , określić, jak reaguje na ruch, i opcjonalnie zastosować granice lub ograniczenia ruchu.
Dostosowywanie wykrywaczy przeciągania
Styl przeciągania
DragDetectors mapę kursora mapy przesuwa się w kierunku wirtualnych linii i samolotów, aby obliczyć proponowaną 3D. Przez właściwość DragStyle możesz wybrać z różnych map, aby dostosować się do swoich potrzeb.
Ustawienia | Opis |
---|---|
TranslateLine | 1D ruch wzdłuż osi Axis , domyślnie światowa osi Y . |
TranslatePlane | 2D ruch w samolocie perpendicular do detektora Axis , domyślnie świat XZ samolotu. |
TranslatePlaneOrLine | 2D ruch w samolocie perpendicular do detektora Axis i, gdy modyfikator jest aktywny, 1D ruch wzdłuż Class.DragDetector.Axis|Axis detektora. |
TranslateLineOrPlane | 1D ruch wzdłuż osi Axis i, gdy modyfikator jest aktywny, 2D ruch w samolocie wzdłuż osi Class.DragDetector.Axis|Axis . |
TranslateViewPlane | 2D ruch w samolocie perpendicular do widoku kamery. W tym trybie, samolot jest nieustannie aktualizowany, nawet podczas przeciągania, i zawsze będzie twarzyć obecny widok kamery. |
RotateAxis | Rotacja wokół Axis detektora, domyślnie światowa osi Y . |
RotateTrackball | Rotacja kulowa śledź, dalsza dostosowana poprzez Class.DragDetector.TrackballRadialPullFactor|TrackballRadialPullFactor i Class.DragDetector.TrackballRollFactor|TrackballRadialPullFactor właściwości. |
BestForDevice | TłumaczPrzezGlądajStronęAlboPrzezGamepad dla myszy i gamepadu; TłumaczPrzezDotykajStronęAlboPrzezGamepad dla dotykania; 6DOF dla VR. |
Scriptable | Oblicza pożądane ruchy za pomocą niestandardowej funkcji dostarczonej poprzez SetDragStyleFunction() . |
Kierunek przesuwania
Domyślnie 3D motion i powiązany DragStyle mapy do przestrzeni kosmicznej. Ale można chcieć zmienić ReferenceInstance , Orientation lub 1>
Własność | Opis | Domyślny |
---|---|---|
ReferenceInstance | Instancja, której pivot dostarcza ramę odniesienia dla wykrywacza przeciągnięcia. DragFrame jest wyrażony w odniesieniu do tej ramy odniesienia, która może być odzyskana za | nil |
Orientation | Określa rotację YXZ w przestrzeniach ruchu w stosunku do referencji (nie zmienia orientacji samej referencji). Linearne tłumienie i obroty osiowe będą na tej osi Y i planary tłumienie w przestrzeniach X . zmiany tej wartości automatycznie aktualizuje 1> Class | (0, 0, 0) |
Axis | Główną osią ruchu, wyrażoną w odniesieniu do referencyjnej ramy. Zmienie tego wartości automatycznie aktualizuje Orientation i vice versa. | (0, 1, 0) |
Odpowiedź na ruch
Właściwość ResponseStyle określa, jak reaguje obiekt na proponowaną ruch, w zależności od tego, czy obiekt jest Anchored lub nie.
Ustawienia | Zakorzenione zachowanie | Zachowanie bez przyвяzania |
---|---|---|
Geometric | Zarówno w doświadczeniu bieżącym, jak i w trybie edytowania Studio, pozycja/orientacja zakotwiczonego obiektu zostanie zaktualizowana, aby dokładnie odzwierciedlić proponowany ruch. | Dla niewiązanego obiektu zachowanie jest takie same jak dla związanego obiektu. Jako jednak w doświadczeniu bieżącym obiekt zostanie związany na początku przeciągania i zostanie przywrócony do niewiązanego po przeciągnięciu. |
Physical | Zakotwiczone obiektu domyślnie będzie zachowywał się Geometryjny zachowanie, ponieważ nie jest ona dotykana przez siły. | Niezakorowane obiektu zostanie przesunięte przez siły ograniczenia, które próbują go przesunąć do pożądanej pozycji i/lub orientacji zgodnie z proponowaną animacją. |
Custom | Obiekt się nie porusza wszystko, ale DragFrame nadal będzie aktualizowany i możesz zareagować na manipulację przeciąganiem, jak chcesz. | (to samo jak związane) |
Osi & Limitowanie Ruchu
Domyślnie nie ma ograniczeń dla ruchu 3D poza ograniczeniami wrodzonymi w DragStyle. Jeśli to konieczne, można zastosować minimalne i maksymalne ograniczenia dla obu tłumaczeń i rotacji. Uwaga, jednak, że te nie są ograniczeniami; one po prostu zapobiegają, aby drag detector's próby generowania ruchu w cel
Właściwości | Opis | Domyślny |
---|---|---|
Class.DragDetector.MinDragTranslation|MinDragTranslation``Class.DragDetector.MaxDragTranslation|MaxDragTranslation | Ograniczenia do przetłumaczenia w każdym wymiarze. Jeśli MaxDragTranslation jest większy niż MinDragTranslation, tłumaczenie zostanie sklejone w tym zakresie. | (0, 0, 0) |
Class.DragDetector.MinDragAngle|MinDragAngle``Class.DragDetector.MaxDragAngle|MaxDragAngle | Tylko istotne, jeśli DragStyle ustawiony na RotateAxis . Jeśli MaxDragAngle jest większy niż 1> Class.DragDetector.MinDragAngle|MinDragAngle1>, to rotacja zostanie sklepiona w ramach tego zakresu. | 0 |
Zezwolenie na przeciąganie
Zezwolenie graczy na interakcję z określonym modelem wykrywania przeciągnięcia można określić przez właściwość PermissionPolicy. Jest ustawione na Enum.DragDetectorPermissionPolicy.Everybody domyślnie i może być zmienione, aby wspierać zautomatyzowane kontrole uprawnień, jak pokazano w przykładzie kodu.
Ustawienia | Opis |
---|---|
Nobody | Żadni gracze nie mogą interagować z DragDetector . |
Everybody | Wszyscy gracze mogą wchodzić w interakcję z DragDetector. |
Scriptable | Zezwolenia na przeciąganie graczy zostaną określone przez funkcję zarejestrowaną za pośrednictwem SetPermissionPolicyFunction(). W tym ustawienienie powoduje żadnego gracza do przeciągania, jeśli nie zarejestruje funkcji lub nie powróci wynik nieprawidłowy. |
DragDetector - Wbudowany zapis uprawnień
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)
Odpowiedź fizyczna
Załóż, że стиль odpowiedzi drażera ustawiony jest na Fizyczny i zastosowany do niezakorowanego obiektu, ten obiekt zostanie przesunięty przez siły ograniczające, które próbują go przynieć do pozycji/orientacji danej przez proponowany ruch. Możesz dostosować fizyczną odpowiedź poprzez następujące właściwości:
Własność | Opis | Domyślny |
---|---|---|
ApplyAtCenterOfMass | Gdy fałszywy, przytrzymuje siłę na punkt, na którym użytkownik kliknie. Gdy prawdziwy, siła jest stosowana w centrum masy obiektu. | fałszywy |
MaxForce | Maksymalna siła zastosowana, aby osiągnąć cel obiektu. | 10000000 |
MaxTorque | Maksymalny moment obrotowy zastosowany dla obiektu, aby osiągnąć jego cel. | 10000 |
Responsiveness | Wyższe wartości sprawiają, że obiekt szybciej osiągnie swój cel. | 10 |
Wejście zmodyfikowania
Replikacja
Gdy właściwość RunLocally jest fałszywa (domyślnie), klient interpretuje wszystkie wejścia, aby wyprodukować dane, które wysyłuje na serwer do wykonania拖. W tym trybie wszystkie sygnały i funkcje personalizowane muszą być w serwerze Scripts.
Gdy właściwość RunLocally jest prawdziwa, żadne wydarzenia nie są replikowane na serwer. Wszystkie sygnały i funkcje personalizowane muszą być w klientach LocalScripts i musisz używać zdalnych wydarzeń, aby rozprzestrzenić niezbędne zmiany na serwerze.
Skryptowane odpowiedzi na kliknięcie i przeciągnięcie
Przez sygnały wydarzeń , zmiany właściwości, Scriptable styl kopiowania i funkcje niestandardowe, skrypty mogą odpowiadać na manipulację przeciągniętymi obiektami do prowadzenia interfejsu użytkownika lub podejmowania logicznych decyzji, takich jak dostosowywanie poziomu światła w pokoju na podstawie przełącznika św
sygnały wydarzenia
Za pomocą następujących sygnałów wydarzeń możesz wykryć, gdy użytkownik rozpocznie, kontynuuje i zakończy przeciąganie obiektu.
Wydarzenie | Opis |
---|---|
DragStart | Wystąpi, gdy użytkownik zacznie przeciągać obiekt. |
DragContinue | Wyst?puje, gdy u?ytywaczka przedmiotu nadal przeciąga po nim po DragStart została uruchomiona. |
DragEnd | Wystąpi, gdy użytkownik przestanie przeciągać obiekt. |
DragDetector - Signale wydarzeń
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)
Przeciągnij zmiany ramy
Oprócz sygnałów wydarzeń , możesz bezpośrednio monitorować zmiany w DragFrame detektorze.
DragDetector - zmiany w klatce płynące
local dragDetector = script.Parent.DragDetector
dragDetector:GetPropertyChangedSignal("DragFrame"):Connect(function()
local currentDragTranslation = dragDetector.DragFrame.Position
print(currentDragTranslation)
end)
Zakodowany styl przeciągania
Jeśli ustawisz DragStyle detektora na Skrypty , możesz zapewnić własną funkcję, która odbiera Ray i zwraca światowy przestrzeń 1> Datatype.CFrame1> . Dedektor porusza ruch, aby przenieść obiekt przeciągnięty na to niestandard
DragDetector - Skryptowane style przeciągania
local dragDetector = script.Parent.DragDetector
dragDetector.DragStyle = Enum.DragDetectorDragStyle.Scriptable
local cachedHitPoint = Vector3.zero
local cachedHitNormal = Vector3.yAxis
local function followTheCursor(cursorRay)
-- Wyklucz przeciągnięty obiekt z wykrywania 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)
Funkcja Restrykcji Rozmiarów
Wykrywacze Drag nie mają zbudowanych zasad ruchu o sieciach i skręcaniem, ale możesz rejestrować funkcje ograniczeń, aby edytować DragFrame przed jego zastosowaniem. Na przykład możesz utrzymać ruch na sieciach przez zaokrąglenie pozycji po wielokrotności sieci lub simulować grę szachową z z
DragDetector - Funkcja Restrykcji Rozmiarów
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()
Przykładowe użycie
Niezakorowane obiekty fizyczne
Podstawową implementacją wykrywaczy przeciągnięcia jest gra w równowadze wieży, w której gracze muszą uważać, aby usunąć kawałki i próbować utrzymać wieżę w górze. W następującej strukturze wieży każdy kawałek ma dziecko DragDetector z domyślnym Class.DragDetector.
Zakotwiczone modele z dostępnymi częściami
Możesz łatwo tworzyć i dzielić się modelami, które są w większości przypadków przywiązane, ale które mają jedną lub więcej części dzieci/modeli, które gracze mogą przeciągnąć. Na przykład poniższy stół ma dwa szuflady, które gracze mogą otworzyć do inspekcji tego, co jest w środku.
Przeciągnij wykrywacze i ograniczenia
Możesz łączyć wykrywacze przeciągnięcia z Constraints , na przykład marionetę. W następnym ustawieniu kąty sterowe są związane, części ciała są odłączone i klamry trzymają marionetę razem. Rozpływając ręcznie klamry
Interfejsy użytkownika 3D
Interfejsy użytkownika 3D są łatwo dostępne poprzez wykrywacze przeciągania, takie jak dostosowanie jasności Class.SpotLight
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 i szybkość cząsteczek w zależności od czynnika X lokatora
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 w zależności od czynnika Z w wykrywaczu przeciągnięcia
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)