Interakciós – MRTK2

Interakciós

Az Interactable összetevő egy all-in-one tároló, amely bármely objektumot könnyen kezelhetővé és a bemenetre reagálóvá tesz. Az interakció minden típusú bemenethez használható, beleértve az érintést, a kézsugarakat, a beszédet stb. és ezeket az interakciókat eseményekbe és vizuális témákra adott válaszokba. Ez az összetevő megkönnyíti a gombok készítését, a fókuszban lévő objektumok színének módosítását és egyebeket.

Az interakciós beállítások konfigurálása

Az összetevő három elsődleges konfigurációs szakaszt tesz lehetővé:

  1. Általános bemeneti konfiguráció
  2. Több GameObjectsre célzott vizuális témák
  3. Eseménykezelők

Általános bemeneti beállítások

Általános interakciós beállítások

Állapotok

A States (Állapotok ) egy ScriptableObject paraméter, amely meghatározza az interakciós fázisokat, például a lenyomást vagy a megfigyelést az interakciós profilokhoz és a vizuális témákhoz.

A DefaultInteractableStates (Assets/MRTK/SDK/Features/UX/Interactable/States/DefaultInteractableStates.asset) az MRTK-t házon kívülre szállítja, és az interakciós összetevők alapértelmezett paramétere.

States ScriptableObject example in inspector

A DefaultInteractableStates objektum négy állapotot tartalmaz, és az állapotmodell implementálását InteractableStates használja.

  • Alapértelmezett: Semmi sem történik, ez a legelszigeteltebb alapállapot.

  • Fókusz: Az objektumra mutat. Ez egy egyetlen állapot, más állapotok nincsenek beállítva, de az Alapértelmezett rangsorban jelenik meg.

  • Nyomja le: Az objektumra mutat, és egy gomb vagy kéz lenyomva van. A Press state out a Default (Alapértelmezett) és a Focus (Fókusz) sorrendben van. Ez az állapot a Fizikai nyomdára való visszalépésként is be lesz állítva.

  • Letiltva: A gomb nem lehet interaktív, és a vizuális visszajelzések értesítik a felhasználót, ha valamilyen okból ez a gomb jelenleg nem használható. Elméletileg a letiltott állapot minden más állapotot tartalmazhat, de ha az Engedélyezve állapot ki van kapcsolva, a Letiltott állapot minden más állapotot aktivál.

A listában szereplő sorrendtől függően egy bitérték (#) van hozzárendelve az állapothoz.

Megjegyzés

Általában ajánlott a DefaultInteractableStates (Assets/MRTK/SDK/Features/UX/Interactable/States/DefaultInteractableStates.asset) használata interakciós összetevők létrehozásakor.

Azonban 17 elérhető interakciós állapot érhető el, amelyek a témák mozgatására használhatók, bár egyeseket más összetevőknek kell vezérelni. Íme a beépített funkciókkal rendelkezők listája.

  • Megtekintve: az Interakció elemre kattintott.
  • Kapcsoló: A gomb váltó állapotban van, vagy a Dimenzióindex páratlan szám.
  • Kézmozdulat: A kéz vagy a vezérlő lenyomva lett, és az eredeti pozícióból lett áthelyezve.
  • VoiceCommand: Beszédparancs használatával aktiválta az Interakciós parancsot.
  • PhysicalTouch: A rendszer jelenleg érintéses bemenetet észlel, amelyet az engedélyezéshez használhat NearInteractionTouchable .
  • Megragadás: Egy kéz jelenleg az objektum határait ragadja meg, és ezzel NearInteractionGrabbable engedélyezi a

Engedélyezve

Azt váltógomb, hogy engedélyezve lesz-e egy interakciós funkció. Ez a kódnak felel meg Interactable.IsEnabled .

Az Interactable engedélyezett tulajdonsága eltér a GameObject/Component használatával konfigurált engedélyezett tulajdonságtól (pl. SetActive stb.). A GameObject vagy az Interactable MonoBehaviour letiltása letiltja az osztály minden elemének futását, beleértve a bemeneteket, a vizuális témákat, az eseményeket stb. A letiltás Interactable.IsEnabled letiltja a legtöbb bemeneti kezelést, és alaphelyzetbe állítja a kapcsolódó bemeneti állapotokat. Az osztály azonban továbbra is minden keretet futtat, és fogadja a bemeneti eseményeket, amelyeket figyelmen kívül hagy. Ez akkor hasznos, ha az Interakció funkció letiltott állapotban jelenik meg, amely vizuális témákon keresztül végezhető el. Erre tipikus példa egy küldés gomb, amely az összes szükséges beviteli mező kitöltésére vár.

Bemeneti műveletek

Válassza ki azt a bemeneti műveletet a bemeneti konfigurációból vagy a vezérlőleképezési profilból, amelyekre az interakciós összetevőnek reagálnia kell.

Ez a tulajdonság futásidőben, kódban konfigurálható a használatával Interactable.InputAction.

IsGlobal

Ha igaz, az összetevőt globális bemeneti figyelőként jelöli meg a kiválasztott bemeneti művelethez. Az alapértelmezett viselkedés hamis, amely csak erre az interakciós ütköztetőre/GameObjectre korlátozza a bemenetet.

Ez a tulajdonság futásidőben, kódban konfigurálható a használatával Interactable.IsGlobal.

Speech Command

Az MRTK Beszédparancsok profilból származó Speech parancs egy OnClick-esemény hangalapú interakcióhoz való aktiválásához.

Ez a tulajdonság futásidőben, kódban konfigurálható a használatával Interactable.VoiceCommand.

Fókuszt igényel

Ha igaz, a hangparancs csak akkor aktiválja az Interakciós beállítást, ha és csak akkor, ha már van fókusza egy mutatóról. Ha hamis, akkor az Interakció funkció globális figyelőként fog működni a kiválasztott hangparancshoz. Az alapértelmezett viselkedés igaz, mivel több globális beszédfigyelőt nehéz lehet rendszerezni egy jelenetben.

Ez a tulajdonság futásidőben, kódban konfigurálható a használatával Interactable.VoiceRequiresFocus.

Kijelölési mód

Ez a tulajdonság határozza meg a kiválasztási logikát. Ha egy interakciós elemre kattint, a következő dimenziószintre lép. A dimenziók hasonlóak a rangsoroláshoz, és a bemeneteken kívüli állapotot határoznak meg (pl. fókusz, prés stb.). Ezek hasznosak a gombhoz társított váltóállapotok vagy más többsoros állapotok meghatározásához. Az aktuális dimenziószintet a következő követi nyomon: Interactable.DimensionIndex.

Az elérhető kijelölési módok a következők:

  • Gomb - Dimenziók = 1, egyszerű kattintásra használható
  • Váltás - Dimenziók = 2, Interakcióba lépő alternatívák a kikapcsolva/ állapot között
  • Többdimenziós - Méretek>= 3, minden kattintás növeli az aktuális dimenziószintet + 1. Hasznos egy lista gombállapotának definiálásához stb.

Az interakciós funkció lehetővé teszi, hogy dimenziónként több téma is definiálható legyen. Ha például a SelectionMode=Toggle kapcsolót választja, az egyik téma akkor alkalmazható, ha az Interakció lehetőség ki van választva , és egy másik téma lesz alkalmazva az összetevő kijelölésekor.

Az aktuális kijelölési mód futásidőben lekérdezhető a következőn keresztül: Interactable.ButtonMode. A üzemmód futásidőben történő frissítéséhez állítsa be a Interactable.Dimensions tulajdonságot a kívánt funkciónak megfelelően. A jelenlegi dimenzió, amely a Kapcsoló ésa Többdimenziós üzemmódok esetében hasznos, a segítségével Interactable.CurrentDimensionérhető el.

Interakciós profilok

A profilok olyan elemek, amelyek kapcsolatot hoznak létre a GameObject és a vizuális téma között. A profil határozza meg, hogy egy téma mely tartalmakat fogja kezelni állapotváltozás esetén.

A témák nagyon hasonlóak az anyagokhoz. Ezek olyan szkriptelhető objektumok, amelyek az aktuális állapot alapján egy objektumhoz hozzárendelendő tulajdonságok listáját tartalmazzák. A témák újra felhasználhatók, és több interakciós UX-objektumhoz is hozzárendelhetők .

Visszaállítás megsemmisítés után

A vizuális témák a kiválasztott témamotor osztályától és típusától függően módosítják a célzott GameObject különböző tulajdonságait. Ha a Visszaállítás a megsemmisítéskor igaz, amikor az Interakcióba lépő összetevő megsemmisül, az összetevő visszaállítja az összes módosított tulajdonságot az aktív témákból az eredeti értékükre. Ellenkező esetben, ha megsemmisül, az Interakcióba lépő összetevő a módosított tulajdonságokat változatlan állapotban hagyja. Ez utóbbi esetben az értékek utolsó állapota megmarad, kivéve, ha egy másik külső összetevő módosítja. Az alapértelmezett érték hamis.

Profilkészítés

esemény

Minden interakcióra alkalmas összetevő rendelkezik egy OnClick-eseménysel , amely akkor aktiválódik, amikor az összetevő egyszerűen ki van jelölve. Az Interakciós lehetőség azonban az OnClicken kívül más bemeneti események észlelésére is használható.

Kattintson az Esemény hozzáadása gombra egy új típusú event receiver-definíció hozzáadásához. A hozzáadás után válassza ki a kívánt eseménytípust.

Példa eseményekre)

Az esemény fogadóinak különböző típusai vannak, amelyek különböző típusú bemenetekre válaszolnak. Az MRTK a következő vevőkészlettel rendelkezik.

Egyéni fogadót úgy hozhat létre, hogy létrehoz egy új osztályt, amely kiterjeszti a következőt ReceiverBase: .

Példa eseményváltó fogadóra

Példa egy váltóesemény-fogadóra

Kezelhető fogadók

Az InteractableReceiver összetevő lehetővé teszi, hogy az események a forrás interaktív összetevőn kívül legyenek meghatározva . Az InteractableReceiver egy másik Interakciós lehetőség által aktivált szűrt eseménytípust figyel. Ha az Interactable tulajdonság nincs közvetlenül hozzárendelve, akkor a Keresési hatókör tulajdonság határozza meg, hogy az InteractableReceiver milyen irányban figyeli az eseményeket, amelyek önmagukban, egy szülőben vagy egy gyermek GameObjectben vannak.

InteractableReceiverList hasonló módon működik, de az egyező események listájáért.

Interakciós reciver

Egyéni események létrehozása

A Vizuális témákhoz hasonlóan az események is kiterjeszthetők az állapotminták észlelésére vagy a funkciók elérhetővé tételére.

Az egyéni események két fő módon hozhatók létre:

  1. Bővítse ki az ReceiverBase osztályt egy egyéni esemény létrehozásához, amely megjelenik az eseménytípusok legördülő listájában. Alapértelmezés szerint egy Unity-esemény van megadva, de további Unity-események is hozzáadhatók, vagy az esemény beállítható a Unity-események elrejtésére. Ez a funkció lehetővé teszi, hogy a tervező egy projekt mérnökével együttműködve egyéni eseményt hozzon létre, amelyet a tervező beállíthat a szerkesztőben.

  2. Bővítse ki az ReceiverBaseMonoBehavior osztályt egy teljesen egyéni eseményösszetevő létrehozásához, amely az Interakcióra alkalmas objektumon vagy egy másik objektumon található. A ReceiverBaseMonoBehavior az állapotváltozások észleléséhez az Interakcióra hivatkozik.

Példa a kiterjesztésre ReceiverBase

Az CustomInteractablesReceiver osztály állapotinformációkat jelenít meg az interakcióra alkalmas eszközökről, és példaként szolgál az egyéni eseményérzékelők létrehozására.

public CustomInteractablesReceiver(UnityEvent ev) : base(ev, "CustomEvent")
{
    HideUnityEvents = true; // hides Unity events in the receiver - meant to be code only
}

Az alábbi módszerek hasznosak az egyéni eseményérzékelők létrehozásakor történő felülbíráláshoz/implementáláshoz. ReceiverBase.OnUpdate() egy absztrakt módszer, amely az állapotminták/áttűnések észlelésére használható. Emellett a és ReceiverBase.OnClick() a ReceiverBase.OnVoiceCommand() metódusok hasznosak az egyéni eseménylogika létrehozásához, ha az Interakció lehetőség van kiválasztva.

public override void OnUpdate(InteractableStates state, Interactable source)
{
    if (state.CurrentState() != lastState)
    {
        // the state has changed, do something new
        lastState = state.CurrentState();
        ...
    }
}

public virtual void OnVoiceCommand(InteractableStates state, Interactable source,
                                    string command, int index = 0, int length = 1)
{
    base.OnVoiceCommand(state, source, command, index, length);
    // voice command called, perform some action
}  

public virtual void OnClick(InteractableStates state,
                            Interactable source,
                            IMixedRealityPointer pointer = null)
{
    base.OnClick(state, source);
    // click called, perform some action
}
Egyéni eseményérzékelő mezők megjelenítése az ellenőrben

A ReceiverBase-szkriptekInspectorField attribútumokkal teszik elérhetővé az egyéni tulajdonságokat az ellenőrben. Íme egy példa a Vector3-ra, amely egy egyéni tulajdonság elemleírással és címkével kapcsolatos információkkal. Ez a tulajdonság konfigurálhatóként jelenik meg az ellenőrben, ha egy Interaktív GameObject van kiválasztva, és hozzá van adva a társított Eseményérzékelő típus.

[InspectorField(Label = "<Property label>",Tooltip = "<Insert tooltip info>",Type = InspectorField.FieldTypes.Vector3)]
public Vector3 EffectOffset = Vector3.zero;

Az Interakciós lehetőség használata

Egyszerű gomb létrehozása

Létrehozhat egy egyszerű gombot, ha hozzáadja az Interactable összetevőt egy GameObject elemhez, amely a bemeneti események fogadására van konfigurálva. Lehet rajta ütköző, vagy egy gyermek, hogy fogadja a bemenetet. Ha Unity felhasználói felületen alapuló GameObjects-et használ, annak a Canvas GameObject alatt kell lennie.

A gombot egy lépéssel tovább lépve hozzon létre egy új profilt, rendelje hozzá magát a GameObjectet, és hozzon létre egy új témát. Emellett az OnClick esemény használatával is történhet valami.

Megjegyzés

A gomb megnyomhatóvá tételéhez az összetevőre PressableButton van szükség. Emellett az PhysicalPressEventRouter összetevőre is szükség van az eseményeknek az Interakcióra alkalmas összetevőre való tölcsérbe való benyomásához.

Váltógombok és többdimenziós gombok létrehozása

Váltógomb

Ha egy gombot ki szeretne váltani, módosítsa a mezőt úgy, hogy beírja a Selection Mode következőt Toggle: . A Profilok szakaszban minden olyan profilhoz új váltótéma kerül, amely akkor használatos, ha az Interakcióra lehetőség be van kapcsolva.

Amíg a SelectionMode értéke Váltógomb, az IsToggled jelölőnégyzettel beállíthatja a vezérlő alapértelmezett értékét a futtatókörnyezet inicializálásakor.

A CanSelect azt jelenti, hogy azInterakciós lehetőség ki-be kapcsolhat, míg a CanDeselect az inverzet jelenti.

Példa profilváltási vizuális témákra

A fejlesztők a és IsToggled a SetToggled interfészek használatával lekérhetik/beállíthatják az interakciós állapotot kóddal.

// If using SelectionMode = Toggle (i.e Dimensions == 2)

// Make the Interactable selected and toggled on
myInteractable.IsToggled = true;

// Get whether the Interactable is selected or not
bool isSelected = myInteractable.IsToggled;
Gombgyűjtemény váltógombja

Gyakori, hogy a váltógombok listája, ahol egy adott időpontban csak egy lehet aktív, más néven tárcsakészlet vagy választógomb stb.

A funkció engedélyezéséhez használja az InteractableToggleCollection összetevőt. Ez a vezérlő biztosítja, hogy egy adott időpontban csak egy interakciós lehetőség legyen bekapcsolva. A RadialSet (Assets/MRTK/SDK/Features/UX/Interactable/Prefabs/RadialSet.prefab) szintén remek kiindulási pont.

Egyéni radiális gombcsoport létrehozása:

  1. Több interaktív GameObjects/button létrehozása
  2. Állítsa be aSelectionMode = Váltógomb, a CanSelect = true és a CanDeselect = false értéket.
  3. Hozzon létre egy üres szülő GameObject objektumot az összes interakcióhoz , és adja hozzá az InteractableToggleCollection összetevőt
  4. Az Összes interakciós elem hozzáadása a ToggleList elemhez az InteractableToggleCollection elemen
  5. Állítsa be az InteractableToggleCollection.CurrentIndex tulajdonságot annak meghatározásához, hogy melyik gomb van alapértelmezés szerint kiválasztva az indításkor
Gyűjtemény váltógombja

Többdimenziós gomb

A többdimenziós kijelölési mód szekvenciális gombok létrehozására szolgál, vagy olyan gombok létrehozására, amelyek több mint két lépésből áll, például a sebesség szabályozása három értékkel, Gyors (1x), Gyorsabb (2x) vagy Leggyorsabb (3x).

Mivel a dimenziók numerikus értékek, akár 9 téma is hozzáadható a gomb szövegcímkéjének vagy anyagmintázatának szabályozásához az egyes sebességbeállításokhoz, és minden lépéshez más témát használ.

Minden kattintási esemény futásidőben 1-et lép DimensionIndex előre, amíg el nem éri az Dimensions értéket. Ezután a ciklus visszaáll 0-ra.

Példa többdimenziós profilra

A fejlesztők felmérhetik, DimensionIndex hogy melyik dimenzió aktív jelenleg.

// If using SelectionMode = Multi-dimension (i.e Dimensions >= 3)

//Access the current DimensionIndex
int currentDimension = myInteractable.CurrentDimension;

//Set the current DimensionIndex to 2
myInteractable.CurrentDimension = 2;

// Promote Dimension to next level
myInteractable.IncreaseDimension();

Interakcióra alkalmas létrehozása futásidőben

Az interakciós lehetőség egyszerűen hozzáadható bármely GameObjecthez futásidőben. Az alábbi példa bemutatja, hogyan rendelhet hozzá egy profilt egy vizuális témához.

var interactableObject = GameObject.CreatePrimitive(PrimitiveType.Cylinder);
var interactable = interactableObject.AddComponent<Interactable>();

// Get the default configuration for the Theme engine InteractableColorTheme
var newThemeType = ThemeDefinition.GetDefaultThemeDefinition<InteractableColorTheme>().Value;

// Define a color for every state in our Default Interactable States
newThemeType.StateProperties[0].Values = new List<ThemePropertyValue>()
{
    new ThemePropertyValue() { Color = Color.black},  // Default
    new ThemePropertyValue() { Color = Color.black}, // Focus
    new ThemePropertyValue() { Color = Random.ColorHSV()},   // Pressed
    new ThemePropertyValue() { Color = Color.black},   // Disabled
};

interactable.Profiles = new List<InteractableProfileItem>()
{
    new InteractableProfileItem()
    {
        Themes = new List<Theme>()
        {
            Interactable.GetDefaultThemeAsset(new List<ThemeDefinition>() { newThemeType })
        },
        Target = interactableObject,
    },
};

// Force the Interactable to be clicked
interactable.TriggerOnClick()

Interakciós események kóddal

Az alapesethez Interactable.OnClick az alábbi példában szereplő kóddal adhat hozzá műveletet.

public static void AddOnClick(Interactable interactable)
{
    interactable.OnClick.AddListener(() => Debug.Log("Interactable clicked"));
}

Interactable.AddReceiver<T>() A függvénnyel dinamikusan adhat hozzá eseményérzékelőket futásidőben.

Az alábbi példakód bemutatja, hogyan adhat hozzá egy InteractableOnFocusReceivert, amely figyeli a fókusz be- és kilépését, valamint meghatározza az eseménypéldányok aktiválásakor végrehajtandó műveleti kódot.

public static void AddFocusEvents(Interactable interactable)
{
    var onFocusReceiver = interactable.AddReceiver<InteractableOnFocusReceiver>();

    onFocusReceiver.OnFocusOn.AddListener(() => Debug.Log("Focus on"));
    onFocusReceiver.OnFocusOff.AddListener(() => Debug.Log("Focus off"));
}

Az alábbi példakód bemutatja, hogyan adhat hozzá egy InteractableOnToggleReceivert, amely figyeli a kijelölt/nem kijelölt állapotváltásokat a váltógombos interakciókon, valamint meghatározza az eseménypéldányok aktiválásakor végrehajtandó műveleti kódot.

public static void AddToggleEvents(Interactable interactable)
{
    var toggleReceiver = interactable.AddReceiver<InteractableOnToggleReceiver>();

    // Make the interactable have toggle capability, from code.
    // In the gui editor it's much easier
    interactable.Dimensions = 2;
    interactable.CanSelect = true;
    interactable.CanDeselect  = true;

    toggleReceiver.OnSelect.AddListener(() => Debug.Log("Toggle selected"));
    toggleReceiver.OnDeselect.AddListener(() => Debug.Log("Toggle un-selected"));
}

Lásd még