Instancja DragDetector ułatwia i zachęca do interakcji z obiektami 3D w doświadczeniu, takimi jak otwieranie drzwi i szuflad, przesuwanie części, chwytanie i rzucanie kulki bowlingowej, wyciąganie i wystrzelanie strzałki, a także wiele więcej.Główne funkcje obejmują:
Umieść DragDetector pod każdym BasePart lub Model aby uczynić go przeciąganym za pomocą wszystkich wejść (mysz, dotyk, gamepad i VR), bez pojedynczej linii kodu.
Wybierz z kilku stylów przeciągania , określ, jak obiekt odpowiada na ruch , a opcjonalnie zastosuj ograniczenia osi lub ruchu .
Skrypty mogą odpowiedzieć na manipulację przeciągniętymi obiektami, aby sterować interfejsem użytkownika lub podejmować logiczne decyzje, takie jak dostosowywanie poziomu oświetlenia w pokoju w oparciu o przełącznik regulowany przez przesuwającą się ścianę.
Gracze mogą manipulować zakotwiczone części lub modele i zostaną dokładnie tam, gdzie je umieścisz po wydaniu.
Praca w Studio tak długo, jak jesteś nie korzystasz z narzędzia Wybierz, Przesuń, Skala lub Obróć, co ułatwia testowanie i dostosowywanie przeciąganych obiektów podczas edycji.
Spraw, aby obiekty były przeciągane
Aby każda część lub model była przeciągana, po prostu dodaj DragDetector jako bezpośredni potomek.
W oknie Eksploratora przewiń nad Part, MeshPart lub Model i kliknij przycisk ⊕. Wyświetla się menu kontekstowe.
Z menu wstawь Detektor przeciągnięć .
Domyślnie obiekt będzie teraz przeciągany w płanie podziemnym, ale możesz dostosować jego , określić, jak reaguje na ruch, i opcjonalnie zastosować ograniczenia osi lub ruchu .
Dostosuj wykrywacze przeciągów
Przeciągnij styl
DragDetectors mapuje ruch kursora do wirtualnych linii i planów, aby obliczyć proponowany ruch 3D.Poprzez właściwość DragStyle możesz wybrać spośród różnych map odpowiednie dla Twoich potrzeb.Na przykład TranslatePlane wytwarza tłumaczenie w wirtualnym samolocie, podczas gdy RotateAxis wytwarza rotację wokół wirtualnego osi.
Ustawienie | Opis |
---|---|
TranslateLine | 1D ruch wzdłuż osi detektora Axis, domyślnie osi świata Y . |
TranslatePlane | 2D ruch w płanie równoległym do detektora Axis , domyślnie świat XZ planu. |
TranslatePlaneOrLine | 2D ruch w płanie równoległym do detektora Axis i, gdy aktywny jest modyfikator , 1D ruch wzdłuż detektora Axis. |
TranslateLineOrPlane | 1D ruch wzdłuż detektora Axis i, gdy aktywny jest modyfikator , 2D ruch w płanie równoległym do detektora Axis. |
TranslateViewPlane | 2D ruch w płanie równoległym do widoku kamery.W tym trybie samolot jest stale aktualizowany, nawet podczas przeciągania, i zawsze będzie miał widok obecnej kamery. |
RotateAxis | Rotacja wokół detektora Axis , domyślnie osi świata Y . |
RotateTrackball | Rotacja kuli śledzącej, dalsza dostosowywana za pomocą właściwości TrackballRadialPullFactor i TrackballRollFactor. |
BestForDevice | TranslatePlaneOrLine dla myszy i gamepada; TranslatePlane dla dotyku; 6DOF dla VR. |
Scriptable | Oblicza pożądaną kinematykę za pomocą niestandardowej funkcji dostarczanej za pośrednictwem SetDragStyleFunction(). |
Przeciągnij kierunek
Domyślnie, ruch 3D i związana z nim mapa DragStyle do przestrzeni świata.Jednak możesz chcieć zmienić ReferenceInstance , Orientation lub Axis , na przykład podczas budowania wykrywaczy przeciągów w modelach z regulowanymi częściami .
Właściwość | Opis | Domyślny |
---|---|---|
ReferenceInstance | Instancja, której osie dostarczają ramę odniesienia dla wykrywacza przeciągnięć dla detektora.The DragFrame jest wyrażony względem tego ramu referencyjnego, który można odzyskać za pomocą GetReferenceFrame() .Jeśli ram odniesienia jest nil, tłumaczenie będzie w kierunku (lub w płaszczyźnie perpendykularnej do) właściwości Axis w przestrzeni świata. | nil |
Orientation | Określa rotację YXZ osi ruchu względem ramy odniesienia (nie zmienia orientacji samej ramy odniesienia).Liniowa translacja i rotacja osiowa będzie na tym przekierowanym Y osi, a płaska translacja w planie XZ .Zmiana tej wartości automatycznie aktualizuje Axis i odwrotnie. | (0, 0, 0) |
Axis | Główna osia ruchu, wyrażona względem ramienia odniesienia. Zmiana tej wartości automatycznie aktualizuje Orientation i odwrotnie. | (0, 1, 0) |
Odpowiedź na ruch
Właściwość ResponseStyle określa, w jaki sposób obiekt odpowiada na proponowaną akcję, w zależności od tego, czy obiekt jest Anchored czy nie.
Ustawienie | Zakotwiczone zachowanie | Niezakotwiczone zachowanie |
---|---|---|
Geometric | Zarówno w trakcie wykonywania doświadczenia, jak i w trybie edycji w Studio, pozycja/orientacja osadzonego obiektu zostanie zaktualizowana, aby dokładnie odzwierciedlała proponowane ruchy. | Dla niezakotwiczonego obiektu zachowanie jest takie samo jak dla zakotwiczonego obiektu.Jednak w trakcie wykonywania doświadczenia obiekt zostanie zakotwiczony na początku przeciągania i przywrócony do niezakotwiczenia po uwolnieniu przeciągania. |
Physical | Przyczepiony obiekt będzie domyślnie zachowywał się w sposób geometryczny , ponieważ nie jest wpływany przez siły. | Niezakotwiczone obiekt zostanie przeniesiony przez siły ograniczeń, które próbują przesunąć go do pożądanego położenia i/lub orientacji określonej przez proponowany ruch. |
Custom | Obiekt nie będzie się w wszystkoporuszał, ale DragFrame nadal zostanie zaktualizowany, a ty możesz odpowiedzieć na manipulację przeciągania tak, jak chcesz. | (taki sam jak zakotwiczone) |
Ograniczenia osi i ruchu
Domyślnie nie ma ograniczeń dotyczących ruchu 3D poza wewnętrznymi ograniczeniami DragStyle.Jeśli to konieczne, możesz zastosować minimalne i maksymalne limity zarówno do tłumaczenia, jak i rotacji.Zauważ jednak, że nie są to ograniczenia , ponieważ jedynie utrudniają próby wykrycia ruchu przez detektor, aby pozostać w granicach.
Właściwości | Opis | Domyślny |
---|---|---|
Class.DragDetector.MinDragTranslation|MinDragTranslation``Class.DragDetector.MaxDragTranslation|MaxDragTranslation | Ograniczenia przeciągania tłumaczenia w każdym wymiarze. Jeśli MaxDragTranslation jest większy niż MinDragTranslation, tłumaczenie zostanie ograniczone w tym zakresie. | (0, 0, 0) |
Class.DragDetector.MinDragAngle|MinDragAngle``Class.DragDetector.MaxDragAngle|MaxDragAngle | Tylko istotne, jeśli DragStyle jest ustawione na RotateAxis .Jeśli MaxDragAngle jest większy niż MinDragAngle, rotacja zostanie ograniczona w tym zakresie. | 0 |
Przeciągnij uprawnienia
Można określić uprawnienie graczy do interakcji z daną instancją detektora przeciągnięć za pomocą właściwości PermissionPolicy.Domyślnie jest ustawiony na Enum.DragDetectorPermissionPolicy.Everybody, a można go również zmienić, aby wspierać kontrolki uprawnień skryptowanych, jak pokazano w przykładzie kodu.
Ustawienie | Opis |
---|---|
Nobody | Żaden gracz nie może wchodzić w interakcję z DragDetector. |
Everybody | Wszyscy gracze mogą wchodzić w interakcję z DragDetector. |
Scriptable | Prawa przeciągania graczy zostaną określone przez funkcję zarejestrowaną za pośrednictwem SetPermissionPolicyFunction().W tym ustawienieniepowodzenie rejestracji funkcji lub powrót nieprawidłowego wyniku uniemożliwi wszystkim graczom przeciąganie. |
Detektor przeciągania - Zapisane uprawnienie 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)
Odpowiedź fizyczna
Załóż, że styl odpowiedzi draggera jest ustawiony na Fizyczny i zostanie on zastosowany do niezakotwiczonego obiektu, który zostanie przesunięty przez siły ograniczenia, które próbują przynieść go do pozycji/orientacji określonej przez proponowany ruch.Możesz dalej dostosować odpowiedź fizyczną za pomocą następujących właściwości:
Właściwość | Opis | Domyślny |
---|---|---|
ApplyAtCenterOfMass | Gdy fałsz, siła przeciągnięcia jest stosowana w punkcie, na który kliknął użytkownik. Gdy prawda, siła jest stosowana w centrum masy obiektu. | fałsz |
MaxForce | Maksymalna siła zastosowana do osiągnięcia celu przez obiekt. | 10000000 |
MaxTorque | Maksymalny moment obrotowy zastosowany do osiągnięcia celu przez obiekt. | 10000 |
Responsiveness | Wyższe wartości powodują, że obiekt szybciej osiąga swój cel. | 10 |
Edytor wejścia
Niektóre tryby DragStyle pozwalają użytkownikom przytrzymać klawisz modyfikatora w celu manipulowania przeciąganym obiektem w różny sposób.Domyślnie modyfikator jest LeftControl na komputerze, ButtonR1 na gamepadzie lub ButtonL2 na VR.Możesz dostosować te modyfikatory za pomocą KeyboardModeSwitchKeyCode , GamepadModeSwitchKeyCode lub VRSwitchKeyCode właściwości instancji wykrywacza instancja.
Replikacja
Gdy właściwość RunLocally jest fałszywa (domyślnie), klient interpretuje całe wejście, aby wyprodukować dane, które wysyła na serwer, aby wykonać przeciągnięcie.W tym trybie wszystkie niestandardowe sygnały zdarzeń i zarejestrowane funkcje muszą być na serwerze Scripts.
Gdy właściwość RunLocally jest prawda, żadne zdarzenia nie są replikowane na serwerze.Wszystkie niestandardowe sygnały zdarzeń i zarejestrowane funkcje muszą być w klientzie LocalScripts i musisz używać zdarzeń zdalnych do rozprzestrzeniania niezbędnych zmian na serwerze.
Odpowiedzi skryptu na klikanie i przeciąganie
Poprzez sygnały wydarzeń , zmiany właściwości, styl przeciągania i niestandardowe funkcje skrypty mogą odpowiedzieć na manipulację przeciąganymi obiektami, aby sterować interfejsem użytkownika lub podejmować logiczne decyzje, takie jak dostosowywanie poziomu oświetlenia w pokoju w oparciu o przełącznik ściany przesuwnej.
Znaki zdarzeń
Poprzez następujące sygnały zdarzeń możesz wykryć, kiedy użytkownik zaczyna, kontynuuje i kończy przeciąganie obiektu.
Wydarzenie | Opis |
---|---|
DragStart | Wystrzeliwuje, gdy użytkownik zaczyna przeciągać obiekt. |
DragContinue | Wystrzeliwuje, gdy użytkownik nadal przeciąga obiekt po tym, jak DragStart został uruchomiony. |
DragEnd | Wystrzeliwuje, 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)
Przesuwanie zmian ramy
Oprócz sygnałów zdarzeń możesz monitorować zmiany w detektorze bezpośrednio.
Detektor przeciągnięć - zmiany ramy przeciągnięć
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 na Skryptowalny , możesz dostarczyć własną funkcję, która przyjmuje Ray i zwraca przestrzeń świata CFrame.Detektor przesunie ruch, aby przeciągnięty obiekt poszedł do tej niestandardowej lokalizacji/orientacji.
Detektor przeciągania - Skryptowany styl przeciągania
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)
-- Wyłącz przeciągnięty obiekt z wykrywania promieni
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 ograniczenia niestandardowego
Detektory przeciągania nie mają wbudowanych zasad ruchu o siatkach i przesuwaniu, ale możesz zarejestrować niestandardowe funkcje ograniczeń, aby edytować detektor przed jego zastosowaniem DragFrame.Na przykład możesz utrzymać ruch na siatce, zaokrągliwszy pozycje do wielokrotności zwiększenia siatki, lub symulować grę szachową z zasadami ruchu legalnymi dla każdej części.
DragDetector - Funkcja ograniczenia niestandardowego
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()
Przykładowe użycie
Niezakotwiczone fizyczne obiekty
Podstawową implementacją wykrywaczy przeciążeń jest gra równoważenia wieży, w której gracze muszą ostrożnie usuwać kawałki i próbować utrzymać wieżę w pionie.W następującej strukturze wieży każda część ma dziecko DragDetector z domyślnym DragStyle z TranslatePlane , tak że gracze mogą wyciągać części na zewnątrz, ale nie w górę lub w dół.
Modelowanie zakotwiczone z regulowanymi częściami
Możesz łatwo tworzyć i dzielić modele, które są głównie zakotwiczone, ale które mają jedną lub więcej części/modeli dziecięcych, które gracze mogą przeciągnąć.Na przykład poniższy stół ma dwa szuflady, które gracze mogą otworzyć, aby sprawdzić, co jest w środku.
Przesuwanie wykrywaczy i ograniczeń
Możesz łączyć wykrywacze przeciągów z Constraints , na przykład z lalką marionetką.W następnym ustawieniu sterowane uchwyty są zakotwiczone, części ciała nie są zakotwiczone, a ograniczenia utrzymują marionetkę razem.Przesuwanie uchwytów za pomocą TranslateViewPlane DragStyle powoduje, że marionetka tańczy, a poszczególne części ciała mogą być również przesuwane za pomocą detektorów przeciągnięć, wszystko podczas zachowania integralności modelu.
Interfejsy użytkownika 3D
Interfejsy użytkownika 3D są łatwe do osiągnięcia za pomocą wykrywaczy przeciągnięć, takich jak dostosowanie jasności SpotLight w oparciu o przesuwany przełącznik wyłącznik.Możesz również wykryć osobno osie X i Z , aby kontrolować dwa różne aspekty interfejsu użytkownika 3D, takie jak Size, Speed i Color z ParticleEmitter.
Detektor przeciągnięć - 3D interfejs użytkownika
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 prędkość cząstek na podstawie czynnika wykrywacza przeciągów 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)
-- Dostosuj kolor cząstek w oparciu o czynnik wykrywania przeciągów 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)