Wykrywacze 3D Drag

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

  1. W oknie Explorer, przesuń się nad Class.Part , 2> Class.MeshPart2> lub 5> Class.Model5> i kliknij przycisk ⊕. Wyświetlony zostanie menu kontekstowe.

  2. Z menu, wklej DragDetector .

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

UstawieniaOpis
TranslateLine1D ruch wzdłuż osi Axis , domyślnie światowa osi Y .
TranslatePlane2D ruch w samolocie perpendicular do detektora Axis , domyślnie świat XZ samolotu.
TranslatePlaneOrLine2D ruch w samolocie perpendicular do detektora Axis i, gdy modyfikator jest aktywny, 1D ruch wzdłuż Class.DragDetector.Axis|Axis detektora.
TranslateLineOrPlane1D ruch wzdłuż osi Axis i, gdy modyfikator jest aktywny, 2D ruch w samolocie wzdłuż osi Class.DragDetector.Axis|Axis .
TranslateViewPlane2D 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.
RotateAxisRotacja wokół Axis detektora, domyślnie światowa osi Y .
RotateTrackballRotacja 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.
ScriptableOblicza 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śćOpisDomyślny
ReferenceInstanceInstancja, 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 zanil
OrientationOkreś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)
AxisGłó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.

UstawieniaZakorzenione zachowanieZachowanie bez przyвяzania
GeometricZaró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.
PhysicalZakotwiczone 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ą.
CustomObiekt 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ściOpisDomyślny
Class.DragDetector.MinDragTranslation|MinDragTranslation``Class.DragDetector.MaxDragTranslation|MaxDragTranslationOgraniczenia 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|MaxDragAngleTylko 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.

UstawieniaOpis
NobodyŻadni gracze nie mogą interagować z DragDetector .
EverybodyWszyscy gracze mogą wchodzić w interakcję z DragDetector.
ScriptableZezwolenia 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śćOpisDomyślny
ApplyAtCenterOfMassGdy fałszywy, przytrzymuje siłę na punkt, na którym użytkownik kliknie. Gdy prawdziwy, siła jest stosowana w centrum masy obiektu.fałszywy
MaxForceMaksymalna siła zastosowana, aby osiągnąć cel obiektu.10000000
MaxTorqueMaksymalny moment obrotowy zastosowany dla obiektu, aby osiągnąć jego cel.10000
ResponsivenessWyż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.

WydarzenieOpis
DragStartWystąpi, gdy użytkownik zacznie przeciągać obiekt.
DragContinueWyst?puje, gdy u?ytywaczka przedmiotu nadal przeciąga po nim po DragStart została uruchomiona.
DragEndWystą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)