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

  1. W oknie Eksploratora przewiń nad Part, MeshPart lub Model i kliknij przycisk ⊕. Wyświetla się menu kontekstowe.

  2. Z menu wstawь Detektor przeciągnięć .

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

UstawienieOpis
TranslateLine1D ruch wzdłuż osi detektora Axis, domyślnie osi świata Y .
TranslatePlane2D ruch w płanie równoległym do detektora Axis , domyślnie świat XZ planu.
TranslatePlaneOrLine2D ruch w płanie równoległym do detektora Axis i, gdy aktywny jest modyfikator , 1D ruch wzdłuż detektora Axis.
TranslateLineOrPlane1D ruch wzdłuż detektora Axis i, gdy aktywny jest modyfikator , 2D ruch w płanie równoległym do detektora Axis.
TranslateViewPlane2D 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.
RotateAxisRotacja wokół detektora Axis , domyślnie osi świata Y .
RotateTrackballRotacja 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.
ScriptableOblicza 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śćOpisDomyślny
ReferenceInstanceInstancja, 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
OrientationOkreś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)
AxisGłó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.

UstawienieZakotwiczone zachowanieNiezakotwiczone zachowanie
GeometricZaró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.
PhysicalPrzyczepiony 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.
CustomObiekt 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ściOpisDomyślny
Class.DragDetector.MinDragTranslation|MinDragTranslation``Class.DragDetector.MaxDragTranslation|MaxDragTranslationOgraniczenia 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|MaxDragAngleTylko 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.

UstawienieOpis
NobodyŻaden gracz nie może wchodzić w interakcję z DragDetector.
EverybodyWszyscy gracze mogą wchodzić w interakcję z DragDetector.
ScriptablePrawa 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śćOpisDomyślny
ApplyAtCenterOfMassGdy 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
MaxForceMaksymalna siła zastosowana do osiągnięcia celu przez obiekt.10000000
MaxTorqueMaksymalny moment obrotowy zastosowany do osiągnięcia celu przez obiekt.10000
ResponsivenessWyż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.

WydarzenieOpis
DragStartWystrzeliwuje, gdy użytkownik zaczyna przeciągać obiekt.
DragContinueWystrzeliwuje, gdy użytkownik nadal przeciąga obiekt po tym, jak DragStart został uruchomiony.
DragEndWystrzeliwuje, 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)