Pekare – MRTK2

Pekaren

Den här artikeln beskriver hur du konfigurerar och svarar på pekarindata i praktiken. Mer information om hur du styr flera pekare på hög nivå finns i Pekararkitektur.

Pekare instanseras automatiskt vid körning när en ny kontrollant identifieras. Mer än en pekare kan kopplas till en kontrollant. Med standardpekarprofilen får Windows Mixed Reality styrenheter både en linje och en parabolisk pekare för normal markering respektive teleportering.

Konfiguration av pekare

Pekare konfigureras som en del av indatasystemet i MRTK via en MixedRealityPointerProfile. Den här typen av profil tilldelas till en MixedRealityInputSystemProfile i MRTK-konfigurationskontrollen. Pekarprofilen avgör markören, vilka typer av pekare som är tillgängliga vid körning och hur pekarna kommunicerar med varandra för att avgöra vilken som är aktiv.

  • Pointing Extent – definierar det maximala avståndet för vilket en pekare kan interagera med ett GameObject.

  • Pekar på Raycast Layer Masks – det här är en prioriterad matris med LayerMasks för att avgöra vilka möjliga GameObjects en viss pekare kan interagera med och ordningen på interaktionen att försöka. Detta kan vara användbart för att se till att pekare interagerar med gränssnittselement först före andra scenobjekt. Exempel på pekarprofil

Konfiguration av pekaralternativ

Standardkonfigurationen för MRTK-pekarprofilen innehåller följande pekarklasser och associerade prefabs out-of-box. Listan över pekare som är tillgängliga för systemet vid körning definieras under Pekaralternativ i pekarprofilen. Utvecklare kan använda den här listan för att konfigurera om befintliga pekare, lägga till nya pekare eller ta bort en.

Exempel på pekaralternativprofil

Varje pekarpost definieras av följande datauppsättning:

  • Typ av kontrollant – Den uppsättning kontrollanter som en pekare är giltig för.

    • Till exempel ansvarar PokePointer för att "peta" objekt med ett finger, och är som standard markerat som endast stöd för den ledade handstyrenhetstypen. Pekare instansieras bara när en kontrollant blir tillgänglig och i synnerhet kontrollanttypen definierar vilka kontrollanter som den här pekarens prefab kan skapas med.
  • Handedness – tillåter en pekare till att bara instansieras för en specifik hand (vänster/höger)

Anteckning

Om du anger egenskapen Handedness för en pekarpost till Ingen inaktiveras den effektivt från systemet som ett alternativ till att ta bort pekaren från listan.

  • Pointer Prefab – Den här prefab-tillgången instansieras när en kontrollant som matchar den angivna kontrollanttypen och handligheten börjar spåras.

Det går att ha flera pekare associerade med en kontrollant. I (Assets/MRTK/SDK/Profiles/HoloLens2/) associeras till exempel DefaultHoloLens2InputSystemProfile den ledade handkontrollanten med PokePointer, GrabPointer och DefaultControllerPointer (dvs. handstrålar).

Anteckning

MRTK tillhandahåller en uppsättning pekarprefabs i Assets/MRTK/SDK/Features/UX/Prefabs/Pointers. En ny anpassad prefab kan skapas så länge den innehåller ett av pekarskripten i Assets/MRTK/SDK/Features/UX/Scripts/Pointers eller något annat skript som implementerar IMixedRealityPointer.

Markörkonfiguration

Gaze-markören kan konfigureras direkt via GazeCursorPrefab egenskapen i MixedRealityInputSystemProfile redigeraren. Om du vill konfigurera markören som används för andra pekare måste du ändra prefab som används i fältet för CursorPrefab motsvarande BaseControllerPointer. Om du vill ändra markören programmatiskt ändrar du BaseCursor egenskapen för motsvarande IMixedRealityPointer beteende.

Markörförhandsegenskap

Se våra markörprefabs i Assets/MRTK/SDK/Features/UX/Prefabs/Cursors för exempel på implementeringar av markörens beteende. I synnerhet ger DefaultGazeCursor en robust implementering av att ändra markörens grafik baserat på kontextuellt tillstånd.

Standardpekarklasser

Följande klasser är de färdiga MRTK-pekarna som är tillgängliga och definierade i standardprofilen för MRTK-pekare som beskrivs ovan. Varje prefab för pekare som anges under Assets/MRTK/SDK/Features/UX/Prefabs/Pointers innehåller en av pekarkomponenterna.

STANDARDpekare för MRTK

Långt pekare

LinePointer

LinePointer, en baspekarklass, ritar en linje från indatakällan (d.v.s. kontrollanten) i pekarriktningen och stöder en enda ray-typ i den här riktningen. I allmänhet instansieras och används underordnade klasser som ShellHandRayPointer och teleporteringspekare (som också ritar linjer för att indikera var teleporteringen hamnar) i stället för den här klassen som främst tillhandahåller vanliga funktioner.

För rörelsekontrollanter som i Oculus, Vive och Windows Mixed Reality matchar rotationen kontrollantens rotation. För andra styrenheter som HoloLens 2 ledade händer matchar rotationen handens pekposition som tillhandahålls av systemet.

MRTK-pekarlinje
CurvePointer

CurvePointer utökar Klassen LinePointer genom att tillåta strålkastningar i flera steg längs en kurva. Den här baspekarklassen är användbar för böjda instanser, till exempel teleporteringspekare där linjen konsekvent böjs till en parabola.

ShellHandRayPointer

Implementeringen av ShellHandRayPointer, som sträcker sig från LinePointer, används som standard för MRTK-pekarprofilen. Prefab för DefaultControllerPointer implementerar ShellHandRayPointer klassen .

GGVPointer

GGVPointer, även känd som GGV-pekaren (Gaze/Gesture/Voice), driver HoloLens 1-stil utseende och tryckinteraktioner, främst via Gaze and Air Tap eller Gaze and voice Välj interaktion. GGV-pekarens position och riktning styrs av huvudets position och rotation.

TouchPointer

TouchPointer ansvarar för att arbeta med Unity Touch-indata (dvs. pekskärm). Detta är "långt interaktioner" eftersom handlingen att röra skärmen kommer att kasta en stråle från kameran till en potentiellt långt plats i scenen.

MousePointer

MousePointer driver en skärm till världens raycast för avlägsna interaktioner, men för mus istället för beröring.

Muspekaren

Anteckning

Musstöd är inte tillgängligt som standard i MRTK, men kan aktiveras genom att lägga till en ny indataprovider av typen MouseDeviceManager till MRTK-indataprofilen och tilldela MixedRealityMouseInputProfile till dataprovidern.

Nära pekare

PokePointer

PokePointer används för att interagera med spelobjekt som stöder "nära interaktionspekbar". som är GameObjects som har ett kopplat NearInteractionTouchable skript. När det gäller UnityUI söker den här pekaren efter NearInteractionTouchableUnityUIs. PokePointer använder en SphereCast för att fastställa det närmaste pekbara elementet och används för att driva saker som de pressbara knapparna.

När du konfigurerar GameObject med komponenten NearInteractionTouchable måste du konfigurera localForward-parametern så att den pekar ut från knappens framsida eller något annat objekt som ska göras pekbart. Kontrollera också att pekbara gränser matchar gränserna för det pekbara objektet.

Användbara egenskaper för poke-pekare:

  • TouchableDistance: Maximalt avstånd där en beröringsbar yta kan interagera med
  • Visuella objekt: Spelobjekt som används för att återge visuellt fingerspetsobjekt (ringen på fingret, som standard).
  • Linje: Valfri linje att rita från fingertoppen till den aktiva indataytan.
  • Poke Layer Masks – en prioriterad matris med LayerMasks för att avgöra vilka möjliga GameObjects som pekaren kan interagera med och ordningen på interaktionen som ska försökas. Observera att ett GameObject också måste ha en NearInteractionTouchable komponent för att interagera med en poke-pekare.
Peta pekare
SpherePointer

SpherePointer använder UnityEngine.Physics.OverlapSphere för att identifiera närmaste NearInteractionGrabbable objekt för interaktion, vilket är användbart för "grabbbara" indata som ManipulationHandler. Precis som det PokePointer/NearInteractionTouchable funktionella paret måste spelobjektet innehålla en komponent som är skriptet för att kunna interagera med sphere-pekaren NearInteractionGrabbable .

Hämtar pekare

Användbara egenskaper för sphere-pekare:

  • Sfärens gjutningsradie: Radien för den sfär som används för att fråga efter handtagsbara objekt.
  • Nära objektmarginal: Avståndet ovanpå sfärens gjutna radie för att fråga efter identifiering av om ett objekt ligger nära pekaren. Total identifieringsradie nära objekt är sfärens gjutna radie + nära objektmarginalen
  • Nära objektsektorvinkel: Vinkeln runt pekarens framåtaxel för att fråga efter närliggande objekt. Gör att IsNearObject frågan fungerar som en kon. Detta är inställt på 66 grader som standard för att matcha Hololens 2-beteende

Sphere-pekare har ändrats till att endast fråga efter objekt i framåtriktad riktning

  • Utjämningsfaktor för nära objekt: Utjämningsfaktor för identifiering av nära objekt. Om ett objekt identifieras i radien Nära objekt blir den efterfrågade radien nära objektradien * (1 + utjämningsfaktor för nära objekt) för att minska känsligheten och göra det svårare för ett objekt att lämna identifieringsområdet.
  • Grab Layer Masks – en prioriterad matris med LayerMasks för att avgöra vilka möjliga GameObjects pekaren kan interagera med och ordningen på interaktionen att försöka. Observera att ett GameObject också måste ha en NearInteractionGrabbable för att interagera med en SpherePointer.

    Anteckning

    Spatial Awareness-lagret är inaktiverat i standardprefab för GrabPointer som tillhandahålls av MRTK. Detta görs för att minska prestandaeffekten av att göra en sfäröverlappningsfråga med det rumsliga nätet. Du kan aktivera detta genom att ändra prefab för GrabPointer.

  • Ignorera Colliders Inte i FOV – Om du vill ignorera kolliderare som kan vara nära pekaren, men inte i det visuella FOV. Detta kan förhindra oavsiktliga tagningar, och gör att handstrålar kan aktiveras när du kanske är nära en gripbar men inte kan se den. Visual FOV definieras via en kon i stället för den typiska frustum av prestandaskäl. Denna kon är centrerad och orienterad på samma sätt som kamerans frustum med en radie som motsvarar halv visningshöjd (eller vertikal FOV).
Sfärpekare

Teleporterpekare

  • TeleportPointer genererar en teleporteringsbegäran när åtgärder vidtas (t.ex. teleporteringsknappen trycks på) för att flytta användaren.
  • ParabolicTeleportPointer genererar en teleporteringsbegäran när åtgärder vidtas (dvs. teleporteringsknappen trycks på) med en parabolisk linjestråle för att flytta användaren.
Pekare parabolisk

Pekarstöd för plattformar för mixad verklighet

I följande tabell beskrivs de pekartyper som vanligtvis används för vanliga plattformar i MRTK. Obs! Det är möjligt att lägga till olika pekartyper på dessa plattformar. Du kan till exempel lägga till en poke-pekare eller sphere-pekare till VR. Dessutom kan VR-enheter med en gamepad använda GGV-pekaren.

Pekare OpenVR Windows Mixed Reality HoloLens 1 HoloLens 2
ShellHandRayPointer Giltig Giltig Giltig
TeleportPointer Giltig Giltig
GGVPointer Giltig
SpherePointer Giltig
PokePointer Giltig

Pekarinteraktioner via kod

Gränssnitt för pekare

MonoBehaviours som implementerar ett eller flera av följande gränssnitt och tilldelas till ett GameObject med en Collider tar emot pekarinteraktioner som definieras av det associerade gränssnittet.

Händelse Description Hanterare
Innan fokus ändrades/fokus ändrades Upphöjt på både spelobjektet förlorar fokus och den som får den varje gång en pekare ändrar fokus. IMixedRealityFocusChangedHandler
Fokus retur/avsluta Upphöjt på spelobjektet får fokus när den första pekaren går in i den och på den som förlorar fokus när den sista pekaren lämnar den. IMixedRealityFocusHandler
Pekare nedåt/drad/uppåt/klickad Upphöjt till rapportpekartryckning, dra och släpp. IMixedRealityPointerHandler
Touch Started/Uppdaterad/Slutförd Upphöjt av beröringsmedvetna pekare som PokePointer att rapportera pekaktivitet. IMixedRealityTouchHandler

Anteckning

IMixedRealityFocusChangedHandler och IMixedRealityFocusHandler bör hanteras i de objekt som de lyfts upp på. Det är möjligt att ta emot fokushändelser globalt, men till skillnad från andra indatahändelser blockerar inte den globala händelsehanteraren mottagande händelser baserat på fokus (händelsen tas emot av både den globala hanteraren och ett motsvarande objekt i fokus).

Pekarindatahändelser i praktiken

Pekarens indatahändelser identifieras och hanteras av MRTK-indatasystemet på ett liknande sätt som vanliga indatahändelser. Skillnaden är att pekarens indatahändelser endast hanteras av GameObject i fokus av pekaren som utlöste indatahändelsen samt eventuella globala indatahanterare. Vanliga indatahändelser hanteras av GameObjects i fokus för alla aktiva pekare.

  1. MRTK-indatasystemet identifierar att en indatahändelse har inträffat
  2. MRTK-indatasystemet utlöser den relevanta gränssnittsfunktionen för indatahändelsen till alla registrerade globala indatahanterare
  3. Indatasystemet avgör vilket GameObject som är i fokus för pekaren som utlöste händelsen
    1. Indatasystemet använder Unitys händelsesystem för att utlösa relevant gränssnittsfunktion för alla matchande komponenter på det fokuserade GameObject
    2. Om en indatahändelse har markerats som använd avslutas processen och inga ytterligare GameObjects får återanrop.
      • Exempel: Komponenter som implementerar gränssnittet IMixedRealityFocusHandler genomsöks efter en GameObject-vinst eller förlorar fokus
      • Obs! Unity-händelsesystemet bubblar upp för att söka i det överordnade GameObject om inga komponenter som matchar önskat gränssnitt hittas i det aktuella GameObject..
  4. Om inga globala indatahanterare har registrerats och inget GameObject hittas med en matchande komponent/gränssnitt anropar indatasystemet varje fallback-registrerade indatahanterare

Exempel

Nedan visas ett exempelskript som ändrar färgen på den bifogade återgivningen när en pekare tar eller lämnar fokus eller när en pekare markerar objektet.

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;
    }
}

Frågepekare

Det går att samla in alla pekare som för närvarande är aktiva genom att loopa igenom de tillgängliga indatakällorna (dvs. tillgängliga styrenheter och indata) för att identifiera vilka pekare som är kopplade till dem.

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);
        }
    }
}

Primär pekare

Utvecklare kan prenumerera på händelsen FocusProviders PrimaryPointerChanged för att meddelas när den primära pekaren i fokus har ändrats. Detta kan vara mycket användbart för att identifiera om användaren för närvarande interagerar med en scen via blick eller en handstråle eller en annan indatakälla.

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);
}

Scenen PrimaryPointerExample (Assets/MRTK/Examples/Demos/Input/Scenes/PrimaryPointer) visar hur du använder PrimaryPointerChangedHandler för händelser för att svara på en ny primär pekare.

Exempel på primär pekare

Pekarresultat

Result Pekaregenskapen innehåller det aktuella resultatet för scenfrågan som används för att fastställa objektet med fokus. För en raycast-pekare, som de som skapats som standard för rörelsekontroller, blickinmatning och handstrålar, kommer den att innehålla platsen och det normala för raycast-träffen.

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);
}

Scenen PointerResultExample (Assets/MRTK/Examples/Demos/Input/Scenes/PointerResult/PointerResultExample.unity) visar hur du använder pekaren Result för att skapa ett objekt på träffplatsen.

Pekarresultat

Inaktivera pekare

Om du vill aktivera och inaktivera pekare (till exempel för att inaktivera handstrålen) anger du PointerBehavior för en viss pekartyp via 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);
}

Se PointerUtils och TurnPointersOnOff för fler exempel.

Pekarinteraktioner via redigeraren

För pekarhändelser som hanteras av IMixedRealityPointerHandlerger MRTK ytterligare bekvämlighet i form av komponenten PointerHandler , vilket gör att pekarhändelser kan hanteras direkt via Unity-händelser.

Pekarhanterare

Pekarens omfattning

Långt pekare har inställningar som begränsar hur långt de kommer att raycasta och interagera med andra objekt i scenen. Som standard är det här värdet inställt på 10 meter. Det här värdet valdes för att förbli konsekvent med beteendet för HoloLens-gränssnittet.

Detta kan ändras genom att uppdatera prefab-komponentens DefaultControllerPointerShellHandRayPointer fält:

Pekare– Detta styr det maximala avståndet som pekarna ska interagera med.

Standardvärde för pekare – Detta styr längden på pekarens stråle/linje som renderas när pekaren inte interagerar med någonting.

Se även