Mutatók – MRTK2

Mutató

Ez a cikk bemutatja, hogyan konfigurálhatja és válaszolhatja meg a mutató bemenetét a gyakorlatban. Ha jobban meg szeretné érteni, hogyan vezérelhet több mutatót magas szinten, olvassa el a Mutatóarchitektúra című témakört.

A mutatókat a rendszer futásidőben automatikusan példányba helyezi, amikor új vezérlőt észlel. Egy vezérlőhöz több mutató is csatolható. Az alapértelmezett mutatóprofillal például Windows Mixed Reality vezérlők egy vonalat és egy parabolikus mutatót is kapnak a normál kijelöléshez és a teleportáláshoz.

Mutató konfigurációja

A mutatók az MRTK bemeneti rendszerének részeként vannak konfigurálva egy MixedRealityPointerProfilerendszeren keresztül. Ez a profiltípus az MRTK configuration inspector egyikéhez van hozzárendelve MixedRealityInputSystemProfile . A Mutatóprofil határozza meg a kurzort, a futtatókörnyezetben elérhető mutatók típusait, valamint azt, hogy ezek a mutatók hogyan kommunikálnak egymással annak eldöntéséhez, hogy melyik aktív.

  • Pontozási mérték – Azt a maximális távolságot határozza meg, amelynél a mutató használhatja a GameObject-et.

  • Raycast-rétegmaszkok mutatása – Ez a Rétegmaszkok rangsorolt tömbje annak meghatározására, hogy az adott mutató mely lehetséges GameObjects-elemekkel kommunikálhat, és hogy milyen sorrendben próbálja meg az interakciót. Ez hasznos lehet annak biztosításához, hogy a mutatók először a többi jelenetobjektum előtt használják a felhasználói felület elemeit. Példa mutatóprofilra

Mutató beállításainak konfigurálása

Az alapértelmezett MRTK-mutatóprofil-konfiguráció a következő mutatóosztályokat és a hozzá tartozó előlapokat tartalmazza. A rendszer számára futásidőben elérhető mutatók listája a Mutatóprofil Mutatóbeállítások területén van definiálva. A fejlesztők ezt a listát felhasználhatják a meglévő mutatók újrakonfigurálására, új mutatók hozzáadására vagy törlésére.

Példa mutatóbeállítások profilra

Az egyes pointer-bejegyzéseket a következő adatkészlet határozza meg:

  • Vezérlő típusa – Azoknak a vezérlőknek a készlete, amelyekre a mutató érvényes.

    • Például a PokePointer felelős az objektumok ujjal történő "pokingjáért", és alapértelmezés szerint csak a csuklós kézi vezérlőtípust támogatja. A mutatók csak akkor lesznek példányosítva, ha egy vezérlő elérhetővé válik, és különösen a Vezérlő típusa határozza meg, hogy mely vezérlőkkel hozható létre ez a mutatóelőfab.
  • Kezesség – lehetővé teszi, hogy egy mutató csak egy adott kézhez legyen példányosítva (balra/jobbra)

Megjegyzés

Ha a Mutató bejegyzés Handedness tulajdonságát Nincs értékre állítja, azzal gyakorlatilag letiltja azt a rendszerből a mutató listából való eltávolításának alternatívájaként.

  • Pointer Prefab – Ez az előfab objektum akkor lesz példányosítva, ha egy, a megadott vezérlőtípusnak és a kézitásnak megfelelő vezérlő nyomon követése elindul.

Egy vezérlőhöz több mutató is társítható. Például az (Assets/MRTK/SDK/Profiles/HoloLens2/) fájlban DefaultHoloLens2InputSystemProfile a csuklós kézi vezérlő a PokePointerhez, a GrabPointerhez és a DefaultControllerPointerhez (azaz a kézi sugarakhoz) van társítva.

Megjegyzés

Az MRTK mutatóelőtagokat biztosít az Assets/MRTK/SDK/Features/UX/Prefabs/Pointers elemben. Új egyéni előfab hozható létre, feltéve, hogy az eszközök/MRTK/SDK/Features/UX/Scripts/Pointers vagy bármely más implementáló szkript egyik mutatószkriptjét IMixedRealityPointertartalmazza.

Kurzorkonfiguráció

A Tekintet kurzor közvetlenül konfigurálható a GazeCursorPrefab Szerkesztőben található tulajdonságon MixedRealityInputSystemProfile keresztül. A többi mutatóhoz használt kurzor konfigurálásához módosítania kell a CursorPrefab megfelelő BaseControllerPointermezőben használt előfabot. A kurzor programozott módon történő módosításához módosítsa a BaseCursor tulajdonságot a megfelelő IMixedRealityPointer viselkedésen.

Kurzor előfab tulajdonsága

A kurzor-előfabsokat az Assets/MRTK/SDK/Features/UX/Prefabs/Cursors területen tekintheti meg, például a kurzor viselkedésének implementációit. A DefaultGazeCursor különösen hatékony implementációt biztosít a kurzor képének környezeti állapoton alapuló módosításához.

Alapértelmezett mutatóosztályok

A következő osztályok a fent vázolt alapértelmezett MRTK-mutatóprofilban elérhető és definiált, beépített MRTK-mutatók. Az Assets/MRTK/SDK/Features/UX/Prefabs/Pointers alatt megadott egyes mutatóelőfabok tartalmazzák a csatolt mutatóösszetevők egyikét.

AZ MRTK alapértelmezett mutatói

Távoli mutatók

LinePointer

A LinePointer egy alapmutató-osztály, amely a bemenet forrásától (azaz a vezérlőtől) húz vonalat a mutató irányában, és támogatja az ebbe az irányba öntött egyetlen sugarat. Általában a gyermekosztályok, például a ShellHandRayPointer és a teleport mutatói példányosíthatók és használhatók (amelyek vonalakat rajzolnak, hogy jelezzék, hol végződik a teleportálás) ahelyett, hogy ez az osztály elsősorban általános funkciókat biztosít.

Az olyan mozgásvezérlők esetében, mint az Oculus, a Vive és a Windows Mixed Reality, a forgatás megegyezik a vezérlő forgatásával. Más vezérlők, például HoloLens 2 csuklós kezek esetében a forgatás megegyezik a kéz rendszer által biztosított mutató pózával.

MRTK mutatóvonal
CurvePointer

A CurvePointer kibővíti a LinePointer osztályt azáltal, hogy lehetővé teszi a többlépéses sugaras vetítéseket egy görbe mentén. Ez az alapmutató-osztály olyan ívelt példányok esetében hasznos, mint a teleportálási mutatók, ahol a vonal folyamatosan parabolába hajol.

ShellHandRayPointer

A ShellHandRayPointer implementációja, amely a -től LinePointerterjed ki, az MRTK Pointer Profile alapértelmezett elemét használja. A DefaultControllerPointer prefab implementálja az osztályt ShellHandRayPointer .

GGVPointer

Más néven a Gaze/Gesture/Voice (GGV) mutató, a GGVPointer hatalmi HoloLens 1 stílusú megjelenés és koppintás interakciók, elsősorban a tekintet és a levegő koppintás vagy a tekintet és a hang kiválasztása interakció. A GGV-mutató helyzetét és irányát a fej pozíciója és elforgatása vezérli.

TouchPointer

A TouchPointer felelős a Unity Touch bemenetének (azaz érintőképernyőjének) a működéséért. Ezek "távoli interakciók", mert a cselekmény megérinti a képernyőt vet egy sugarat a kamera egy potenciálisan távoli helyre a jelenetben.

MousePointer

A MousePointer a képernyőt a távoli interakciókhoz, de az érintés helyett az egér világához űzi.

Egérmutató

Megjegyzés

Az egértámogatás alapértelmezés szerint nem érhető el az MRTK-ban, de engedélyezhető egy új típusú MouseDeviceManagerbemeneti adatszolgáltató hozzáadása az MRTK bemeneti profiljához, és az MixedRealityMouseInputProfile adatszolgáltatóhoz való hozzárendelése.

Közeli mutatók

PokePointer

A PokePointer olyan játékobjektumokkal való interakcióra szolgál, amelyek támogatják a "közel érintéses interakciót". ezek a Csatolt NearInteractionTouchable szkripttel rendelkező GameObjects parancsprogramok. UnityUI esetén ez a mutató a NearInteractionTouchableUnityUI-kat keresi. A PokePointer a SphereCast használatával határozza meg a legközelebbi érinthető elemet, és a lenyomható gombokhoz hasonló dolgok bekapcsolására szolgál.

Amikor konfigurálja a GameObjectet az NearInteractionTouchable összetevővel, konfigurálja a localForward paramétert úgy, hogy a gomb vagy más, érintésre alkalmas objektum elejére mutasson. Győződjön meg arról is, hogy az érinthető korlátok megegyeznek az érinthető objektum határaival.

Hasznos Poke-mutató tulajdonságai:

  • TouchableDistance: Az érintéses felület maximális távolsága
  • Vizualizációk: Az ujjhegy vizualizáció megjelenítéséhez használt játékobjektum (alapértelmezés szerint az ujjon lévő gyűrű).
  • Vonal: Nem kötelező vonal, amely az ujjhegytől az aktív beviteli felületig húzható.
  • Poke Layer Masks – A LayerMasks rangsorolt tömbje annak meghatározásához, hogy a mutató mely lehetséges GameObjects-elemekkel kommunikálhat, és hogy milyen sorrendben próbálja meg az interakciót. Vegye figyelembe, hogy a GameObject-nek is rendelkeznie kell egy NearInteractionTouchable összetevővel a poke mutatóval való interakcióhoz.
Pökésmutató
SpherePointer

A SpherePointer a UnityEngine.Physics.OverlapSphere használatával azonosítja az interakcióhoz legközelebbi NearInteractionGrabbable objektumot, amely hasznos az olyan "megragadható" bemenetekhez, mint a ManipulationHandler. A funkcionális párhoz PokePointer/NearInteractionTouchable hasonlóan ahhoz, hogy a Sphere Pointerrel kommunikálhasson, a játékobjektumnak tartalmaznia kell egy olyan összetevőt, amely a NearInteractionGrabbable szkript.

Mutató megragadás

Hasznos gömbmutató tulajdonságai:

  • Gömböntvény sugara: A megragadható objektumok lekérdezéséhez használt gömb sugara.
  • Objektummargó közelében: A Gömböntvény sugara fölötti távolság, amely alapján megállapítható, hogy egy objektum közel van-e az egérmutatóhoz. Az objektum közelében lévő észlelési sugár összesen Gömböntvény sugara + Objektum margója közelében
  • Objektum szektorának közel szöge: Az egérmutató előretoló tengelye körüli szög a közeli objektumok lekérdezéséhez. IsNearObject A lekérdezési függvényt kúpként teszi el. Ez alapértelmezés szerint 66 fokra van állítva, hogy megfeleljen a Hololens 2 viselkedésének

A gömbmutató úgy van módosítva, hogy csak a továbbítási irányban lévő objektumok lekérdezésére legyen módosítva

  • Objektumközeli simítási tényező: Simítási tényező a közeli objektumészleléshez. Ha objektumot észlel a közeli objektum sugarában, a lekérdezett sugár ekkor objektum közeli sugara * (1 + Objektumközeli simítási tényező) lesz, hogy csökkentse a érzékenységet, és megnehezítse az objektum számára az észlelési tartomány elhagyását.
  • Rétegmaszkok megragadása – A LayerMasks rangsorolt tömbje annak meghatározására, hogy a mutató mely lehetséges GameObjects-elemekkel kommunikálhat, és hogy milyen sorrendben próbálja meg az interakciót. Vegye figyelembe, hogy a GameObjectnek rendelkeznie kell egy NearInteractionGrabbable SpherePointerrel való interakcióhoz is.

    Megjegyzés

    A térbeli tudatossági réteg le van tiltva az MRTK által biztosított alapértelmezett GrabPointer-előfabban. Ez azért történik, hogy csökkentse a térbeli hálóval átfedésben lévő gömb típusú lekérdezések teljesítményre gyakorolt hatását. Ezt a GrabPointer-előfab módosításával engedélyezheti.

  • Ütközők figyelmen kívül hagyása Nem az FOV-ban – Azt határozza meg, hogy figyelmen kívül hagyja-e azokat a ütközőket, amelyek a mutató közelében lehetnek, de valójában nem a vizualizáció FOV-jában. Ez megakadályozhatja a véletlen megragadásokat, és lehetővé teszi a kézi sugarak bekapcsolását, ha közel van egy megragadhatóhoz, de nem látja. A Visual FOV a jellemző frustum helyett egy kúpon keresztül van definiálva teljesítménybeli okokból. Ez a kúp a kamera frustumjával megegyező középpontú és orientált, amelynek sugara egyenlő a kijelző magasságával (vagy függőleges FOV-jával).
Gömbmutató

Teleportmutatók

  • TeleportPointer a művelet végrehajtásakor (azaz a teleport gomb megnyomásakor) teleportálási kérést küld a felhasználó áthelyezéséhez.
  • ParabolicTeleportPointer a művelet végrehajtásakor (azaz a teleport gomb megnyomásakor) egy parabolikus vonalas raycasttel indítja el a teleport-kérést a felhasználó áthelyezéséhez.
Mutató parabolikus

Mutató támogatása vegyes valósági platformokhoz

Az alábbi táblázat azOKAT a mutatótípusokat ismerteti, amelyeket általában az MRTK gyakori platformjaihoz használnak. MEGJEGYZÉS: Ezekhez a platformokhoz különböző mutatótípusok is hozzáadhatók. Hozzáadhat például egy Poke-mutatót vagy Sphere-mutatót a VR-hoz. Emellett a játékpaddal rendelkező VR-eszközök is használhatják a GGV mutatót.

Mutató OpenVR Windows Mixed Reality HoloLens 1 HoloLens 2
ShellHandRayPointer Érvényes Érvényes Érvényes
TeleportPointer Érvényes Érvényes
GGVPointer Érvényes
SpherePointer Érvényes
PokePointer Érvényes

Mutató interakciói kóddal

Mutató eseményillesztői

Azok a MonoBehavioursok, amelyek az alábbi felületek közül legalább egyet implementálnak, és egy GameObject-hez vannak rendelve, Collider a mutató interakciós eseményeit fogják kapni a társított felület által meghatározottak szerint.

Esemény Description Kezelő
Fókusz módosítása / Fókusz módosítása előtt Emelt mind a játék objektum elveszíti a fókuszt, és az egyik egyre minden alkalommal, amikor egy mutató módosítja a fókuszt. IMixedRealityFocusChangedHandler
Fókusz be- és kilépése Emelt a játék objektum egyre fókuszba, amikor az első mutató belép, és az egyik elveszíti a fókuszt, amikor az utolsó mutató elhagyja. IMixedRealityFocusHandler
Mutató lefelé / húzva / felfelé / kattintással A jelentésmutatóhoz emelve nyomja le, húzza és engedje fel. IMixedRealityPointerHandler
Touch Started /Updated /Completed Olyan érintésérzékeny mutatók emelik fel, mint az PokePointer érintéses tevékenységek jelentése. IMixedRealityTouchHandler

Megjegyzés

IMixedRealityFocusChangedHandler és IMixedRealityFocusHandler a felhozott objektumokban kell kezelni. A fókuszesemények globálisan fogadhatók, de a többi bemeneti eseménytől eltérően a globális eseménykezelő nem blokkolja az események fókuszon alapuló fogadását (az eseményt a globális kezelő és a megfelelő objektum is megkapja a fókuszban).

Mutató bemeneti eseményei működés közben

A mutató bemeneti eseményeit az MRTK bemeneti rendszere ugyanúgy ismeri fel és kezeli, mint a normál bemeneti eseményeket. A különbség az, hogy a mutató bemeneti eseményeit csak a fókuszban lévő GameObject kezeli a bemeneti eseményt aktiváló mutató, valamint a globális bemeneti kezelők. A rendszeres bemeneti eseményeket a GameObjects kezeli a fókuszban az összes aktív mutató esetében.

  1. Az MRTK bemeneti rendszere felismeri, hogy bemeneti esemény történt
  2. Az MRTK bemeneti rendszer a bemeneti esemény megfelelő interfészfüggvényét aktiválja az összes regisztrált globális bemeneti kezelő számára
  3. A bemeneti rendszer határozza meg, hogy melyik GameObject van a fókuszban az eseményt aktiváló mutatóhoz
    1. A bemeneti rendszer a Unity eseményrendszerével aktiválja a megfelelő interfészfüggvényt a koncentrált GameObject összes egyező összetevőjéhez
    2. Ha egy bemeneti eseményt használtként jelölt meg, a folyamat véget ér, és nem kap további GameObjects visszahívásokat.
      • Példa: Az interfészt IMixedRealityFocusHandler implementáló összetevőket a GameObject nyereséget keres, vagy elveszíti a fókuszt
      • Megjegyzés: A Unity eseményrendszer felbuborul a szülő GameObject kereséséhez, ha a kívánt felületnek megfelelő összetevők nem találhatók az aktuális GameObject-en.
  4. Ha nincsenek regisztrálva globális bemeneti kezelők, és nem található GameObject egyező összetevővel/felülettel, akkor a bemeneti rendszer meghívja az egyes tartalék regisztrált bemeneti kezelőket

Példa

Az alábbiakban egy példaszkript látható, amely megváltoztatja a csatolt renderelő színét, amikor egy mutató fókuszba kerül vagy elhagyja a fókuszt, vagy amikor egy mutató kijelöli az objektumot.

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

Lekérdezésmutatók

A jelenleg aktív összes mutató összegyűjthető a rendelkezésre álló bemeneti források (azaz a vezérlők és a rendelkezésre álló bemenetek) hurkolásával, hogy felderítse, mely mutatók vannak hozzájuk csatolva.

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

Elsődleges mutató

A fejlesztők feliratkozhatnak a FocusProviders PrimaryPointerChanged eseményre, hogy értesítést kapjanak, ha a fókuszban lévő elsődleges mutató megváltozott. Ez rendkívül hasznos lehet annak megállapításához, hogy a felhasználó jelenleg egy jelenetet tekintve, kézi sugáron vagy más bemeneti forráson keresztül kommunikál-e.

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

A PrimaryPointerExample (Assets/MRTK/Examples/Demos/Input/Scenes/PrimaryPointer) jelenetből megtudhatja, hogyan válaszolhat az PrimaryPointerChangedHandler eseményekre egy új elsődleges mutatóra.

Példa elsődleges mutatóra

Mutató eredménye

A mutató Result tulajdonság tartalmazza a fókuszban lévő objektum meghatározásához használt jelenet-lekérdezés aktuális eredményét. A raycast-mutatók esetében, például a mozgásvezérlőkhöz alapértelmezés szerint létrehozottakhoz, a bemenő tekintetekhez és a kézi sugarakhoz, tartalmazni fogja a raycast-találat helyét és normál értékét.

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

A PointerResultExample jelenet (Assets/MRTK/Examples/Demos/Input/Scenes/PointerResult/PointerResultExample.unity) bemutatja, hogyan lehet az egérmutatóval Result objektumot létrehozni a találat helyén.

Mutató eredménye

Mutatók letiltása

A mutatók engedélyezéséhez és letiltásához (például a kézi sugár letiltásához) állítsa be az adott mutatótípust a PointerBehavior használatával 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);
}

További példákért lásd PointerUtils a és TurnPointersOnOff a további példákat.

Mutatóműszerkesztések szerkesztőn keresztül

Az által IMixedRealityPointerHandlerkezelt mutatóesemények esetében az MRTK további kényelmet nyújt az PointerHandler összetevő formájában, így a mutatóesemények közvetlenül a Unity-eseményeken keresztül kezelhetők.

Mutatókezelő

Mutató kiterjedése

A távoli mutatók olyan beállításokkal rendelkeznek, amelyek korlátozzák, hogy milyen messzire sugárznak, és hogy milyen mértékben használják a jelenet más objektumait. Alapértelmezés szerint ez az érték 10 méterre van állítva. Ezt az értéket úgy választották ki, hogy összhangban maradjon a HoloLens-rendszerhéj viselkedésével.

Ez a prefab összetevő mezőinek ShellHandRayPointer frissítésével DefaultControllerPointer módosítható:

Mutató kiterjedése – Ez határozza meg, hogy a mutatók milyen távolságra lépnek.

Alapértelmezett mutató kiterjedése – Ez szabályozza a mutató sugarának/vonalának hosszát, amely akkor jelenik meg, ha a mutató nem kommunikál semmivel.

Lásd még