Kezelhető – MRTK2
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é:
- Általános bemeneti konfiguráció
- Több GameObjectre célzott vizuális témák
- Eseménykezelők
Általános beviteli beállítások
Á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.
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.DimensionIndex
tö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.

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.
)
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.
InteractableAudioReceiver
InteractableOnClickReceiver
InteractableOnFocusReceiver
InteractableOnGrabReceiver
InteractableOnHoldReceiver
InteractableOnPressReceiver
InteractableOnToggleReceiver
InteractableOnTouchReceiver
Egyéni fogadót úgy hozhat létre, hogy létrehoz egy új, kibővíthető osztályt ReceiverBase
.
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.

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:
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.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ó. AReceiverBaseMonoBehavior
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 Mode
Toggle
. 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.
A fejlesztők használhatják a SetToggled
IsToggled
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:
- Több interaktív GameObjects/gomb létrehozása
- A SelectionMode = Váltógomb, a CanSelect = true és a CanDeselect = false értékek mindegyikének beállítása
- Hozzon létre egy üres szülő GameObjectet az összes interakciós elemhez, és adja hozzá az InteractableToggleCollection összetevőt
- Az összes interakciós elem hozzáadása a ToggleList elemhez az InteractableToggleCollection elemen
- Á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

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