Bagikan melalui


Dapat berinteraksi — MRTK2

Dapat berinteraksi

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:

  1. Konfigurasi input umum
  2. Tema Visual yang ditargetkan terhadap beberapa GameObjects
  3. Penanganan aktivitas

Pengaturan input umum

Pengaturan Umum yang Dapat Berinteraksi

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.

Contoh Status ScriptableObject di inspektur

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

Profil theams

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.

Contoh peristiwa)

Ada berbagai jenis penerima peristiwa untuk merespons berbagai jenis input. MRTK dikirim dengan set penerima berikut out-of-box.

Penerima kustom dapat dibuat dengan membuat kelas baru yang memperluas ReceiverBase.

Contoh Penerima Pengalih Peristiwa

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.

Reciver yang dapat berinteraksi

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:

  1. 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.

  2. 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.

Contoh Tema Visual Pengalih Profil

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:

  1. Membuat beberapa Interactable GameObjects/buttons
  2. Atur setiap Interactable dengan SelectionMode = Toggle, CanSelect = true, dan CanDeselect = false
  3. Buat GameObject induk kosong di semua Interactables dan tambahkan komponen InteractableToggleCollection
  4. Menambahkan semua Interactables ke ToggleList pada InteractableToggleCollection
  5. Atur properti InteractableToggleCollection.CurrentIndex untuk menentukan tombol mana yang dipilih secara default di awal
Alihkan koleksi

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.

Contoh profil Multi-Dimensi

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

Lihat juga