L'istanza DragDetector facilita e incoraggia l'interazione con oggetti 3D in un'esperienza, come l'apertura di porte e cassetti, lo scivolamento di una parte intorno, la presa e il lancio di una palla da bowling, il ritiro e il fuoco di una slingshot e molto altro ancora.Le caratteristiche principali includono:
Posiziona un sotto qualsiasi o per rendere trascorribile via tutti gli input (Topo, or mouse as computer mouse, touch, gamepad e VR), tutti senza una singola linea di codice.
Scegli tra diversi stili di trascinamento, definisci come l'oggetto risponde alla mossa e applica opzionalmente limiti asse o movimento .
Gli script possono rispondere alla manipolazione di oggetti trascinati per guidare l'interfaccia utente o prendere decisioni logiche, come regolare il livello di luce in una stanza in base a un dimmer di parete scorrevole.
I giocatori possono manipolare parti o modelli ancorati e rimarranno esattamente dove li hai messi al rilascio.
DragDetectors lavorare in Studio finché non sei non utilizzando gli strumenti Seleziona , Sposta , Scala o Ruota , rendendo più facile testare e regolare gli oggetti trascorribili durante l'edizione.
Rendi gli oggetti trascorribili
Per rendere qualsiasi parte o modello trascorribile, aggiungi semplicemente un DragDetector come DIscendentediretto.
Dal menu, inserisci un DragDetector .
Per impostazione predefinita, l'oggetto ora sarà trascinabile nel piano di superficie, ma puoi personalizzare il suo , definire come risponde alla mossa e applicare opzionalmente limiti dell'asse o del movimento .
Personalizza i rilevatori di trascinamento
Trascina lo stile
DragDetectors mappa la movimento del cursore alla linee virtuali e ai piani per calcolare la moto 3D proposta.Attraverso la ProprietàDragStyle puoi scegliere tra diverse mappe per soddisfare le tue esigenze.Ad esempio, TranslatePlane produce traduzione in un piano virtuale, mentre RotateAxis produce rotazione attorno a un asse virtuale.
Impostazione | Descrizione |
---|---|
TranslateLine | 1D movimento lungo l'asse del rilevatore Axis, per impostazione predefinita l'asse del mondo Y . |
TranslatePlane | 2D movimento nell'aereo perpendicolare al piano del rilevatore di Axis , per impostazione predefinita l'aereo del mondo XZ . |
TranslatePlaneOrLine | 2D movimento nell'aereo perpendicolare al sensore di e, quando il modificatore è attivo, 1D movimento lungo il sensore di . |
TranslateLineOrPlane | 1D movimento lungo il sensore di e, quando il modificatore è attivo, movimento 2D nel piano perpendicolare al sensore di . |
TranslateViewPlane | 2D movimento nel piano perpendicolare alla vista della Telecamera.In questa modalità, l'aereo viene costantemente aggiornato, anche durante il trascinamento, e affronterà sempre la vista attuale della Telecamera. |
RotateAxis | Rotazione attorno all'asse del rilevatore di Axis, per impostazione predefinita l'asse del mondo Y . |
RotateTrackball | Rotazione del trackball, ulteriormente personalizzata attraverso le proprietà TrackballRadialPullFactor e TrackballRollFactor. |
BestForDevice | TranslatePlaneOrLine per mouse e gamepad; TranslatePlane per il tocco; 6DOF per VR. |
Scriptable | Calcola la rotazione desiderata attraverso una funzione personalizzata fornita attraverso SetDragStyleFunction() . |
Trascina la direzione
Per impostazione predefinita, la mappa di movimento 3D e l'associazione DragStyle con lo Spaziomondiale.Tuttavia, potresti voler cambiare il , , o , ad esempio quando costruisci drag detector in modelli con parti regolabili .
Proprietà | Descrizione | Basilare |
---|---|---|
ReferenceInstance | Un'istanza il cui punto focale fornisce il quadro di riferimento per il rilevatore di trascinamento.Il DragFrame è espresso rispetto a questo quadro di riferimento che può essere recuperato tramite GetReferenceFrame() .Se il quadro di riferimento è nil , la traduzione sarà nella direzione di (o nel piano perpendicolare a) la proprietà Axis in Spaziomondiale. | nil |
Orientation | Specifica la rotazione YXZ degli assi di movimento relativi al frame di riferimento (non cambia l'orientamento del frame di riferimento stesso).La traduzione lineare e la rotazione assiale saranno su questo asse riorientato Y , e la traduzione planare nell'asse XZ .Cambiare questo valore aggiorna automaticamente Axis e viceversa. | (0, 0, 0) |
Axis | L'asse primario di movimento, espresso rispetto al frame di riferimento. Cambiare questo valore aggiorna automaticamente Orientation e viceversa. | (0, 1, 0) |
Risposta alla mozione
La proprietà ResponseStyle specifica come un oggetto risponde alla proposta moto, a seconda se l'oggetto è Anchored o no.
Impostazione | Comportamento ancorato | Comportamento non ancorato |
---|---|---|
Geometric | Sia all'interno dell'esperienza in esecuzione che in modalità di modifica in Studio, la posizione/orientamento di un oggetto ancorato verrà aggiornata per riflettere esattamente la mossa proposta. | Per un oggetto non ancorato, il comportamento è lo stesso di quello di un oggetto ancorato.Tuttavia, in un'esperienza in esecuzione, l'oggetto verrà ancorato all'inizio del trascinamento e ripristinato non ancorato dopo il rilascio del trascinamento. |
Physical | Un oggetto ancorato passerà al comportamento Geometrico , poiché non è influenzato dalle forze. | Un oggetto non ancorato verrà spostato da forze di restrizione che tentano di portarlo alla posizione e/o all'orientamento desiderati forniti dalla proposta di moto. |
Custom | L'oggetto non si muoverà tutti/tutte, ma DragFrame verrà comunque aggiornato e puoi rispondere alla manipolazione di trascinamento come vuoi. | (idem come ancorato) |
Limiti di asse e movimento
Per impostazione predefinita, non ci sono limiti alla moto 3D al di là delle restrizioni intrinseche del DragStyle .Se necessario, puoi applicare limiti minimi e massimi sia alla traduzione che alla rotazione.Nota, tuttavia, che questi non sono vincoli ; impediscono semplicemente ai tentativi del rilevatore di movimento di generare movimento per rimanere entro i limiti.
Proprietà | Descrizione | Basilare |
---|---|---|
Class.DragDetector.MinDragTranslation|MinDragTranslation``Class.DragDetector.MaxDragTranslation|MaxDragTranslation | Limitazioni alla trascinamento della traduzione in ogni dimensione. Se MaxDragTranslation è maggiore di MinDragTranslation, la traduzione verrà limitata all'interno di tale intervallo. | (0, 0, 0) |
Class.DragDetector.MinDragAngle|MinDragAngle``Class.DragDetector.MaxDragAngle|MaxDragAngle | Rilevante solo se DragStyle è impostato su RotateAxis .Se MaxDragAngle è maggiore di MinDragAngle , la rotazione verrà limitata all'interno di tale intervallo. | 0 |
Trascina le autorizzazioni
Il permesso ai giocatori di interagire con una determinata istanza di rilevamento del trascinamento può essere specificato dalla ProprietàPermissionPolicy.Questo è impostato su Enum.DragDetectorPermissionPolicy.Everybody per impostazione predefinita e può essere cambiato per supportare i controlli di autorizzazione scriptati come mostrato nell'esempio di codice.
Impostazione | Descrizione |
---|---|
Nobody | Nessun giocatore può interagire con il DragDetector . |
Everybody | Tutti i giocatori possono interagire con il DragDetector . |
Scriptable | Le autorizzazioni di trascinamento dei giocatori saranno determinate da una funzione registrata attraverso SetPermissionPolicyFunction().Con questa Configurazione, il mancato registro di una funzione o il ritorno di un risultato non valido impedirà a tutti i giocatori di trascinare. |
DragDetector - Permesso di trascinamento scriptato
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)
Risposta fisica
Presumendo che lo stile di risposta di un trascinatore sia impostato su fisico e che venga applicato a un oggetto non ancorato, quell'oggetto verrà spostato dalle forze di restrizione che tentano di portarlo alla posizione/orientamento indicato dalla proposta di moto.Puoi personalizzare ulteriormente la risposta fisica attraverso le seguenti proprietà:
Proprietà | Descrizione | Basilare |
---|---|---|
ApplyAtCenterOfMass | Quando è falsa, viene applicata la forza di trascinamento al punto in cui l'utente fa clic. Quando è vera, la forza viene applicata al centro di massa dell'oggetto. | fallito |
MaxForce | Forza massima applicata all'oggetto per raggiungere il suo obiettivo. | 10000000 |
MaxTorque | Torque massimo applicato per l'oggetto per raggiungere il suo obiettivo. | 10000 |
Responsiveness | I valori più alti fanno sì che l'oggetto raggiunga il suo obiettivo più rapidamente. | 10 |
Input modificatore
Alcuni DragStyle permettono agli utenti di tenere premuto un modificatore tasto/pulsante per manipolare l'oggetto trascinato in modi diversi.Per impostazione predefinita, il modificatore è LeftControl su PC, ButtonR1 su gamepad o ButtonL2 su VR.Puoi personalizzare questi modificatori attraverso le proprietà KeyboardModeSwitchKeyCode, GamepadModeSwitchKeyCode o VRSwitchKeyCode della istanza del rilevatore di trascinamento.
Replicazione
Quando la proprietà RunLocally è falsa (predefinita), il client interpreta tutti gli input per produrre dati che invia al server per eseguire il trascinamento.In questo modo, tutti i segnali di evento personalizzati e le funzioni registrate devono essere nel server Scripts .
Quando la proprietà RunLocally è vera, non vengono replicati eventi al Server.Tutti i segnali di evento personalizzati e le funzioni registrate devono essere nel client LocalScripts e devi usare eventi remoti per propagare i cambiamenti necessari al Server.
Risposte dello script al clic e al trascinamento
Attraverso segnali di evento , modifiche di proprietà, Scriptable stile di trascinamento e funzioni personalizzate, gli script possono rispondere alla manipolazione di oggetti trascinati per guidare l'interfaccia utente o prendere decisioni logiche, come regolare il livello di luce in una stanza in base a un interruttore di parete scorrevole dimmer.
Segnali di evento
Attraverso i seguenti segnali di evento, puoi rilevare quando un utente inizia, continua e termina trascinando un oggetto.
Evento | Descrizione |
---|---|
DragStart | Si attiva quando un utente inizia a trascinare l'oggetto. |
DragContinue | Si accende quando un utente continua a trascinare l'oggetto dopo che DragStart è stato inizializzato. |
DragEnd | Si attiva quando un utente smette di trascinare l'oggetto. |
DragDetector - Segnali evento
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)
Trascina le modifiche della cornice
Oltre ai segnali di evento , puoi monitorare le modifiche al rilevatore di direttamente.
DragDetector - Cambiamenti del DragFrame
local dragDetector = script.Parent.DragDetector
dragDetector:GetPropertyChangedSignal("DragFrame"):Connect(function()
local currentDragTranslation = dragDetector.DragFrame.Position
print(currentDragTranslation)
end)
Stile di trascinamento scriptato
Se impostate il DragStyle di un rilevatore su Scriptabile , potete fornire la vostra funzione che prende in un Ray e restituisce uno spazio mondiale CFrame .Il rilevatore sposterà la mossa in modo che l'oggetto trascinato vada a quella posizione/orientamento personalizzato.
DragDetector - Stile di trascinamento scriptato
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)
-- Escludi l'oggetto trascinato dalla rilevazione del 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)
Funzione di vincolo personalizzata
I rilevatori di trascinamento non hanno regole di movimento integrate sulle griglie e lo snap, ma puoi registrare funzioni di vincolo personalizzate per modificare il rilevatore di DragFrame prima che venga applicato.Ad esempio, puoi mantenere la velocità su una griglia arrotondando le posizioni a multipli dell'incremento della griglia, o simulare una partita di scacchi con regole di movimento legali per ciascuna pezza.
DragDetector - Funzione di restrizione personalizzata
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()
Esempio di utilizzo
Oggetti fisici non ancorati
Una implementazione di base dei rilevatori di trascinamento è un gioco di equilibrio della torre in cui i giocatori devono rimuovere attentamente le parti e tentare di mantenere la torre in piedi.Nella seguente struttura della torre, ogni pezzo ha un figlio DragDetector con un predefinito DragStyle di TranslatePlane in modo che i giocatori possano estrarre i pezzi verso l'esterno ma non verso l'alto o verso il basso.
Modelli ancorati con parti regolabili
Puoi facilmente creare e condividere modelli che sono principalmente ancorati, ma che hanno una o più parti/modelli figli che i giocatori possono trascinare.Ad esempio, il seguente scrivania ha due cassetti che i giocatori possono aprire per ispezionare ciò che c'è dentro.
Trascina rilevatori e vincoli
Puoi combinare i rilevatori di trascinamento con Constraints , ad esempio una marionetta puppet.Nella seguente configurazione, le maniglie di controllo sono ancorate, le parti del corpo non sono ancorate e le restrizioni tengono la marionetta insieme.Spostare le maniglie con il TranslateViewPlane rende la marionetta in danza, e le singole parti del corpo possono anche essere spostate con i rilevatori di trascinamento, tutto mentre il modello mantiene la sua integrità.
Interfacce utente 3D
Le interfacce utente 3D sono facilmente ottenibili attraverso i rilevatori di trascinamento, come l'aggiustamento della luminosità di un SpotLight basato su un dimmer a scorrimento.Puoi anche rilevare individualmente gli assi X e Z per controllare due diversi aspetti di un'interfaccia utente 3D, come Size, Speed e Color di un ParticleEmitter.
DragDetector - Interfaccia utente 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
-- Aggiusta la dimensione e la velocità delle particelle in base al fattore X del rilevatore di trascinamento
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)
-- Aggiusta il colore delle particelle in base al fattore Z del rilevatore di trascinamento
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)