Kezelhető – MRTK2

Interactable

Az Interactable összetevő egy teljes körű tároló, amely minden 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ényekké és vizuális témákra adott válaszokká alakítja. Ez az összetevő egyszerű módot kínál a gombok készítésére, a fókuszban lévő objektumok színének módosítására és sok másra.

Az Interakciók 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 GameObjectre célzott vizuális témák
  3. Eseménykezelők

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

General Interactable Settings

Állapotok

Az Állapotok egy ScriptableObject paraméter, amely meghatározza az interakciós fázisokat, például a sajtót vagy a megfigyeltet, 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ül szállítja, és az interakcióra alkalmas ö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 egyetlen állapot, jelenleg nincsenek más állapotok beállítva, de az alapértelmezett rangsorban jelenik meg.

  • Nyomja le: Az objektum rámutat, és egy gomb vagy kéz lenyomva van. A Sajtó állapot az Alapértelmezett és a Fókusz rangsorban van. Ez az állapot a Physical Press tartalékaként is be lesz állítva.

  • Letiltva: A gomb nem lehet interaktív, és a vizuális visszajelzések tájékoztatják 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 az összes többi államot is kijátszja.

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

Megjegyzés

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

Azonban 17 használható állapot érhető el, amelyek a témák mozgatására használhatók, de néhányat más összetevőknek kell vezérelnie. Íme a beépített funkciókkal rendelkezők listája.

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

Engedélyezve

Azt jelzi, hogy az interakciós funkció engedélyezve lesz-e, vagy sem. Ez megfelel a Interactable.IsEnabled kódban megadottnak.

Az interakcióra képes tulajdonság 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 letiltja Interactable.IsEnabled a legtöbb bemeneti kezelést, és alaphelyzetbe állítja a kapcsolódó bemeneti állapotokat. Az osztály azonban továbbra is minden keretet lefuttat, és olyan bemeneti eseményeket fogad, amelyek figyelmen kívül lesznek hagyva. Ez akkor hasznos, ha az Interakció funkció letiltott állapotban jelenik meg, amely a vizuális témákon keresztül végezhető el. Erre tipikus példa a Küldés gomb, amely az összes szükséges beviteli mező befejezé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 konfigurálható a kódban a következőn keresztül 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özőre/GameObjectre korlátozza a bemenetet.

Ez a tulajdonság futásidőben konfigurálható a kódban a következőn keresztül Interactable.IsGlobal: .

Speech Command

A Beszéd parancs az MRTK Speech Commands-profilból onClick-esemény aktiválásához hangalapú interakcióhoz.

Ez a tulajdonság futásidőben konfigurálható a kódban a következőn keresztül Interactable.VoiceCommand: .

Fókuszt igényel

Ha igaz, a hangparancs csak akkor és csak akkor aktiválja az Interakcióképes parancsot, ha már van fókusza egy mutatóról. Ha hamis, akkor az Interactable a kiválasztott hangparancs globális figyelőjeként fog működni. 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 konfigurálható a kódban a következőn keresztül 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 vált. A dimenziók hasonlóak a rangsoroláshoz, és a bemeneteken kívüli állapotot határoznak meg (pl. fókusz, sajtó stb.). Ezek a gombokkal társított váltóállapotok vagy más többsoros állapotok meghatározásához hasznosak. Az aktuális dimenziószint nyomon követése a következő szerint Interactable.DimensionIndextörténik: .

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

  • Gomb - Dimenziók = 1, egyszerűen kattintható, kezelhető
  • Váltás - Dimenziók = 2, interakcióba léphető 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 gombállapotok listához való definiálásához stb.

Az interakcióvaldimenziónként több téma is definiálható. Ha például a SelectionMode=Toggle kapcsolót választja, az egyik téma akkor alkalmazható, ha az interakciós lehetőségnincs kijelölve , é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 mó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. Továbbá a jelenlegi dimenzió, amely a váltó- és a többdimenziós üzemmódokhoz hasznos, a következőn keresztül Interactable.CurrentDimensionérhető el: .

Kezelhető 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 milyen tartalmakat módosít egy á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 hozzárendelendő tulajdonságok listáját tartalmazzák. A témák is újra felhasználhatók, és több interakciós UX-objektumhoz rendelhetők hozzá.

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 az interakcióba lépő összetevő a módosított tulajdonságokat a jelen állapotában 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.

Profile theams

esemény

Minden interakcióra alkalmas összetevő rendelkezik egy OnClick-eseménysel , amely aktiválódik, amikor az összetevő egyszerűen ki van választva. 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ú eseményérzékelő-definíció hozzáadásához. A hozzáadás után válassza ki a kívánt eseménytípust.

Events example)

Különböző típusú eseményérzékelők válaszolnak a különböző típusú bemenetekre. Az MRTK a következő vevőkészlettel szállítja a dobozon kívül.

Egyéni fogadót úgy hozhat létre, hogy létrehoz egy új, kibővíthető osztályt ReceiverBase.

Event Toggle Receiver Example

Példa egy váltó eseményérzékelőre

Kezelhető fogadók

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

InteractableReceiverList hasonló módon viselkedik, de az egyező események listájára.

Interactable 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 megjelenítésé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ó úgy, hogy elrejtse a Unity-eseményeket. Ez a funkció lehetővé teszi, hogy a tervező együttműködjön egy mérnökkel egy projekten, és létrehozhasson egy egyéni eseményt, amelyet a tervező beállíthat a szerkesztőben.

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

Példa a kiterjesztésre ReceiverBase

Az CustomInteractablesReceiver osztály állapotinformációkat jelenít meg egy interakciós lehetőségről , és példa egyéni eseményérzékelő 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 metódusok és ReceiverBase.OnClick() a ReceiverBase.OnVoiceCommand() metódusok hasznosak az egyéni eseménylogika létrehozásához, amikor 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 vizsgálóban

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 elemleírással és címkével kapcsolatos információkat tartalmazó egyéni tulajdonság. 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 eszköz használata

Egyszerű gomb létrehozása

Létrehozhat egy egyszerű gombot, ha hozzáadja az Interakcióképes összetevőt egy olyan GameObject elemhez, amely úgy van konfigurálva, hogy fogadja a bemeneti eseményeket. Lehet rajta egy ü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 viheti, ha létrehoz egy új profilt, hozzárendeli magát a GameObjectet, és létrehoz 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 szükség van az összetevőre PressableButton . Emellett az PhysicalPressEventRouter összetevőre az interakciós összetevő eseményeinek tölcsérbe való benyomásához is szükség van.

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

Váltógomb

Ha gombot szeretne váltógombot létrehozni, módosítsa a mezőt gépelésre Selection ModeToggle. A Profilok szakaszban a rendszer minden olyan profilhoz új váltó témát ad hozzá, amely akkor használatos, amikor az Interakcióra lehetőség be van kapcsolva.

Amíg a SelectionMode kapcsoló váltógombra van állítva, az IsToggled jelölőnégyzettel beállíthatja a vezérlő alapértelmezett értékét futásidőben történő inicializáláskor.

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

Profile Toggle Visual Themes Example

A fejlesztők használhatják a SetToggledIsToggled felületeket az interakciós állapot kódon keresztüli lekéréséhez/beállításához.

// 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ása

Gyakori, hogy van egy lista a váltógombok, ahol csak egy lehet aktív bármikor, más néven tárcsakészlet vagy választógombok stb.

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

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

  1. Több interaktív GameObjects/gomb létrehozása
  2. A SelectionMode = Váltógomb, a CanSelect = true és a CanDeselect = false értékek mindegyikének beállítása
  3. Hozzon létre egy üres szülő GameObjectet az összes interakciós elemhez, é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
Toggle collection

Többdimenziós gomb

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

Mivel a dimenziók numerikus értékek, legfeljebb 9 téma adható hozzá a gomb szövegfeliratának vagy anyagmintázatának szabályozásához minden sebességbeállításhoz, minden lépéshez más témát használva.

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

Multi-Dimensional profile example

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

Futtatáskor használható létrehozása

Az interakciós funkció egyszerűen hozzáadható bármely GameObjecthez futásidőben. Az alábbi példa bemutatja, hogyan rendelhet hozzá egy profilt egy vizualizációs 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()

Kódon keresztül kezelhető események

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

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

A függvény használatával Interactable.AddReceiver<T>() 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 vehet fel egy InteractableOnToggleReceiver objektumot, amely figyeli a kijelölt/kijelzett á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