Puntatori - MRTK2

Puntatore

Questo articolo illustra come configurare e rispondere all'input del puntatore in pratica. Per comprendere meglio come controllare più puntatori a livello generale, vedere Architettura puntatore.

I puntatori vengono istanza automaticamente in fase di esecuzione quando viene rilevato un nuovo controller. Più puntatori possono essere collegati a un controller. Ad esempio, con il profilo del puntatore predefinito, Windows Mixed Reality controller ottengono rispettivamente una riga e un puntatore parabolico per la selezione normale e il teleportazione.

Configurazione puntatore

I puntatori vengono configurati come parte del sistema di input in MRTK tramite .MixedRealityPointerProfile Questo tipo di profilo viene assegnato a un MixedRealityInputSystemProfile nel controllo configurazione MRTK. Il profilo puntatore determina il cursore, i tipi di puntatori disponibili in fase di esecuzione e il modo in cui questi puntatori comunicano tra loro per decidere quale è attivo.

  • Estensione puntatore : definisce la distanza massima per cui un puntatore può interagire con un GameObject.

  • Puntatore a Raycast Layer Masks : si tratta di una matrice con priorità di LayerMasks per determinare quali possibili oggetti GameObjects possono interagire con e l'ordine di interazione da tentare. Ciò può essere utile per garantire che i puntatori interagiscono con gli elementi dell'interfaccia utente prima di altri oggetti scena. Esempio di profilo puntatore

Configurazione delle opzioni del puntatore

La configurazione predefinita del profilo del puntatore MRTK include le classi del puntatore seguenti e i prefab associati out-of-box. L'elenco dei puntatori disponibili per il sistema in fase di esecuzione è definito in Opzioni puntatore nel profilo puntatore . Gli sviluppatori possono usare questo elenco per riconfigurare i puntatori esistenti, aggiungere nuovi puntatori o eliminarli.

Esempio di profilo opzioni puntatore

Ogni voce puntatore è definita dal set di dati seguente:

  • Tipo di controller : set di controller per cui un puntatore è valido.

    • Ad esempio, Il PokePointer è responsabile degli oggetti "poking" con un dito ed è, per impostazione predefinita, contrassegnata come solo per supportare il tipo di controller di mano articolato. I puntatori vengono creati solo quando un controller diventa disponibile e in particolare il tipo di controller definisce i controller con cui è possibile creare il prefab del puntatore.
  • Handness : consente a un puntatore di creare un'istanza solo per una mano specifica (sinistra/destra)

Nota

L'impostazione della proprietà Handedness di una voce Puntatore su None la disabilita dal sistema come alternativa alla rimozione di tale puntatore dall'elenco.

  • Prefab puntatore : questo asset prefab verrà creata un'istanza quando un controller corrispondente al tipo di controller specificato e la mano inizia a essere monitorato.

È possibile avere più puntatori associati a un controller. Ad esempio, in DefaultHoloLens2InputSystemProfile (Assets/MRTK/SDK/Profiles/HoloLens2/) il controller di mano articolato è associato al pokePointer, GrabPointer e defaultControllerPointer (ad esempio i raggi di mano).

Nota

MRTK fornisce un set di prefab puntatori in Asset/MRTK/SDK/Features/UX/Prefabs/Puntatori. Un nuovo prefab personalizzato può essere compilato purché contenga uno degli script puntatori in Asset/MRTK/SDK/Features/UX/Script/Puntatori o qualsiasi altro script che implementa IMixedRealityPointer.

Configurazione del cursore

Il cursore Sguardo è configurabile direttamente tramite la GazeCursorPrefab proprietà MixedRealityInputSystemProfile nell'editor. Per configurare il cursore usato per altri puntatori, è necessario modificare il prefab usato nel CursorPrefab campo del corrispondente BaseControllerPointer. Per modificare il programma di cursore, modificare la BaseCursor proprietà nel comportamento corrispondente IMixedRealityPointer .

Cursor Prefab, proprietà

Vedere i prefab del cursore in Asset/MRTK/SDK/Features/UX/Prefabs/Cursors , ad esempio implementazioni del comportamento del cursore. In particolare, DefaultGazeCursor offre un'implementazione affidabile della modifica dell'elemento grafico del cursore in base allo stato contestuale.

Classi puntatore predefinite

Le classi seguenti sono i puntatori MRTK predefiniti disponibili e definiti nel profilo di puntatore MRTK predefinito descritto in precedenza. Ogni prefab puntatore fornito in Asset/MRTK/SDK/Features/UX/Prefabs/Pointers contiene uno dei componenti del puntatore collegati.

Puntatori predefiniti MRTK

Puntatori lontani

LinePointer

LinePointer, una classe puntatore di base, disegna una linea dall'origine dell'input (ad esempio il controller) nella direzione del puntatore e supporta un singolo cast di raggi in questa direzione. In genere, le classi figlio come e ShellHandRayPointer i puntatori di teleporto vengono create e usate (che disegnano anche linee per indicare dove la teleportazione finirà in corrispondenza) anziché questa classe che fornisce principalmente funzionalità comuni.

Per i controller di movimento come in Oculus, Vive e Windows Mixed Reality, la rotazione corrisponderà alla rotazione del controller. Per altri controller come HoloLens 2 mani articolate, la rotazione corrisponde alla posizione puntante fornita dal sistema della mano.

Linea puntatore MRTK
CurvePointer

CurvePointer estende la classe LinePointer consentendo cast a raggi a più passaggi lungo una curva. Questa classe puntatore di base è utile per le istanze curve, ad esempio i puntatori di teleportazione in cui la linea si piega in modo coerente in una parabola.

ShellHandRayPointer

L'implementazione di ShellHandRayPointer, che si estende da LinePointer, viene usata come impostazione predefinita per il profilo del puntatore MRTK. Il prefab DefaultControllerPointer implementa la ShellHandRayPointer classe.

GGVPointer

Noto anche come puntatore Gaze/Gesture/Voice (GGV), il GGVPointer abilita l'aspetto di HoloLens 1 e tocca le interazioni, principalmente tramite Gaze e Air Tap o Gaze e voice Select interazione. La posizione e la direzione del puntatore GGV sono guidate dalla posizione e dalla rotazione della testa.

TouchPointer

TouchPointer è responsabile dell'uso dell'input Touch di Unity (ad esempio touchscreen). Queste sono "interazioni lontane" perché l'atto di toccare lo schermo casterà un raggio dalla fotocamera a una posizione potenzialmente lontana nella scena.

MousePointer

MousePointer consente a uno schermo di visualizzare il raycast mondiale per interazioni lontane, ma per il mouse invece del tocco.

Puntatore del mouse

Nota

Il supporto del mouse non è disponibile per impostazione predefinita in MRTK, ma può essere abilitato aggiungendo un nuovo provider MouseDeviceManager di dati di input al profilo di input MRTK e assegnandolo MixedRealityMouseInputProfile al provider di dati.

Puntatori vicino

PokePointer

Il PokePointer viene usato per interagire con gli oggetti del gioco che supportano "near interaction touchable". che sono GameObjects che hanno uno script collegato NearInteractionTouchable . Nel caso di UnityUI, questo puntatore cerca NearInteractionTouchableUnityUIs. Il PokePointer usa un oggetto SphereCast per determinare l'elemento touchable più vicino e viene usato per attivare elementi come i pulsanti premuti.

Quando si configura GameObject con il componente, assicurarsi di configurare il NearInteractionTouchable parametro localForward in modo che punti dalla parte anteriore del pulsante o da un altro oggetto che deve essere reso toccabile. Assicurarsi inoltre che i limiti del touchable corrispondano ai limiti dell'oggetto toccabile.

Proprietà utili del puntatore poke:

  • TouchableDistance: distanza massima in cui è possibile interagire con una superficie toccabile
  • Oggetti visivi: oggetto Game usato per eseguire il rendering dell'oggetto visivo della punta del dito (l'anello sul dito, per impostazione predefinita).
  • Linea: linea facoltativa da disegnare dalla dita alla superficie di input attiva.
  • Maschera di livello poke : matrice con priorità di LayerMasks per determinare quali possibili oggetti GameObject possono interagire con e l'ordine di interazione da tentare. Si noti che un GameObject deve avere anche un componente per interagire con un NearInteractionTouchable puntatore poke.
Puntatore poke
SpherePointer

SpherePointer usa UnityEngine.Physics.OverlapSphere per identificare l'oggetto più NearInteractionGrabbable vicino per l'interazione, utile per l'input "afferrabile" come .ManipulationHandler Analogamente alla PokePointer/NearInteractionTouchable coppia funzionale, per interagire con il puntatore Sphere, l'oggetto gioco deve contenere un componente che è lo NearInteractionGrabbable script.

Puntatore di afferramento

Proprietà utili del puntatore sphere:

  • Raggio cast della sfera: raggio per la sfera usata per eseguire query per oggetti afferrabili.
  • Near Object Margin: distanza superiore al raggio cast sphere per eseguire una query per rilevare se un oggetto è vicino al puntatore. Il raggio totale di rilevamento di oggetti vicino è Raggio cast sphere + Margine oggetto vicino
  • Angolo del settore dell'oggetto vicino: angolo intorno all'asse avanti del puntatore per la query per gli oggetti vicini. Rende la IsNearObject funzione di query come un cono. Questo valore è impostato su 66 gradi per impostazione predefinita in modo che corrisponda al comportamento di Hololens 2

Puntatore Sphere modificato per eseguire una query solo per gli oggetti nella direzione in avanti

  • Fattore di smoothing dell'oggetto vicino: fattore di smoothing per il rilevamento di oggetti vicini. Se un oggetto viene rilevato nel raggio dell'oggetto vicino, il raggio sottoposto a query diventa Near Object Radius * (1 + Near Object Smoothing Factor) per ridurre la sensibilità e rendere più difficile un oggetto lasciare l'intervallo di rilevamento.
  • Grab Layer Masks : matrice con priorità di LayerMasks per determinare quali possibili oggetti GameObject possono interagire con e l'ordine di interazione da tentare. Si noti che un GameObject deve avere anche un NearInteractionGrabbable oggetto per interagire con un Oggetto SpherePointer.

    Nota

    Il livello di consapevolezza spaziale è disabilitato nel prefab di GrabPointer predefinito fornito da MRTK. Questa operazione consente di ridurre l'impatto sulle prestazioni dell'esecuzione di una query di sovrapposizione della sfera con la mesh spaziale. È possibile abilitare questa operazione modificando il prefab di GrabPointer.

  • Ignora colliders Non in FOV: se ignorare i collideri che potrebbero essere vicini al puntatore, ma non in realtà nel FOV visivo. Ciò può impedire afferramenti accidentali e permetterà ai raggi della mano di attivare quando si potrebbe essere vicino a un afferrabile, ma non può vederlo. Visual FOV viene definito tramite un cono anziché il frustum tipico per motivi di prestazioni. Questo cono è centrato e orientato allo stesso modo del frustum della fotocamera con un raggio uguale a metà altezza dello schermo(o foV verticale).
Puntatore sphere

Puntatori teleporti

  • TeleportPointer genererà una richiesta di teleporto quando viene eseguita un'azione (ad esempio il pulsante di teleporto viene premuto) per spostare l'utente.
  • ParabolicTeleportPointer genererà una richiesta di teleporto quando viene eseguita un'azione (ad esempio il pulsante di teleporto viene premuto) con un raycast linea parabolico per spostare l'utente.
Puntatore Parabolico

Supporto puntatore per piattaforme di realtà mista

Nella tabella seguente vengono descritti i tipi di puntatore usati in genere per le piattaforme comuni in MRTK. NOTA: è possibile aggiungere diversi tipi di puntatore a queste piattaforme. Ad esempio, è possibile aggiungere un puntatore Poke o un puntatore Sphere a VR. Inoltre, i dispositivi VR con un gamepad possono usare il puntatore GGV.

Puntatore OpenVR Windows Mixed Reality HoloLens 1 HoloLens 2
ShellHandRayPointer Valido Valido Valido
TeleportPointer Valido Valido
GGVPointer Valido
SpherePointer Valido
PokePointer Valido

Interazioni del puntatore tramite codice

Interfacce evento puntatore

MonoBehaviours che implementa una o più delle interfacce seguenti e vengono assegnate a un GameObject con un Collider oggetto riceverà eventi di interazione puntatore come definito dall'interfaccia associata.

Event Descrizione Gestore
Prima della modifica dello stato attivo/modifica dello stato attivo Generato sia sull'oggetto gioco che perde lo stato attivo e quello che lo ottiene ogni volta che un puntatore cambia lo stato attivo. IMixedRealityFocusChangedHandler
Messa a fuoco invio/uscita Generato sull'oggetto gioco ottenendo lo stato attivo quando il primo puntatore lo entra e su uno perde lo stato attivo quando l'ultimo puntatore lo lascia. IMixedRealityFocusHandler
Puntatore verso il basso/Trascinato/Verso l'alto/Fare clic su Generato in puntatore di report premere, trascinare e rilasciare. IMixedRealityPointerHandler
Tocco avviato/aggiornato/completato Generato dai puntatori a riconoscimento del tocco come PokePointer segnalare l'attività tocco. IMixedRealityTouchHandler

Nota

IMixedRealityFocusChangedHandler e IMixedRealityFocusHandler deve essere gestito negli oggetti su cui vengono generati. È possibile ricevere eventi di stato attivo a livello globale, ma, a differenza di altri eventi di input, il gestore eventi globale non blocca la ricezione di eventi in base allo stato attivo (l'evento verrà ricevuto sia dal gestore globale che da un oggetto corrispondente nello stato attivo).

Eventi di input puntatore in azione

Gli eventi di input del puntatore vengono riconosciuti e gestiti dal sistema di input MRTK in modo analogo agli eventi di input regolari. La differenza è che gli eventi di input del puntatore vengono gestiti solo dal GameObject in stato attivo dal puntatore che ha attivato l'evento di input, nonché da tutti i gestori di input globali. Gli eventi di input regolari vengono gestiti da GameObjects nello stato attivo per tutti i puntatori attivi.

  1. Il sistema di input MRTK riconosce che si è verificato un evento di input
  2. Il sistema di input MRTK attiva la funzione di interfaccia pertinente per l'evento di input a tutti i gestori di input globali registrati
  3. Il sistema di input determina quale GameObject è attivo per il puntatore che ha attivato l'evento
    1. Il sistema di input usa il sistema eventi di Unity per attivare la funzione di interfaccia pertinente per tutti i componenti corrispondenti nel GameObject incentrato
    2. Se in qualsiasi momento un evento di input è stato contrassegnato come usato, il processo terminerà e non verranno ricevuti altri CallObjects.
      • Esempio: i componenti che implementano l'interfaccia IMixedRealityFocusHandler verranno cercati per ottenere un GameObject o perdere lo stato attivo
      • Nota: il sistema eventi unity verrà visualizzato in modo da cercare GameObject padre se non sono presenti componenti corrispondenti all'interfaccia desiderata nell'oggetto GameObject corrente.
  4. Se non vengono registrati gestori di input globali e non viene trovato GameObject con un componente/interfaccia corrispondente, il sistema di input chiamerà ogni gestori di input registrati di fallback

Esempio

Di seguito è riportato uno script di esempio che modifica il colore del renderer collegato quando un puntatore accetta o lascia lo stato attivo o quando un puntatore seleziona l'oggetto.

public class ColorTap : MonoBehaviour, IMixedRealityFocusHandler, IMixedRealityPointerHandler
{
    private Color color_IdleState = Color.cyan;
    private Color color_OnHover = Color.white;
    private Color color_OnSelect = Color.blue;
    private Material material;

    private void Awake()
    {
        material = GetComponent<Renderer>().material;
    }

    void IMixedRealityFocusHandler.OnFocusEnter(FocusEventData eventData)
    {
        material.color = color_OnHover;
    }

    void IMixedRealityFocusHandler.OnFocusExit(FocusEventData eventData)
    {
        material.color = color_IdleState;
    }

    void IMixedRealityPointerHandler.OnPointerDown(
         MixedRealityPointerEventData eventData) { }

    void IMixedRealityPointerHandler.OnPointerDragged(
         MixedRealityPointerEventData eventData) { }

    void IMixedRealityPointerHandler.OnPointerClicked(MixedRealityPointerEventData eventData)
    {
        material.color = color_OnSelect;
    }
}

Puntatori di query

È possibile raccogliere tutti i puntatori attualmente attivi eseguendo il ciclo attraverso le origini di input disponibili (ad esempio controller e input disponibili) per individuare quali puntatori sono collegati a loro.

var pointers = new HashSet<IMixedRealityPointer>();

// Find all valid pointers
foreach (var inputSource in CoreServices.InputSystem.DetectedInputSources)
{
    foreach (var pointer in inputSource.Pointers)
    {
        if (pointer.IsInteractionEnabled && !pointers.Contains(pointer))
        {
            pointers.Add(pointer);
        }
    }
}

Puntatore primario

Gli sviluppatori possono sottoscrivere l'evento FocusProviders PrimaryPointerChanged per ricevere una notifica quando il puntatore primario nello stato attivo è cambiato. Ciò può essere estremamente utile per identificare se l'utente sta attualmente interagisce con una scena tramite lo sguardo o un raggio di mano o un'altra origine di input.

private void OnEnable()
{
    var focusProvider = CoreServices.InputSystem?.FocusProvider;
    focusProvider?.SubscribeToPrimaryPointerChanged(OnPrimaryPointerChanged, true);
}

private void OnPrimaryPointerChanged(IMixedRealityPointer oldPointer, IMixedRealityPointer newPointer)
{
    ...
}

private void OnDisable()
{
    var focusProvider = CoreServices.InputSystem?.FocusProvider;
    focusProvider?.UnsubscribeFromPrimaryPointerChanged(OnPrimaryPointerChanged);

    // This flushes out the current primary pointer
    OnPrimaryPointerChanged(null, null);
}

La PrimaryPointerExample scena (Asset/MRTK/Esempi/Demos/Input/Scene/PrimaryPointer) mostra come usare gli PrimaryPointerChangedHandler eventi per rispondere a un nuovo puntatore primario.

Esempio di puntatore primario

Risultato puntatore

La proprietà puntatore Result contiene il risultato corrente per la query della scena usata per determinare l'oggetto con lo stato attivo. Per un puntatore raycast, come quelli creati per impostazione predefinita per i controller di movimento, l'input dello sguardo e i raggi della mano, conterrà la posizione e la normalità dell'hit raycast.

private void IMixedRealityPointerHandler.OnPointerClicked(MixedRealityPointerEventData eventData)
{
    var result = eventData.Pointer.Result;
    var spawnPosition = result.Details.Point;
    var spawnRotation = Quaternion.LookRotation(result.Details.Normal);
    Instantiate(MyPrefab, spawnPosition, spawnRotation);
}

La PointerResultExample scena (Assets/MRTK/Examples/Demos/Input/Scenes/PointerResult/PointerResultExample.unity) mostra come usare il puntatore Result per generare un oggetto nella posizione di hit.

Risultato puntatore

Disabilitare i puntatori

Per attivare e disabilitare i puntatori (ad esempio, per disabilitare il raggio della mano), impostare l'oggetto PointerBehavior per un determinato tipo di puntatore tramite PointerUtils.

// Disable the hand rays
PointerUtils.SetHandRayPointerBehavior(PointerBehavior.AlwaysOff);

// Disable hand rays for the right hand only
PointerUtils.SetHandRayPointerBehavior(PointerBehavior.AlwaysOff, Handedness.Right);

// Disable the gaze pointer
PointerUtils.SetGazePointerBehavior(PointerBehavior.AlwaysOff);

// Set the behavior to match HoloLens 1
// Note, if on HoloLens 2, you must configure your pointer profile to make the GGV pointer show up for articulated hands.
public void SetHoloLens1()
{
    PointerUtils.SetPokePointerBehavior(PointerBehavior.AlwaysOff, Handedness.Any);
    PointerUtils.SetGrabPointerBehavior(PointerBehavior.AlwaysOff, Handedness.Any);
    PointerUtils.SetRayPointerBehavior(PointerBehavior.AlwaysOff, Handedness.Any);
    PointerUtils.SetGGVBehavior(PointerBehavior.Default);
}

Per altri esempi, vedere PointerUtils e TurnPointersOnOff per altri esempi.

Interazioni del puntatore tramite editor

Per gli eventi del puntatore gestiti da IMixedRealityPointerHandler, MRTK offre ulteriore praticità sotto forma di PointerHandler componente, che consente di gestire gli eventi del puntatore direttamente tramite Gli eventi unity.

Gestore puntatore

Estensione puntatore

I puntatori lontani hanno impostazioni che limitano la distanza in cui verranno raggicast e interagiscono con altri oggetti nella scena. Per impostazione predefinita, questo valore è impostato su 10 metri. Questo valore è stato scelto per rimanere coerente con il comportamento della shell HoloLens.

Questa modifica può essere modificata aggiornando i DefaultControllerPointer campi del componente del ShellHandRayPointer prefab:

Estensione puntatore : consente di controllare la distanza massima con cui i puntatori interagiscono.

Estensione puntatore predefinita : consente di controllare la lunghezza del raggio/riga del puntatore che eseguirà il rendering quando il puntatore non interagisce con nulla.

Vedi anche