Kezelhető

Kezelhető

Az Interactable összetevő egy all-in-one tároló, amely minden objektumot könnyen kezelhető és a bemenetre reagáló módon biztosít. Az interakciós műveletek minden bemenethez használhatók, beleértve az érintést, a kéz sugarait, a beszédet stb. és ezeket az interakciókat eseményekbe és vizuális témaválaszokbe. Ez az összetevő egyszerű lehetőséget biztosít a gombok gombra, a fókuszt ható objektumok színének módosítása stb.

Interakciós kapcsolat konfigurálása

Az összetevő három fő 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 bemeneti beállítások

Általános interakciós Gépház

Állapotok

A States egy ScriptableObject paraméter, amely meghatározza az interakciós fázisokat( például a lenyomást vagy a megfigyeltet) az Interakciós profilok és a Vizuális témák esetében.

A DefaultInteractableStates (Assets/MRTK/SDK/Features/UX/Interactable/States/DefaultInteractableStates.asset) az MRTK-t tartalmazza, és a Kezelhető összetevők alapértelmezett paramétere.

States ScriptableObject példa az Inspectorban

A DefaultInteractableStates eszköz négy állapotot tartalmaz, és az állapotmodell InteractableStates implementációját használja.

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

  • Fókusz: A objektumra mutat. Ez egyetlen állapot, jelenleg nincsenek más állapotok beállítva, de az Alapértelmezett értékhez lesz rangsorolva.

  • Nyomja le: Az objektumra mutat, és egy gomb vagy kéz lenyomása folyamatban van. A Press state out rangsorolja az Alapértelmezett és a Fókusz értéket. Ez az állapot a Fizikai nyomás tartalékként is be lesz állítva.

  • Disabled: A gomb nem lehet interaktív, és a vizuális visszajelzés tudatja a felhasználóval, ha valamilyen okból ez a gomb jelenleg nem használható. Elméletileg a letiltott állapot az összes többi állapotot is tartalmazhatja, de ha az Engedélyezve beállítás ki van kapcsolva, a Letiltva állapot az összes többi állapotot is tartalmazza.

A lista sorrendjétől függően a rendszer bitértéket (#) rendel az állapothoz.

Megjegyzés

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

A témákat azonban 17 interakcióba ható módon lehet vezérelni, de ezek némelyikét más összetevőknek kell vezérelni. Az alábbi lista tartalmazza a beépített funkciókat.

  • Felkeresve: A Interactable (Interakció) gombra 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ójából lépett.
  • VoiceCommand: A Interactable aktiválására egy beszédparancsot használtak.
  • Physical Touch: A rendszer jelenleg érintéses bemenetet észlel. Ezt a használatával NearInteractionTouchable engedélyezheti.
  • Ragadás: Egy kéz jelenleg az objektum határán van megragadva, a segítségével NearInteractionGrabbable engedélyezze

Engedélyezve

Be- és bekapcsolja, hogy egy Interakciós eszköz engedélyezve legyen-e. Ez a kódban a Interactable.IsEnabled következőnek felel meg: .

A Interactable engedélyezett tulajdonsága eltér a GameObject/Component segítségével konfigurált engedélyezett tulajdonságtól (azaz SetActive stb.). A GameObject vagy a Kezelhető MonoBehaviour letiltása letiltja az osztályban lévő összes futását, beleértve a bemenetet, a vizuális témákat, az eseményeket stb. A segítségével történő Interactable.IsEnabled letiltás letiltja a legtöbb bemeneti kezelést, és alaphelyzetbe állítja a kapcsolódó bemeneti államokat. A osztály azonban továbbra is minden képkockát futtat, és fogadja a bemeneti eseményeket, amelyeket a rendszer figyelmen kívül hagy. Ez akkor hasznos, ha letiltott állapotban jeleníti meg az Interakciós interakciót, amely vizuális témákon keresztül érhető el. Erre jellemző példa egy 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 vezérlőleképezési profilból, amelyre a Kezelhető összetevőnek reagálnia kell.

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

IsGlobal

Ha true (igaz) érték van bejelölve, akkor az összetevő globális bemeneti figyelőként lesz megjelölve a kiválasztott bemeneti művelethez. Az alapértelmezett viselkedés hamis, ami a bemenetet csak erre a Interactable collider/GameObjectre korlátozza.

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

Beszédparancs

AzMRTK Speech Commands-profilból származó Speech parancs egy OnClick-esemény hangalapú interakcióhoz való aktiválására.

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

Fókuszt igényel

Ha igaz, a hangparancs csak akkor aktiválja az Interakcióra használható üzenetet, ha az már egy mutatóból van fókuszban. Ha hamis, akkor a Interactable a kiválasztott hangparancs globális figyelője lesz. Az alapértelmezett viselkedés igaz, mivel egy jelenetben nehéz lehet több globális beszéd figyeljen.

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

Kijelölési mód

Ez a tulajdonság határozza meg a kiválasztási logikát. Amikor egy Interakciós elemre kattint, a következő dimenziószintre lép. A dimenziók hasonlóak a rangsoroláshoz, és a bemeneten kívüli állapotot határoznak meg (vagyis fókusz, lenyomás stb.). Ezek akkor hasznosak, ha váltó államokat vagy más, gombhoz társított több rangsorú államot definiál. Az aktuális dimenziószintet a követi Interactable.DimensionIndex nyomon.

Az elérhető kiválasztási módok a következőek:

  • Gomb - Dimensions = 1, simple clickable Interactable
  • Váltógomb - Dimensions = 2, Interakcióra használható alternatívák a ki van / kapcsolva állapot között
  • Többdimenziós - Dimenziók >= 3, minden kattintás növeli az aktuális dimenziószintet + 1. Akkor hasznos, ha egy gombállapotot listához vagy hasonlókhoz definiál.

A kezelhető azt is lehetővé teszi, hogy dimenziónként több téma is definiálható legyen. Ha például a SelectionMode=Toggle van kiválasztva, az egyik téma alkalmazható, ha az Interakciós elem ki van választva, és egy másik téma lesz alkalmazva az összetevő kiválasztásakor.

Az aktuális kijelölési mód futásidőben kérdezhető le a következőn Interactable.ButtonMode keresztül: . A mód futásidőben való frissítése a kívánt funkciónak megfelelő tulajdonság Interactable.Dimensions beállításával érhető el. Emellett a váltó- és a többdimenziós módokhoz használható aktuális dimenzió a segítségével érhető Interactable.CurrentDimension el.

Kezelhető profilok

A profilok olyan elemek, amelyek kapcsolatot hoznak létre egy GameObject és egy vizuális téma között. A profil határozza meg, hogy a téma milyen tartalmakat módosít, amikor állapotváltás történik.

A témák az anyagokhoz hasonlóan működnek. Ezek parancsfájlokkal használható objektumok, amelyek az adott objektumhoz az aktuális állapot alapján hozzárendelt tulajdonságok listáját tartalmazzák. A témák újra használhatók, és több Interakciós UX-objektumhoz is hozzárendelhetők.

Visszaállítás semmisíten meg

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 megsemmisítéskor értéke igaz, amikor a Kezelhető összetevőt megsemmisítik, az összetevő visszaállítja az összes módosított tulajdonságot az aktív témákból az eredeti értékekre. Ellenkező esetben az Interakcióra használható összetevő az összes módosított tulajdonságot meghagyja. Ebben az utóbbi esetben az értékek utolsó állapota megmarad, kivéve, ha egy másik külső összetevő módosította. Az alapértelmezett érték a false (hamis).

Profile theams

Események

Minden Kezelhető összetevő rendelkezik egy OnClick-eseményzel, amely akkor vált ki, amikor az összetevő egyszerűen ki van választva. A Interactable azonban használható az OnClicken kívül más bemeneti események észlelésére is.

Kattintson az Esemény hozzáadása gombra egy új típusú esemény fogadó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)

Különböző típusú esemény fogadók létezik, amelyek különböző típusú bemenetekre reagálnak. Az MRTK az alábbi, elsőre beállított fogadókkal rendelkezik.

Egyéni fogadó úgy is létrehozható, ha létrehoz egy új osztályt, amely kibővíti a ReceiverBase osztályt.

Event Toggle Receiver Example

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

Kezelhető fogadók

Az összetevő lehetővé teszi az események definiálát a forrásKént InteractableReceiver használható összetevőn kívül. A InteractableReceiver egy másik Interakciós eseménytípus által kibocsátott szűrt eseménytípust figyel. Ha a Kezelhető tulajdonság nincs közvetlenül hozzárendelve, akkor a Keresési hatókör tulajdonság határozza meg, hogy a InteractableReceiver milyen irányban figyelje az olyan eseményeket, amelyek magára, egy szülőre vagy egy gyermek GameObjectre terjednek ki.

InteractableReceiverList hasonlóan viselkedik, de a megfelelő események listáját tartalmazza.

Interactable reciver

Egyéni események létrehozása

A Vizuális témákhozhasonló események kiterjeszthetőek bármilyen állapotminta észlelése vagy funkciók elérhetővé teése érdekében.

Az egyéni események két fő módon létrehozhatóak:

  1. Terjessze ki a osztályt, és hozzon létre egy egyéni eseményt, amely megjelenik az eseménytípusok ReceiverBase 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óak, vagy az esemény beállítható úgy, hogy elrejtse a Unity-eseményeket. Ez a funkció lehetővé teszi, hogy a tervező egy projekten mérnökkel dolgozzon, és létrehoz egy egyéni eseményt, amit a tervező a szerkesztőben tud beállítani.

  2. Terjessze ki a osztályt egy teljesen egyéni eseményösszetevő létrehozásához, amely a Kommunikálható objektumon vagy ReceiverBaseMonoBehavior egy másik objektumon található. A ReceiverBaseMonoBehavior az Interakciós kapcsolatra hivatkozik az állapotváltozások észlelésére.

Példa bővítésre ReceiverBase

A osztály megjeleníti az Interakciós kapcsolat állapotinformációját, és egy példa egy egyéni esemény fogadó CustomInteractablesReceiver 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 metódusok akkor hasznosak, ha egyéni esemény fogadó létrehozásakor felül szeretné bírálni/implementálja a metódusokat. ReceiverBase.OnUpdate() A egy absztrakt metódus, amely az állapotminták/átmenetek észlelésére használható. Emellett a és metódusok akkor is hasznosak, ha egyéni eseménylogikát hoz létre, ha az ReceiverBase.OnVoiceCommand() ReceiverBase.OnClick() Interakciós elem 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 fogadómezőinek megjelenítése az inspectorban

A ReceiverBase-szkriptek InspectorField attribútumokkal fedik fel az egyéni tulajdonságokat az vizsgálóban. Példa a Vector3 egyéni tulajdonságra elemleírásokkal és címkeinformációval. Ez a tulajdonság konfigurálhatóként fog mutatni az vizsgálóban, ha egy Interactable GameObject van kiválasztva, és hozzáadja a társított esemény fogadótípust.

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

A Kezelhetők használata

Egyszerű gomb kiépítése

Létrehozhat egy egyszerű gombot, ha hozzáadja az Interakciós összetevőt egy GameObjecthez, amely a bemeneti események fogadására van konfigurálva. A bemenet fogadása egy collider vagy egy gyermek számára is lehet. Ha a Interactablet Unity UI-alapú GameObjectekkel használja, annak a Canvas GameObject alatt kell lennie.

Még egy lépéssel tovább adhatja a gombot: 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óként való használatához az PressableButton összetevőre van szükség. Emellett az összetevőre azért van szükség, hogy az Interakcióra alkalmas összetevőben tölcsérbe nyomják az PhysicalPressEventRouter eseményeket.

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

Váltógomb

Ha egy váltógombot váltógombot is használnia kell, módosítsa a mezőt Selection Mode a következőre: Toggle . A Profilok szakaszban egy új, váltógombos téma lesz hozzáadva minden olyan profilhoz, amely akkor használatos, amikor az Interakciós kapcsoló be van váltva.

Bár a váltógombra van állítva, az IsToggled jelölőnégyzet segítségével beállíthatja a vezérlő alapértelmezett értékét a SelectionMode futásidő inicializálásakor.

A CanSelect azt jelenti, hogy az Interakciós eszköz be- és kikapcsolható, míg a CanDeselect az inverz.

Példa a profiltémák váltógombra

A fejlesztők a és a felület használatával lekért vagy beállíthatnak egy Interakciós interakció állapotát SetToggled IsToggled 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ása

Gyakran van egy lista váltógombokról, ahol egyszerre csak egy lehet aktív, más néven radiális halmaz vagy választógomb.

A funkció InteractableToggleCollection engedélyezéséhez használja az ö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ű kezdőpont.

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

  1. Több interakcióra használható GameObjects/gomb létrehozása
  2. Állítsa be az egyes Interakciók a SelectionMode = Váltógombot, a CanSelect = true és a CanDeselect = false értékeket
  3. Hozzon létre egy üres gameObject szülőt az összes Interakciós elemhez, és adja hozzá a InteractableToggleCollection összetevőt
  4. Adja hozzá az összes Interactables et a ToggleList listához a InteractableToggleCollection (Interakciók)collection (Interakciók) gombra
  5. Állítsa be a InteractableToggleCollection.CurrentIndex tulajdonságot annak meghatározásához, hogy melyik gomb legyen 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 egy kettőnél több lépésből álló gomb létrehozására használható, például a sebesség szabályozása három értékkel, Gyors (1x), Gyorsabb (2x) vagy Leggyorsabb (3x).

Ha a dimenziók numerikus értékek, akár 9 téma is hozzáadható a gomb szövegcímkéje vagy textúra-mintázatának szabályozásához minden egyes sebességbeállításhoz, különböző téma használatával az egyes lépésekkel.

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

Példa többdimenziós profilra

A fejlesztők felmérik DimensionIndex a(z) et annak meghatározásához, 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();

Kezelhető létrehozása futásidőben

A kezelhető bármely GameObjecthez egyszerűen hozzáadható futásidőben. Az alábbi példa bemutatja, hogyan rendelhet hozzá egy profiltémával.

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

Kezelhető események kóddal

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

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

A függvény Interactable.AddReceiver<T>() használatával dinamikusan adhat hozzá esemény fogadókat futásidőben.

Az alábbi példakód bemutatja, hogyan adhat hozzá egy InteractableOnFocusReceiverkódot, amely figyel az enter/exit fókuszra, valamint meghatározza az eseménypéldányok eloltáskor végrehajtani szükséges műveletkó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 InteractableOnToggleReceiverkódot, amely a kiválasztott/nem kijelölt állapotváltásokat figyeli a váltóval használható Interakciós műveletek esetén, továbbá meghatározza az eseménypéldányok oltásakor végrehajtani szükséges műveletkó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