Dapat berinteraksi — MRTK2
Komponen Interactable
adalah kontainer all-in-one untuk membuat objek apa pun mudah berinteraksi dan responsif terhadap input. Interactable bertindak sebagai catch-all untuk semua jenis input termasuk sentuhan, sinar tangan, ucapan, dll dan menyalurkan interaksi ini ke dalam peristiwa dan respons tema visual . Komponen ini menyediakan cara mudah untuk membuat tombol, mengubah warna pada objek dengan fokus, dan banyak lagi.
Cara mengonfigurasi Interactable
Komponen ini memungkinkan tiga bagian utama konfigurasi:
- Konfigurasi input umum
- Tema Visual yang ditargetkan terhadap beberapa GameObjects
- Penanganan aktivitas
Pengaturan input umum
Negara
Status adalah parameter ScriptableObject yang menentukan fase interaksi, seperti tekan atau diamati, untuk Profil yang Dapat Berinteraksi dan Tema Visual.
DefaultInteractableStates (Assets/MRTK/SDK/Features/UX/Interactable/States/DefaultInteractableStates.asset) dikirim dengan MRTK out-of-box dan merupakan parameter default untuk komponen Yang dapat berinteraksi.
Aset DefaultInteractableStates berisi empat status dan menggunakan InteractableStates
implementasi model status.
Default: Tidak ada yang terjadi, ini adalah status dasar yang paling terisolasi.
Fokus: Objek sedang ditujuk. Ini adalah status tunggal, tidak ada status lain yang saat ini ditetapkan, tetapi akan keluar peringkat Default.
Tekan: Objek sedang diarahkan dan tombol atau tangan ditekan. Status Tekan keluar memberi peringkat Default dan Fokus. Status ini juga akan ditetapkan sebagai fallback ke Physical Press.
Dinonaktifkan: Tombol tidak boleh interaktif dan umpan balik visual akan memberi tahu pengguna jika karena alasan tertentu tombol ini tidak dapat digunakan saat ini. Secara teori, status yang dinonaktifkan dapat berisi semua status lain, tetapi ketika Diaktifkan dinonaktifkan, status Dinonaktifkan meniru semua status lainnya.
Nilai bit (#) ditetapkan ke status tergantung pada urutan dalam daftar.
Catatan
Umumnya disarankan untuk menggunakan DefaultInteractableStates (Assets/MRTK/SDK/Features/UX/Interactable/States/DefaultInteractableStates.asset) saat membuat komponen Interactable .
Namun, ada 17 status Yang dapat berinteraksi yang tersedia yang dapat digunakan untuk mendorong tema, meskipun beberapa dimaksudkan untuk didorong oleh komponen lain. Berikut adalah daftar yang memiliki fungsionalitas bawaan.
- Dikunjungi: Interactable telah diklik.
- Dialihkan: Tombol dalam keadaan beralih atau Indeks dimensi adalah angka ganjil.
- Gerakan: Tangan atau pengontrol ditekan dan telah bergerak dari posisi asli.
- VoiceCommand: Perintah ucapan digunakan untuk memicu Interactable.
- PhysicalTouch: Input sentuhan saat ini terdeteksi, gunakan
NearInteractionTouchable
untuk mengaktifkan. - Grab: Tangan saat ini meraih di batas objek, gunakan
NearInteractionGrabbable
untuk mengaktifkan
Aktif
Mengalihkan apakah Interactable akan mulai diaktifkan atau tidak. Ini sesuai dengan Interactable.IsEnabled
dalam kode.
Properti yang diaktifkan Interactable berbeda dari properti yang diaktifkan yang dikonfigurasi melalui GameObject/Component (yaitu SetActive dll). Menonaktifkan GameObject atau Interactable MonoBehaviour akan menonaktifkan semua yang ada di kelas agar tidak berjalan termasuk input, tema visual, peristiwa, dll. Menonaktifkan melalui Interactable.IsEnabled
akan menonaktifkan sebagian besar penanganan input, mengatur ulang status input terkait. Namun, kelas akan tetap menjalankan setiap bingkai dan menerima peristiwa input yang akan diabaikan. Ini berguna untuk menampilkan Interactable dalam status dinonaktifkan yang dapat dilakukan melalui Tema Visual. Contoh umum dari ini adalah tombol kirim menunggu semua bidang input yang diperlukan selesai.
Tindakan Input
Pilih tindakan input dari konfigurasi input atau profil pemetaan pengontrol yang harus bereaksi terhadap komponen Dapat berinteraksi .
Properti ini dapat dikonfigurasi pada runtime dalam kode melalui Interactable.InputAction
.
Isglobal
Jika true, ini akan menandai komponen sebagai pendengar input global untuk tindakan input yang dipilih. Perilaku default adalah false yang akan membatasi input hanya ke collider/GameObject yang dapat berinteraksi ini.
Properti ini dapat dikonfigurasi pada runtime dalam kode melalui Interactable.IsGlobal
.
Perintah Ucapan
Perintah Ucapan, dari Profil Perintah Ucapan MRTK, untuk memicu peristiwa OnClick untuk interaksi suara.
Properti ini dapat dikonfigurasi pada runtime dalam kode melalui Interactable.VoiceCommand
.
Membutuhkan Fokus
Jika true, perintah suara hanya akan mengaktifkan Interactable jika dan hanya jika sudah memiliki fokus dari pointer. Jika false, maka Interactable akan bertindak sebagai pendengar global untuk perintah suara yang dipilih. Perilaku defaultnya benar, karena beberapa pendengar ucapan global bisa sulit diatur dalam adegan.
Properti ini dapat dikonfigurasi pada runtime dalam kode melalui Interactable.VoiceRequiresFocus
.
Mode Pemilihan
Properti ini mendefinisikan logika pemilihan. Saat Dapat berinteraksi diklik, itu berulang ke tingkat Dimensi berikutnya.
Dimensi mirip dengan peringkat dan mendefinisikan status di luar input (yaitu fokus, tekan dll). Mereka berguna untuk mendefinisikan status Toggle atau status multi-peringkat lainnya yang terkait dengan tombol. Tingkat Dimensi saat ini dilacak oleh Interactable.DimensionIndex
.
Mode pemilihan yang tersedia adalah:
- Tombol - Dimensi = 1, mudah diklik Dapat diklik Dapat Berinteraksi
- Beralih - Dimensi = 2, Dapat berinteraksi bergantian antara status aktif/nonaktif
- Multi-dimensi - Dimensi>= 3, setiap klik meningkatkan tingkat dimensi saat ini + 1. Berguna untuk menentukan status tombol ke daftar, dll.
Dapat berinteraksi juga memungkinkan beberapa Tema ditentukan per Dimensi. Misalnya ketika SelectionMode=Toggle, satu tema dapat diterapkan saat Interactable tidak dipilih dan tema lain diterapkan saat komponen dipilih.
Mode Pilihan saat ini dapat dikueri saat runtime melalui Interactable.ButtonMode
. Memperbarui mode saat runtime dapat dicapai dengan mengatur Interactable.Dimensions
properti agar sesuai dengan fungsionalitas yang diinginkan. Selain itu, dimensi saat ini, berguna untuk mode Toggle dan Multi-Dimension , dapat diakses melalui Interactable.CurrentDimension
.
Profil yang dapat berinteraksi
Profil adalah item yang membuat hubungan antara GameObject dan Tema Visual. Profil menentukan konten apa yang akan dimanipulasi oleh tema ketika perubahan status terjadi.
Tema bekerja sangat mirip bahan. Mereka adalah objek yang dapat ditulis yang berisi daftar properti yang akan ditetapkan ke objek berdasarkan status saat ini. Tema juga dapat digunakan kembali dan dapat ditetapkan di beberapa objek UX yang dapat berinteraksi .
Reset Saat Dihancurkan
Tema visual memodifikasi berbagai properti pada GameObject yang ditargetkan, tergantung pada kelas dan jenis mesin tema yang dipilih. Jika Reset Saat Dihancurkan benar ketika komponen Dapat berinteraksi dihancurkan, komponen akan mengatur ulang semua properti yang dimodifikasi dari tema aktif ke nilai aslinya. Jika tidak, ketika dihancurkan, komponen Dapat berinteraksi akan meninggalkan properti yang dimodifikasi apa adanya. Dalam kasus terakhir ini, status nilai terakhir akan bertahan kecuali diubah oleh komponen eksternal lain. Defaultnya adalah false (salah).
Acara
Setiap komponen Interactable memiliki peristiwa OnClick yang diaktifkan ketika komponen hanya dipilih. Namun, Interactable dapat digunakan untuk mendeteksi peristiwa input selain hanya OnClick.
Klik tombol Tambahkan Peristiwa untuk menambahkan jenis definisi Penerima Peristiwa baru. Setelah ditambahkan, pilih jenis Peristiwa yang diinginkan.
)
Ada berbagai jenis penerima peristiwa untuk merespons berbagai jenis input. MRTK dikirim dengan set penerima berikut out-of-box.
InteractableAudioReceiver
InteractableOnClickReceiver
InteractableOnFocusReceiver
InteractableOnGrabReceiver
InteractableOnHoldReceiver
InteractableOnPressReceiver
InteractableOnToggleReceiver
InteractableOnTouchReceiver
Penerima kustom dapat dibuat dengan membuat kelas baru yang memperluas ReceiverBase
.
Contoh Pengalih Penerima Peristiwa
Penerima yang dapat berinteraksi
Komponen InteractableReceiver
memungkinkan peristiwa didefinisikan di luar komponen Dapat berinteraksi sumber.
InteractableReceiver akan mendengarkan jenis peristiwa yang difilter yang diaktifkan oleh Interactable lain. Jika properti Interactable tidak secara langsung ditetapkan, maka properti Search Scope menentukan arah InteractableReceiver mendengarkan peristiwa yang berada di dirinya sendiri, di induk, atau di GameObject anak.
InteractableReceiverList
bertindak dengan cara yang sama tetapi untuk daftar peristiwa yang cocok.
Membuat peristiwa kustom
Seperti Tema Visual, peristiwa dapat diperluas untuk mendeteksi pola status apa pun atau untuk mengekspos fungsionalitas.
Peristiwa kustom dapat dibuat dengan dua cara utama:
ReceiverBase
Perluas kelas untuk membuat peristiwa kustom yang akan muncul di daftar dropdown jenis peristiwa. Peristiwa Unity disediakan secara default, tetapi peristiwa Unity tambahan dapat ditambahkan atau peristiwa dapat diatur untuk menyembunyikan peristiwa Unity. Fungsionalitas ini memungkinkan perancang untuk bekerja dengan teknisi pada proyek untuk membuat peristiwa kustom yang dapat disiapkan perancang di editor.ReceiverBaseMonoBehavior
Perluas kelas untuk membuat komponen peristiwa kustom sepenuhnya yang dapat berada di objek Dapat berinteraksi atau objek lain.ReceiverBaseMonoBehavior
akan mereferensikan Interactable untuk mendeteksi perubahan status.
Contoh perluasan ReceiverBase
Kelas CustomInteractablesReceiver
menampilkan informasi status tentang Interactable dan merupakan contoh cara membuat Penerima Peristiwa kustom.
public CustomInteractablesReceiver(UnityEvent ev) : base(ev, "CustomEvent")
{
HideUnityEvents = true; // hides Unity events in the receiver - meant to be code only
}
Metode berikut berguna untuk mengambil alih/menerapkan saat membuat Penerima Peristiwa kustom.
ReceiverBase.OnUpdate()
adalah metode abstrak yang dapat digunakan untuk mendeteksi pola/transisi status. Selain itu, ReceiverBase.OnVoiceCommand()
metode dan ReceiverBase.OnClick()
berguna untuk membuat logika peristiwa kustom saat Interactable dipilih.
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
}
Menampilkan bidang penerima peristiwa kustom di inspektur
Skrip ReceiverBase menggunakan InspectorField
atribut untuk mengekspos properti kustom di inspektur. Berikut adalah contoh Vector3, properti kustom dengan tipsalat dan informasi label. Properti ini akan muncul sebagai dapat dikonfigurasi di inspektur ketika Interactable GameObject dipilih dan memiliki jenis Event Receiver terkait yang ditambahkan.
[InspectorField(Label = "<Property label>",Tooltip = "<Insert tooltip info>",Type = InspectorField.FieldTypes.Vector3)]
public Vector3 EffectOffset = Vector3.zero;
Cara menggunakan Interactable
Membangun tombol sederhana
Seseorang dapat membuat tombol sederhana dengan menambahkan komponen Interactable ke GameObject yang dikonfigurasi untuk menerima peristiwa input. Ini dapat memiliki collider di atasnya atau pada anak untuk menerima input. Jika menggunakan Interactable dengan GameObjects berbasis Unity UI, itu harus berada di bawah Canvas GameObject.
Ambil tombol satu langkah lebih jauh, dengan membuat profil baru, menetapkan GameObject itu sendiri dan membuat tema baru. Selain itu, gunakan peristiwa OnClick untuk membuat sesuatu terjadi.
Catatan
Membuat tombol dapat ditekan memerlukan PressableButton
komponen. Selain itu, PhysicalPressEventRouter
komponen diperlukan untuk menyalurkan peristiwa pers ke komponen Dapat berinteraksi .
Membuat tombol alih dan multi-dimensi
Tombol alih
Untuk membuat tombol Toggle-able, ubah Selection Mode
bidang untuk mengetik Toggle
. Di bagian Profil , tema baru yang dialihkan ditambahkan untuk setiap profil yang digunakan saat Interactable diaktifkan.
SelectionMode
Saat diatur ke Alihkan, kotak centang IsToggled dapat digunakan untuk mengatur nilai default kontrol saat inisialisasi runtime.
CanSelect berarti Interactable dapat hidup dari ke aktif sementara CanDeselect berarti terbalik.
Pengembang dapat menggunakan SetToggled
antarmuka dan IsToggled
untuk mendapatkan/mengatur status toggle dari Interactable melalui kode.
// 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;
Alihkan kumpulan tombol
Adalah umum untuk memiliki daftar tombol pengalih di mana hanya satu yang dapat aktif pada waktu tertentu, juga dikenal sebagai set radial atau tombol radio dll.
InteractableToggleCollection
Gunakan komponen untuk mengaktifkan fungsionalitas ini. Kontrol ini memastikan hanya satu Interactable yang diaktifkan pada waktu tertentu.
RadialSet (Aset/MRTK/SDK/Features/UX/Interactable/Prefabs/RadialSet.prefab) juga merupakan titik awal yang bagus di luar kotak.
Untuk membuat grup tombol radial kustom:
- Membuat beberapa Interactable GameObjects/buttons
- Atur setiap Interactable dengan SelectionMode = Toggle, CanSelect = true, dan CanDeselect = false
- Buat GameObject induk kosong di semua Interactables dan tambahkan komponen InteractableToggleCollection
- Menambahkan semua Interactables ke ToggleList pada InteractableToggleCollection
- Atur properti InteractableToggleCollection.CurrentIndex untuk menentukan tombol mana yang dipilih secara default di awal
Tombol multi-dimensi
Mode pemilihan Multi-Dimensi digunakan untuk membuat tombol berurutan, atau tombol yang memiliki lebih dari dua langkah, seperti mengontrol kecepatan dengan tiga nilai, Cepat (1x), Lebih Cepat (2x) atau Tercepat (3x).
Dengan dimensi menjadi nilai numerik, hingga 9 tema dapat ditambahkan untuk mengontrol label teks atau tekstur tombol untuk setiap pengaturan kecepatan, menggunakan tema yang berbeda untuk setiap langkah.
Setiap peristiwa klik akan memajukan DimensionIndex
1 saat runtime hingga Dimensions
nilai tercapai. Kemudian siklus akan direset ke 0.
Pengembang dapat menilai DimensionIndex
untuk menentukan dimensi mana yang saat ini aktif.
// 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();
Membuat Interactable saat runtime
Dapat berinteraksi dapat dengan mudah ditambahkan ke GameObject apa pun saat runtime. Contoh berikut menunjukkan cara menetapkan profil dengan tema visual.
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()
Peristiwa yang dapat berinteraksi melalui kode
Seseorang dapat menambahkan tindakan ke peristiwa dasar Interactable.OnClick
melalui kode dengan contoh berikut.
public static void AddOnClick(Interactable interactable)
{
interactable.OnClick.AddListener(() => Debug.Log("Interactable clicked"));
}
Interactable.AddReceiver<T>()
Gunakan fungsi untuk menambahkan penerima peristiwa secara dinamis saat runtime.
Contoh kode di bawah ini menunjukkan cara menambahkan InteractableOnFocusReceiver, yang mendengarkan fokus enter/exit, dan selanjutnya menentukan kode tindakan untuk dilakukan saat instans peristiwa diaktifkan.
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"));
}
Contoh kode di bawah ini menunjukkan cara menambahkan InteractableOnToggleReceiver, yang mendengarkan transisi status yang dipilih/tidak dipilih pada Interactables yang dapat dialihkan, dan selanjutnya menentukan kode tindakan yang akan dilakukan saat instans peristiwa diaktifkan.
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"));
}