Attention: Here be dragons
This is the latest
(unstable) version of this documentation, which may document features
not available in or compatible with released stable versions of Godot.
Checking the stable version of the documentation...
La mappa di azioni XR
Godot has an action map feature as part of the XR system. At this point in time this system is part of the OpenXR module. There are plans to encompass WebXR into this in the near future hence we call it the XR action map system in this document. It implements the built-in action map system of OpenXR mostly exactly as it is offered.
The XR action map system exposes input, positional data and output for XR controllers to your game/application. It does this by exposing named actions that can be tailored to your game/application and binding these to the actual inputs and outputs on your XR devices.
As the XR action map is currently part of the OpenXR module, OpenXR needs to be enabled in your project settings to expose it:
You will then find the XR Action Map interface in the bottom of the screen:
Nota
Il sistema di input integrato di Godot ha molte cose in comune con il sistema di mappe di azione XR. In effetti, la nostra idea iniziale era quella di aggiungere funzionalità al sistema di input esistente ed esporre i dati al sistema di mappe di azione OpenXR. Potremmo riconsiderare l'idea in futuro, ma a quanto pare c'erano troppi problemi da superare. Per citarne alcuni:
Godot's input system mainly centers around button inputs, XR adds triggers, axis, poses and haptics (output) into the mix. This would greatly complicate the input system with features that won't work for normal controllers or contrast with the current approach. It was felt this would lead to confusion for the majority of Godot users.
Il sistema di input in Godot funziona con dati grezzi di input che vengono analizzati e attivano azioni corrispondenti. Questi dati di input diventano disponibili all'utente finale. OpenXR, invece, nasconde completamente i dati grezzi ed effettua l'analisi al posto nostro, consentendoci di accedere solo ai dati già analizzati delle azioni. Questa incoerenza potrebbe causare bug quando un utente ignaro tenta di utilizzare un dispositivo XR come un solito dispositivo di input.
Il sistema di input in Godot consente di modificare in fase di esecuzione quali input sono associati alle azioni, OpenXR no.
Il sistema di input in Godot si basa su ID di dispositivi che non hanno alcun significato in OpenXR.
Questo significa che un gioco/applicazione che combina input tradizionali e controller XR avrà una separazione. Nella maggior parte delle applicazioni si utilizza o l'uno o l'altro e questo non è considerato un problema. Alla fin fine, è una limitazione del sistema.
La mappa di azioni predefinita
Godot creerà automaticamente una mappa di azioni predefinita se nessun file di mappa di azioni viene trovato.
Avvertimento
Questa mappa predefinita è stata progettata per aiutare gli sviluppatori a convertire i loro giochi/applicazioni XR da Godot 3 a Godot 4. Pertanto, questa mappatura associa essenzialmente tutti gli input noti su tutti i controller supportati predefiniti alle azioni corrispondenti. Questo non è un buon esempio per configurare una mappa di azioni. Però permette a un nuovo sviluppatore di avere un punto di partenza per familiarizzarsi con Godot XR. Evita di dover prima progettare una mappa di azioni specifica per il proprio gioco/applicazione.
For this walkthrough we're going to start with a blank action map. You can delete the "Godot action set" entry at the top by pressing the trash can icon. This will clear out all actions. You might also want to remove the controllers that you do not wish to setup, more on this later.
Insiemi di azioni
Nota
Prima di continuare, in questo documento sarà utilizzato il termine "runtime XR". Con "runtime XR" intendiamo il software che controlla e interagisce con il visore AR o VR. Il runtime XR ci fornisce poi queste informazioni tramite un'API come OpenXR. Pertanto:
Per Steam questo è Steam VR,
per Meta su desktop questo è il client Oculus (anche quando si utilizza Quest link),
per Meta su Quest questo è il client OpenXR nativo di Quest,
su Linux potrebbe essere Monado, ecc.
La mappa delle azioni ci permette di organizzare le nostre azioni in insiemi. Ogni insieme può essere abilitato o disabilitato singolarmente.
Il concetto qui è che si potrebbero avere diversi insiemi che forniscono associazioni in scenari diversi. Si potrebbe avere:
un insieme
Character controlper quando si cammina,un insieme
Vehicle controlper quando si guida un veicolo,un insieme
Menuquando un menu è aperto.
Sarà quindi possibile abilitare solo l'insieme di azioni applicabile allo stato attuale del gioco/applicazione.
Questo è particolarmente importante se si desidera associare lo stesso input su un controller a un'azione diversa. Ad esempio:
nell'insieme
Character controlsi potrebbe avere un'azioneJump,nell'insieme
Vehicle controlsi potrebbe avere un'azioneAccelerate,nell'insieme
Menusi potrebbe avere un'azioneSelect.
Sono tutti associati al grilletto del controller.
OpenXR associa solo un input o un output a una singola azione. Se lo stesso input o output è associato a più azioni, verrà aggiornato/utilizzato quello presente nell'insieme di azioni attivo con la priorità più alta. Pertanto, nell'esempio precedente, è importante che un solo insieme di azioni sia attivo.
Per il tuo primo gioco/applicazione XR, consigliamo vivamente di cominciare con un solo insieme di azioni e di non complicare troppo le cose.
Per la nostra procedura dettagliata in questo documento, creeremo quindi un singolo insieme di azioni chiamato my_first_action_set. Lo faremo premendo il pulsante :
Le colonne della nostra tabella sono le seguenti:
Colonna |
Valore |
Descrizione |
|---|---|---|
1 |
my_first_action_set |
Questo è il nome interno dell'insieme di azioni. OpenXR non specifica restrizioni particolari su questo nome, oltre alla dimensione, sebbene alcuni runtime XR potrebbero non gradire spazi o caratteri speciali. |
2 |
My first action set |
Questo è un nome leggibile per l'insieme di azioni. Alcuni runtime XR mostreranno questo nome all'utente finale, ad esempio nelle finestre di dialogo di configurazione. |
3 |
0 |
Questa è la priorità dell'insieme di azioni. Se più insiemi attivi di azioni hanno azioni associate agli stessi input o output del controller, l'insieme di azioni con il valore più alto di priorità determinerà l'azione che verrà aggiornata. |
Azioni
Nella mappa di azioni XR, le azioni sono le entità con cui il tuo gioco/applicazione interagirà. Ad esempio, possiamo definire un'azione Shoot e l'input associato a tale azione attiverà il segnale button_pressed sul nodo XRController3D corrispondente nella scena, con Shoot come parametro name del segnale.
È anche possibile interrogare lo stato attuale di un'azione. XRController3D ad esempio ha un metodo is_button_pressed.
Le azioni possono servire sia per l'input sia per l'output e ogni azione ha un tipo che ne definisce il comportamento.
Il tipo
Boolserve per input discreti come i pulsanti.Il tipo
Floatserve per input analogici come le levette.
Questi due sono speciali perché sono gli unici intercambiabili. OpenXR gestirà le conversioni tra input e azioni di tipo Bool e Float. È possibile ottenere il valore di un'azione di tipo Float chiamando il metodo get_float sul nodo XRController3D. Questo emette il segnale input_float_changed quando il valore cambia.
Nota
Quando gli input analogici vengono interrogati come pulsanti, viene applicata una soglia. Attualmente, questa soglia è gestita esclusivamente dal runtime XR. Ci sono piani per estendere Godot per fornire un certo livello di controllo su queste soglie in futuro.
Il tipo Vector2 definisce l'input come un input ad asse. Touchpad, levette analogiche e input simili sono esposti come vettori. È possibile ottenere il valore di un'azione di tipo Vector2 chiamando il metodo get_vector2 sul nodo XRController3D. Questo emette il segnale input_vector2_changed quando il valore cambia.
Il tipo Pose definisce un input tracciato spazialmente. In OpenXR sono disponibili diversi input "pose": aim, grip e palm. Il nodo XRController3D è posizionato automaticamente in base all'azione di posa assegnata alla proprietà pose di questo nodo. Maggiori informazioni sulle pose in seguito.
Nota
L'implementazione di OpenXR in Godot espone anche una posa speciale chiamata Skeleton. Questa fa parte dell'implementazione del tracciamento delle mani. Tale posa è accessibile tramite l'azione skeleton, supportata fuori dal sistema di mappe di azioni. È quindi sempre presente se il tracciamento delle mani è supportato. Non è necessario associare azioni a questa posa per utilizzarla.
Infine, l'unico tipo di output è Haptic e ci permette di impostare l'intensità del feedback aptico, come la vibrazione dei controller. I controller possono avere più output aptici e anche il supporto per i giubbotti aptici arriverà in OpenXR.
So lets add an action for our aim pose, we do this by clicking on the + button for
our action set:
Le colonne della nostra tabella sono le seguenti:
Colonna |
Valore |
Descrizione |
|---|---|---|
1 |
aim_pose |
Questo è il nome interno dell'azione. OpenXR non specifica restrizioni particolari su questo nome, a parte la lunghezza; tuttavia, alcuni runtime XR potrebbero non accettare spazi o caratteri speciali. |
2 |
Aim pose |
Questo è un nome leggibile in chiaro per l'azione. Alcuni runtime XR mostreranno questo nome all'utente finale, ad esempio nelle finestre di configurazione. |
3 |
Posa |
Il tipo di questa azione. |
OpenXR defines a number of bindable input poses that are commonly available for controllers. There are no rules for which poses are supported for different controllers. The poses OpenXR currently defines are:
The aim pose on most controllers is positioned slightly in front of the controller and aims forward. This is a great pose to use for laser pointers or to align the muzzle of a weapon with.
The grip pose on most controllers is positioned where the grip button is placed on the controller. The orientation of this pose differs between controllers and can differ for the same controller on different XR runtimes.
The palm pose on most controllers is positioned in the center of the palm of the hand holding the controller. This is a new pose that is not available on all XR runtimes.
Nota
If hand tracking is used, there are currently big differences in implementations between the different XR runtimes. As a result the action map is currently not suitable for hand tracking. Work is being done on this so stay tuned.
Completiamo il nostro elenco di azioni per un gioco/applicazione di tiro molto semplice:
Le azioni che abbiamo aggiunto sono:
movement, che consente all'utente di muoversi fuori dal normale tracciamento delle dimensioni della stanza.
grab, che rileva quando l'utente vuole impugnare qualcosa.
shoot, che rileva che l'utente vuole sparare con l'arma che impugna.
haptic, che ci consente di trasmettere un feedback tattile.
Now note that we don't distinguish between the left and right hand. This is something that is determined at the next stage. We've implemented the action system in such a way that you can bind the same action to both hands. The appropriate XRController3D node will emit the signal.
Avvertimento
Sia per afferrare sia per sparare abbiamo utilizzato il tipo Bool. Come accennato prima, OpenXR effettua conversioni automatiche dai controlli analogici, tuttavia non tutti i runtime XR attualmente applicano soglie sensate.
Consigliamo come alternativa di utilizzare il tipo Float quando si interagisce con i grilletti e i pulsanti di presa e di applicare una propria soglia.
Per pulsanti come A/B/X/Y e simili in cui non è disponibile un'opzione analogica, il tipo Bool funziona bene.
Nota
È possibile associare la stessa azione a più input per lo stesso controller sullo stesso profilo. In questo caso, il runtime XR tenterà di combinare gli input.
Per gli input
Bool, sarà effettuata un'operazioneORtra i pulsanti.Per gli input
Float, sarà preso il valore più alto tra gli input vincolati.Il comportamento per gli input
Posenon è definito, ma è probabile che sia utilizzato il primo input associato.
Non dovresti associare più azioni dello stesso insieme di azioni allo stesso input del controller. Se lo fai, o se le azioni sono associate a più insiemi di azioni ma hanno priorità sovrapposte, il comportamento non è definito. Il runtime XR potrebbe non accettare la tua mappa di azioni, oppure potrebbe accettarla secondo il principio "chi primo arriva meglio alloggia".
Stiamo ancora valutando le restrizioni relative all'associazione di più azioni allo stesso output, poiché questo scenario ha senso. La specifica OpenXR sembra non consentirlo.
Ora che abbiamo definito le nostre azioni di base, è il momento di collegarle.
Profili
In OpenXR controller bindings are captured in so-called "Interaction Profiles". We've shortened it to "Profiles" because it takes up less space.
This generic name is chosen because controllers don't cover the entire system. Currently there are also profiles for trackers, remotes and tracked pens. There are also provisions for devices such as treadmills, haptic vests and such even though those are not part of the specification yet.
Avvertimento
It is important to know that OpenXR has strict checking on supported devices. The core specification identifies a number of controllers and similar devices with their supported inputs and outputs. Every XR runtime must accept these interaction profiles even if they aren't applicable.
I nuovi dispositivi sono aggiunti tramite estensioni e i runtime XR devono specificare quali supportano. I runtime XR che non supportano un dispositivo aggiunto tramite estensioni non accetteranno questi profili. I runtime XR che non supportano i tipi di input o output aggiunti spesso si bloccano se vengono forniti.
Pertanto, Godot conserva i metadati di tutti i dispositivi disponibili, i relativi input e output e l'estensione che ne aggiunge il supporto. È possibile creare profili di interazione per tutti i dispositivi che si desidera supportare. Godot filtrerà quelli non supportati dal runtime XR utilizzato dall'utente.
Ciò significa che, per supportare nuovi dispositivi, potrebbe essere necessario aggiornare Godot a una versione più recente.
It is however also important to note that the action map has been designed with this in mind. When new devices enter the market, or when your users use devices that you do not have access to, the action map system relies on the XR runtime. It is the XR runtime's job to choose the best fitting interaction profile that has been specified and adapt it for the controller the user is using.
Il modo in cui il runtime XR gestisce questa funzionalità è lasciato all'implementazione del runtime stesso, e pertanto esistono notevoli differenze tra i vari runtime. Alcuni runtime potrebbero persino consentire agli utenti di modificare le associazioni per conto proprio.
A common approach for a runtime is to look for a matching interaction profile first. If this is not found it will check the most common profiles such as that of the "Touch controller" and do a conversion. If all else fails, it will check the generic "Simple controller".
Nota
There is an important conclusion to be made here: When a controller is found, and the action map is applied to it, the XR runtime is not limited to the exact configurations you set up in Godot's action map editor. While the runtime will generally choose a suitable mapping based on one of the bindings you set up in the action map, it can deviate from it.
Ad esempio, quando è utilizzato il profilo del controller Touch, potrebbe accadere uno qualsiasi dei seguenti scenari:
potremmo star usando un controller Quest 1,
potremmo star usando un controller Quest 2,
potremmo star usando un controller Quest Pro ma nessun profilo Quest Pro è stato fornito oppure il runtime XR utilizzato non supporta il controller Quest Pro,
potrebbe essere un controller completamente diverso per il quale nessun profilo è stato fornito, ma il runtime XR utilizza le associazioni touch come base.
Pertanto, al momento non esiste alcun modo per sapere con certezza quale controller sta effettivamente utilizzando l'utente.
Avvertimento
Infine, e questo lascia molti perplessi, le associazioni non sono immutabili. È pienamente permesso, e persino previsto, che un runtime XR consenta all'utente di personalizzare le associazioni.
Al momento, nessuno dei runtime XR offre questa funzionalità, sebbene SteamVR abbia un'interfaccia utente derivata dal sistema di mappe d'azione di OpenVR, che è ancora accessibile. Ciò nonostante stiamo lavorando attivamente su questo aspetto.
La nostra associazione di controller
Configuriamo la nostra prima associazione di controller, usando il controller Touch come esempio.
Premi "Aggiungi profilo", trova il controller Touch e aggiungilo. Se non è presente nell'elenco, potrebbe essere già stato aggiunto.
La nostra interfaccia utente ora mostra pannelli per entrambi i controller sinistro e destro. I pannelli contengono tutti gli input e gli output possibili per ciascun controller. Possiamo premere il simbolo + accanto a ogni voce per associarla a un'azione:
Finiamo la nostra configurazione:
Ogni azione è associata all'input o all'output specificato per entrambi i controller, a indicare che l'azione è supportata da entrambi. L'unica eccezione è l'azione di movimento, associata solo al controller destro. È probabile che si desideri utilizzare lo stick analogico sinistro per uno scopo diverso, ad esempio una funzione di teletrasporto.
Nello sviluppo del gioco/applicazione devi tenere conto della possibilità che l'utente modifichi le associazioni e assegni il movimento alla levetta analogica sinistra.
Nota inoltre che le nostre azioni booleane di "sparo" e "presa" sono collegate a input di tipo Float. Come accennato prima, OpenXR effettuerà le conversioni tra i due tipi, ma leggi bene l'avvertenza fornita prima sull'argomento in questo documento.
Nota
Alcuni input sembrano comparire nel nostro elenco più volte.
Ad esempio, possiamo trovare il pulsante X due volte, una volta come X click e poi come X touch. Questo è perché il controller Touch ha un sensore capacitivo.
X touchsarà true se l'utente sta a malapena toccando il pulsante X.X clicksarà true quando l'utente sta effettivamente premendo il pulsante.
Similmente per la levetta analogica abbiamo:
Thumbstick touchche sarà true se l'utente sta toccando la levetta.Thumbstickche fornisce un valore per la direzione in cui viene spinta la levetta.Thumbstick click, che è true quando l'utente sta premendo la levetta in basso.
È importante notare che solo un numero limitato di controller XR supporta sensori touch o ha funzionalità di clic sulle levette analogiche. Tienilo a mente quando progetti il tuo gioco/applicazione. Assicurati che queste siano usate per funzionalità opzionali del tuo gioco/applicazione.
Il semplice controller
Il "Simple controller" è un controller generico che OpenXR offre come riserva. Applicheremo la nostra mappatura:
Come risulta dolorosamente chiaro, il controller generico è spesso troppo semplice e non basta per qualsiasi cosa che non sia il più semplice dei giochi/applicazioni VR.
Ecco perché molti runtime XR lo utilizzano solo come ultima risorsa e tentano di utilizzare le associazioni di uno dei sistemi più diffusi come prima riserva.
Nota
Due to the simple controller likely not covering the needs of your game, it is tempting to provide bindings for every controller supported by OpenXR. The default action map seems to suggest this as a valid course of action. As mentioned before, the default action map was designed for ease of migration from Godot 3.
It is the recommendation from the OpenXR Working Group that only bindings for controllers actually tested by the developer are setup. The XR runtimes are designed with this in mind. They can perform a better job of rebinding a provided binding than a developer can make educated guesses. Especially as the developer can't test if this leads to a comfortable experience for the end user.
This is our advice as well: limit your action map to the interaction profiles for devices you have actually tested your game with. The Oculus Touch controller is widely used as a fallback controller by many runtimes. If you are able to test your game using a Meta Rift or Quest and add this profile there is a high probability your game will work with other headsets.
Modificatori di associazioni
One of the main goals of the action map is to remove the need for the application to know the hardware used. However, sometimes the hardware has physical differences that require inputs to be altered in ways other than how they are bound to actions. This need ranges from setting thresholds, to altering the inputs available on a controller.
Binding modifiers are not enabled by default and require enabling in the OpenXR project settings. Also there is no guarantee that these modifiers are supported by every runtime. You will need to consult the support for the runtimes you are targeting and decide whether to rely on the modifiers or implement some form of fallback mechanism.
If you are targeting multiple runtimes that have support for the same controllers, you may need to create separate action maps for each runtime. You can control which action map Godot uses by using different export templates for each runtime and using a custom feature tag to set the action map.
In Godot, binding modifiers are divided into two groups: modifiers that work on the interaction profile level, and modifiers that work on individual bindings.
Modificatori di associazioni su un profilo di interazione
Binding modifiers that are applied to the whole interaction profile can be accessed through the modifier button on the right side of the interaction profile editor.
È possibile aggiungere un nuovo modificatore premendo il pulsante .
Avvertimento
Poiché Godot non sa quali controller e runtime supportano un modificatore, non ci sono restrizioni all'aggiunta di modificatori. I modificatori non supportati saranno ignorati.
Modificatore di associazione d-pad
Il modificatore di associazione d-pad aggiunge nuovi input a un profilo di interazione per ogni input del joystick e del pad direzionale di questo controller. Trasforma l'input in un d-pad con input separati su, giù, sinistra e destra che vengono esposti come pulsanti:
Nota
Gli input relativi alle estensioni sono indicati con un asterisco.
Per utilizzare il modificatore di associazione d-pad, è necessario abilitare l'estensione del modificatore di associazione d-pad nelle impostazioni del progetto:
Basta abilitare l'estensione per far funzionare questa funzionalità con le impostazioni predefinite.
Adding the modifier is optional and allows you to fine tune the way the dpad functionality behaves. You can add the modifier multiple times to set different settings for different inputs.
Queste impostazioni sono utilizzate come segue:
Action Setdefinisce l'insieme di azioni a cui sono applicate queste impostazioni.
Input Pathdefinisce l'input originale che è mappato sui nuovi input del d-pad.
Thresholdspecifica il valore di soglia che abiliterà un'azione del d-pad, ad esempio un valore di0.6significa che se la distanza dal centro supera0.6l'azione del d-pad viene premuta.
Threshold Releasedspecifica il valore di soglia che disabiliterà un'azione del d-pad, ad esempio un valore di0.4significa che se la distanza dal centro scende al di sotto di0.4l'azione del d-pad viene rilasciata.
Center Regionspecifica la distanza dal centro che abilita l'azione centrale; questa opzione è supportata solo per i trackpad.
Wedge Anglespecifies the angle of each wedge. A value of90 degreesor lower means that up, down, left and right each have a separate slice in which they are in the pressed state. A value above90 degreesmeans that the slices overlap and that multiple actions can be in the pressed state.
Is Sticky, quando abilitato, significa che un'azione rimane nello stato premuto finché la levetta analogica o il trackpad non si sposta in un altro spicchio, anche se ha lasciato lo spicchio per quell'azione.
On Hapticconsente di definire un output aptico che si attiva automaticamente quando viene premuta un'azione.
Off Hapticconsente di definire un output aptico che si attiva automaticamente quando viene rilasciata un'azione.
Binding modifiers on individual bindings
Binding modifiers that are applied to individual bindings can be accessed through the binding modifier button next to action attached to an input:
È possibile aggiungere un nuovo modificatore premendo il pulsante .
Avvertimento
As Godot doesn't know which inputs on each runtime support a modifier, there is no restriction to adding modifiers. If the modifier extension is unsupported, modifiers will be filtered out at runtime. Modifiers added to the wrong input may result in a runtime error.
You should test your action map on the actual hardware and runtime to verify the proper setup.
Modificatore di soglia analogica
Il modificatore di soglia analogica consente di specificare le soglie utilizzate per qualsiasi input analogico, come il grilletto, che ha un input booleano. Controlla quando l'input è considerato premuto.
Per utilizzare il modificatore, è necessario abilitare l'estensione della soglia analogica nelle impostazioni del progetto:
Il modificatore di soglia analogica ha le seguenti impostazioni:
Queste sono definite come segue:
On Thresholdspecifica il valore di soglia che abiliterà l'azione, ad esempio un valore di0.6significa che quando il valore analogico supera0.6, l'azione viene impostata sullo stato premuto.
Off Thresholdspecifica il valore di soglia che disabiliterà l'azione, ad esempio un valore di0.4significa che quando il valore analogico scende al di sotto0.4, l'azione viene impostata sullo stato rilasciato.
On Hapticconsente di definire un output aptico che si attiva automaticamente quando viene premuto l'input.
Off Hapticconsente di definire un output aptico che si attiva automaticamente quando viene rilasciato l'input.
Haptics on modifiers
I modificatori possono supportare un output aptico automatico che si attiva al raggiungimento di determinate soglie.
Nota
Attualmente entrambi i modificatori disponibili supportano questa funzione, tuttavia non vi è alcuna garanzia che anche i futuri modificatori ne siano capaci. È supportato un solo tipo di feedback aptico, ma in futuro potrebbero essere disponibili altre opzioni.
Haptic vibration
The haptic vibration allows us to specify a simple haptic pulse:
Ha le seguenti opzioni:
Durataè la durata dell'impulso in nanosecondi.-1consente al runtime di scegliere un valore ottimale per un impulso breve adatto all'hardware attuale.
Frequencyè la frequenza dell'impulso in Hz.0consente al runtime di scegliere una frequenza ottimale per un impulso breve adatto all'hardware attuale.
Amplitudeè l'ampiezza dell'impulso.