Pointer — MRTK2

Penunjuk

Artikel ini menjelaskan cara mengonfigurasi dan menanggapi input Pointer dalam praktiknya. Untuk lebih memahami cara mengontrol beberapa pointer pada tingkat tinggi, lihat Arsitektur Pointer.

Pointer diinstansikan secara otomatis saat runtime ketika pengontrol baru terdeteksi. Lebih dari satu pointer dapat dilampirkan ke pengontrol. Misalnya, dengan profil penunjuk default, pengontrol Windows Mixed Reality mendapatkan garis dan penunjuk parabola untuk pemilihan normal dan teleportasi masing-masing.

Konfigurasi penunjuk

Pointer dikonfigurasi sebagai bagian dari Sistem Input di MRTK melalui MixedRealityPointerProfile. Jenis profil ini ditetapkan ke MixedRealityInputSystemProfile di pemeriksa Konfigurasi MRTK. Profil Pointer menentukan kursor, jenis Pointer yang tersedia saat runtime, dan bagaimana pointer tersebut berkomunikasi satu sama lain untuk memutuskan mana yang aktif.

  • Jangkauan Penunjuk - Menentukan jarak maksimum tempat Pointer dapat berinteraksi dengan GameObject.

  • Menunjuk Masker Lapisan Raycast - Ini adalah array LayerMasks yang diprioritaskan untuk menentukan kemungkinan GameObjects mana pun yang dapat berinteraksi dengan Pointer tertentu dan urutan interaksi untuk dicoba. Ini mungkin berguna untuk memastikan Pointer berinteraksi dengan elemen UI terlebih dahulu sebelum objek adegan lainnya. Contoh Profil Penunjuk

Konfigurasi opsi penunjuk

Konfigurasi Profil Pointer MRTK default mencakup kelas penunjuk berikut dan prefab terkait di luar kotak. Daftar penunjuk yang tersedia untuk sistem saat runtime ditentukan di bawah Opsi Penunjuk di profil Pointer. Pengembang dapat menggunakan daftar ini untuk mengonfigurasi ulang Pointer yang ada, menambahkan Pointer baru, atau menghapusnya.

Contoh Profil Opsi Pointer

Setiap entri Pointer ditentukan oleh kumpulan data berikut:

  • Jenis Pengontrol - Kumpulan pengontrol yang valid untuk penunjuk.

    • Misalnya, PokePointer bertanggung jawab untuk "menusuk" objek dengan jari, dan secara default ditandai sebagai hanya mendukung jenis pengontrol tangan artikulasi. Pointer hanya dibuat ketika pengontrol tersedia dan khususnya Jenis Pengontrol menentukan pengontrol apa yang dapat dibuat dengan prefab pointer ini.
  • Handedness - memungkinkan penunjuk hanya dibuat untuk tangan tertentu (kiri/kanan)

Catatan

Mengatur properti Handedness dari entri Pointer ke None akan secara efektif menonaktifkannya dari sistem sebagai alternatif untuk menghapus Pointer tersebut dari daftar.

  • Prefab Pointer - Aset prefab ini akan dibuat ketika pengontrol yang cocok dengan jenis pengontrol dan keserangan yang ditentukan mulai dilacak.

Dimungkinkan untuk memiliki beberapa pointer yang terkait dengan pengontrol. Misalnya, dalam DefaultHoloLens2InputSystemProfile (Aset/MRTK/SDK/Profil/HoloLens2/) pengontrol tangan artikulasi dikaitkan dengan PokePointer, GrabPointer, dan DefaultControllerPointer (yaitu sinar tangan).

Catatan

MRTK menyediakan serangkaian prefab pointer di Aset/MRTK/SDK/Features/UX/Prefabs/Pointers. Prefab kustom baru dapat dibangun selama berisi salah satu skrip pointer di Aset/MRTK/SDK/Features/UX/Scripts/Pointers atau skrip lain yang mengimplementasikan IMixedRealityPointer.

Konfigurasi kursor

Kursor Tatapan dapat dikonfigurasi secara langsung melalui GazeCursorPrefab properti di MixedRealityInputSystemProfile dalam Editor. Untuk mengonfigurasi kursor yang digunakan untuk pointer lain, Anda perlu mengubah prefab yang digunakan di CursorPrefab bidang yang sesuai BaseControllerPointer. Untuk mengubah kursor secara terprogram, ubah BaseCursor properti pada perilaku yang IMixedRealityPointer sesuai.

Properti Prefab Kursor

Lihat prefab kursor kami di Aset/MRTK/SDK/Fitur/UX/Prefabs/Kursor misalnya implementasi perilaku kursor. Secara khusus, DefaultGazeCursor memberikan implementasi yang kuat untuk mengubah grafik kursor berdasarkan status kontekstual.

Kelas penunjuk default

Kelas berikut adalah pointer MRTK out-of-box yang tersedia dan ditentukan dalam Profil Pointer MRTK default yang diuraikan di atas. Setiap prefab pointer yang disediakan di bawah Aset/MRTK/SDK/Features/UX/Prefabs/Pointers berisi salah satu komponen pointer yang terpasang.

Pointer Default MRTK

Penunjuk jauh

LinePointer

LinePointer, kelas penunjuk dasar, menggambar garis dari sumber input (yaitu pengontrol) ke arah penunjuk dan mendukung satu transmisi sinar ke arah ini. Umumnya, kelas anak-anak seperti ShellHandRayPointer dan pointer teleportasi dibuat dan digunakan (yang juga menggambar garis untuk menunjukkan di mana teleportasi akan berakhir di) alih-alih kelas ini yang terutama menyediakan fungsionalitas umum.

Untuk pengontrol gerakan seperti di Oculus, Vive, dan Windows Mixed Reality, rotasi akan cocok dengan rotasi pengontrol. Untuk pengontrol lain seperti tangan artikulasi HoloLens 2, rotasi cocok dengan pose penunjuk tangan yang disediakan sistem.

Garis Penunjuk MRTK
CurvePointer

CurvePointer memperluas kelas LinePointer dengan memungkinkan transmisi sinar multi-langkah di sepanjang kurva. Kelas penunjuk dasar ini berguna untuk instans melengkung seperti penunjuk teleportasi di mana garis secara konsisten membungkuk ke dalam parabola.

ShellHandRayPointer

Implementasi ShellHandRayPointer, yang meluas dari LinePointer, digunakan sebagai default untuk Profil Pointer MRTK. Prefab DefaultControllerPointer mengimplementasikan ShellHandRayPointer kelas .

GGVPointer

Juga dikenal sebagai penunjuk Tatapan/Gerakan/Suara (GGV ), GGVPointer mendukung interaksi tampilan dan ketuk gaya HoloLens 1, terutama melalui Tatapan dan Ketukan Udara atau Tatapan dan interaksi Pilih suara. Posisi dan arah penunjuk GGV didorong oleh posisi dan rotasi kepala.

TouchPointer

TouchPointer bertanggung jawab untuk bekerja dengan input Unity Touch (yaitu layar sentuh). Ini adalah 'interaksi jauh' karena tindakan menyentuh layar akan mentransmisikan sinar dari kamera ke lokasi yang berpotensi jauh di adegan.

MousePointer

MousePointer mendukung raycast layar ke dunia untuk interaksi yang jauh, tetapi untuk mouse alih-alih sentuhan.

Penunjuk mouse

Catatan

Dukungan mouse tidak tersedia secara default di MRTK tetapi dapat diaktifkan dengan menambahkan Penyedia Data Input baru jenis MouseDeviceManager ke profil input MRTK dan menetapkan MixedRealityMouseInputProfile ke penyedia data.

Penunjuk dekat

PokePointer

PokePointer digunakan untuk berinteraksi dengan objek game yang mendukung "interaksi dekat yang dapat disentuh." yang merupakan GameObjects yang memiliki skrip terlampir NearInteractionTouchable . Dalam kasus UnityUI, pointer ini mencari NearInteractionTouchableUnityUIs. PokePointer menggunakan SphereCast untuk menentukan elemen terdekat yang dapat disentuh dan digunakan untuk memberi daya seperti tombol yang dapat ditekan.

Saat mengonfigurasi GameObject dengan NearInteractionTouchable komponen, pastikan untuk mengonfigurasi parameter localForward untuk mengarahkan keluar dari bagian depan tombol atau objek lain yang harus dibuat dapat disentuh. Pastikan juga bahwa batas yang dapat disentuh cocok dengan batas objek yang dapat disentuh.

Properti Poke Pointer yang berguna:

  • TouchableDistance: Jarak maksimum di mana permukaan yang dapat disentuh dapat berinteraksi dengan
  • Visual: Objek game yang digunakan untuk merender visual ujung jari (cincin di jari, secara default).
  • Garis: Garis opsional untuk menggambar dari ujung jari ke permukaan input aktif.
  • Poke Layer Masks - Array LayerMasks yang diprioritaskan untuk menentukan kemungkinan GameObjects mana yang dapat berinteraksi dengan pointer dan urutan interaksi untuk dicoba. Perhatikan bahwa GameObject juga harus memiliki NearInteractionTouchable komponen untuk berinteraksi dengan pointer poke.
Poke Pointer
SpherePointer

SpherePointer menggunakan UnityEngine.Physics.OverlapSphere untuk mengidentifikasi objek terdekat NearInteractionGrabbable untuk interaksi, yang berguna untuk input "dapat diambil" seperti ManipulationHandler. Mirip PokePointer/NearInteractionTouchable dengan pasangan fungsi, agar dapat berinteraksi dengan Sphere Pointer, objek game harus berisi komponen yang merupakan NearInteractionGrabbable skrip.

Penunjuk Ambil

Properti Sphere Pointer yang Berguna:

  • Sphere Cast Radius: Radius untuk bola yang digunakan untuk mengkueri objek yang dapat diambil.
  • Dekat Margin Objek: Jarak di atas Sphere Cast Radius untuk dikueri untuk mendeteksi apakah objek berada di dekat penunjuk. Total radius deteksi Objek Dekat adalah Sphere Cast Radius + Near Object Margin
  • Dekat Sudut Sektor Objek: Sudut di sekitar sumbu maju penunjuk untuk kueri objek terdekat. IsNearObject Membuat fungsi kueri seperti kerujut. Ini diatur ke 66 derajat secara default untuk mencocokkan perilaku Hololens 2

Penunjuk sphere dimodifikasi hanya untuk kueri untuk objek dalam arah maju

  • Dekat Object Smoothing Factor: Faktor smoothing untuk deteksi Near Object. Jika objek terdeteksi di Radius Objek Dekat, radius yang dikueri kemudian menjadi Near Object Radius * (1 + Near Object Smoothing Factor) untuk mengurangi sensitivitas dan mempersulit objek untuk meninggalkan rentang deteksi.
  • Grab Layer Masks - Array LayerMasks yang diprioritaskan untuk menentukan kemungkinan GameObjects mana yang dapat berinteraksi dengan penunjuk dan urutan interaksi untuk dicoba. Perhatikan bahwa GameObject juga harus memiliki NearInteractionGrabbable untuk berinteraksi dengan SpherePointer.

    Catatan

    Lapisan Kesadaran Spasial dinonaktifkan dalam prefab GrabPointer default yang disediakan oleh MRTK. Ini dilakukan untuk mengurangi dampak performa melakukan kueri tumpang tindih bola dengan jala spasial. Anda dapat mengaktifkan ini dengan memodifikasi prefab GrabPointer.

  • Abaikan Colliders Tidak di FOV - Apakah akan mengabaikan collider yang mungkin berada di dekat pointer, tetapi tidak benar-benar dalam visual FOV. Ini dapat mencegah penangkapan yang tidak disengaja, dan akan memungkinkan sinar tangan menyala ketika Anda mungkin berada di dekat grabbable tetapi tidak dapat melihatnya. Visual FOV didefinisikan melalui kerucut alih-alih frustum khas karena alasan performa. Kerucut ini berpusat dan berorientasi sama dengan frustum kamera dengan radius sama dengan tinggi layar setengah (atau FOV vertikal).
Penunjuk Bola

Penunjuk teleport

  • TeleportPointer akan menaikkan permintaan teleportasi ketika tindakan diambil (yaitu tombol teleportasi ditekan) untuk memindahkan pengguna.
  • ParabolicTeleportPointer akan menaikkan permintaan teleportasi ketika tindakan diambil (yaitu tombol teleportasi ditekan) dengan raycast garis parabolik untuk memindahkan pengguna.
Parabolik Penunjuk

Dukungan pointer untuk platform realitas campuran

Tabel berikut merinci jenis penunjuk yang biasanya digunakan untuk platform umum di MRTK. CATATAN: Dimungkinkan untuk menambahkan berbagai jenis pointer ke platform ini. Misalnya, Anda dapat menambahkan penunjuk Poke atau penunjuk Sphere ke VR. Selain itu, perangkat VR dengan gamepad dapat menggunakan pointer GGV.

Penunjuk OpenVR Realitas Campuran Windows HoloLens 1 HoloLens 2
ShellHandRayPointer Valid Valid Valid
TeleportPointer Valid Valid
GGVPointer Valid
SpherePointer Valid
PokePointer Valid

Interaksi pointer melalui kode

Antarmuka peristiwa penunjuk

MonoBehaviours yang mengimplementasikan satu atau beberapa antarmuka berikut dan ditetapkan ke GameObject dengan Collider akan menerima peristiwa interaksi Pointer seperti yang didefinisikan oleh antarmuka terkait.

Kejadian Deskripsi Penghandel
Sebelum Fokus Berubah / Fokus Berubah Dinaikkan pada objek permainan kehilangan fokus dan yang mendapatkannya setiap kali pointer mengubah fokus. IMixedRealityFocusChangedHandler
Fokus Masukkan / Keluar Dimunculkan pada objek game yang mendapatkan fokus ketika pointer pertama memasukinya dan pada yang kehilangan fokus ketika pointer terakhir meninggalkannya. IMixedRealityFocusHandler
Pointer Down / Dragged / Up / Clicked Dinaikkan ke penunjuk laporan tekan, seret dan lepaskan. IMixedRealityPointerHandler
Sentuh Dimulai / Diperbarui / Selesai Dibesarkan oleh penunjuk sadar sentuh suka PokePointer melaporkan aktivitas sentuh. IMixedRealityTouchHandler

Catatan

IMixedRealityFocusChangedHandler dan IMixedRealityFocusHandler harus ditangani dalam objek tempat objek dinaikkan. Dimungkinkan untuk menerima peristiwa fokus secara global tetapi, tidak seperti peristiwa input lainnya, penanganan aktivitas global tidak akan memblokir penerimaan peristiwa berdasarkan fokus (peristiwa akan diterima oleh handler global dan objek yang sesuai dalam fokus).

Peristiwa input penunjuk sedang beraksi

Peristiwa input pointer dikenali dan ditangani oleh sistem input MRTK dengan cara yang sama seperti peristiwa input reguler. Perbedaannya adalah bahwa peristiwa input pointer hanya ditangani oleh GameObject dalam fokus oleh penunjuk yang menembakkan peristiwa input, serta penangan input global. Peristiwa input reguler ditangani oleh GameObjects sebagai fokus untuk semua pointer aktif.

  1. Sistem input MRTK mengenali peristiwa input telah terjadi
  2. Sistem input MRTK mengaktifkan fungsi antarmuka yang relevan untuk peristiwa input ke semua handler input global yang terdaftar
  3. Sistem input menentukan GameObject mana yang menjadi fokus untuk penunjuk yang menembakkan peristiwa
    1. Sistem input menggunakan Sistem Peristiwa Unity untuk mengaktifkan fungsi antarmuka yang relevan untuk semua komponen yang cocok pada GameObject yang berfokus
    2. Jika pada titik mana pun peristiwa input telah ditandai sebagai digunakan, proses akan berakhir dan tidak ada GameObjects lebih lanjut yang akan menerima panggilan balik.
      • Contoh: Komponen yang mengimplementasikan antarmuka IMixedRealityFocusHandler akan dicari untuk keuntungan GameObject atau kehilangan fokus
      • Catatan: Unity Event System akan menggelembung untuk mencari Induk GameObject jika tidak ada komponen yang cocok dengan antarmuka yang diinginkan yang ditemukan pada GameObject saat ini..
  4. Jika tidak ada penangan input global yang terdaftar dan tidak ada GameObject yang ditemukan dengan komponen/antarmuka yang cocok, maka sistem input akan memanggil setiap penangan input terdaftar fallback

Contoh

Di bawah ini adalah contoh skrip yang mengubah warna perender terlampir saat pointer mengambil atau meninggalkan fokus atau saat penunjuk memilih objek.

public class ColorTap : MonoBehaviour, IMixedRealityFocusHandler, IMixedRealityPointerHandler
{
    private Color color_IdleState = Color.cyan;
    private Color color_OnHover = Color.white;
    private Color color_OnSelect = Color.blue;
    private Material material;

    private void Awake()
    {
        material = GetComponent<Renderer>().material;
    }

    void IMixedRealityFocusHandler.OnFocusEnter(FocusEventData eventData)
    {
        material.color = color_OnHover;
    }

    void IMixedRealityFocusHandler.OnFocusExit(FocusEventData eventData)
    {
        material.color = color_IdleState;
    }

    void IMixedRealityPointerHandler.OnPointerDown(
         MixedRealityPointerEventData eventData) { }

    void IMixedRealityPointerHandler.OnPointerDragged(
         MixedRealityPointerEventData eventData) { }

    void IMixedRealityPointerHandler.OnPointerClicked(MixedRealityPointerEventData eventData)
    {
        material.color = color_OnSelect;
    }
}

Penunjuk kueri

Dimungkinkan untuk mengumpulkan semua pointer yang saat ini aktif dengan mengulangi sumber input yang tersedia (yaitu pengontrol dan input yang tersedia) untuk menemukan pointer mana yang melekat padanya.

var pointers = new HashSet<IMixedRealityPointer>();

// Find all valid pointers
foreach (var inputSource in CoreServices.InputSystem.DetectedInputSources)
{
    foreach (var pointer in inputSource.Pointers)
    {
        if (pointer.IsInteractionEnabled && !pointers.Contains(pointer))
        {
            pointers.Add(pointer);
        }
    }
}

Penunjuk utama

Pengembang dapat berlangganan peristiwa FocusProviders PrimaryPointerChanged untuk diberi tahu ketika penunjuk utama dalam fokus telah berubah. Ini bisa sangat berguna untuk mengidentifikasi apakah pengguna saat ini berinteraksi dengan adegan melalui tatapan atau sinar tangan atau sumber input lain.

private void OnEnable()
{
    var focusProvider = CoreServices.InputSystem?.FocusProvider;
    focusProvider?.SubscribeToPrimaryPointerChanged(OnPrimaryPointerChanged, true);
}

private void OnPrimaryPointerChanged(IMixedRealityPointer oldPointer, IMixedRealityPointer newPointer)
{
    ...
}

private void OnDisable()
{
    var focusProvider = CoreServices.InputSystem?.FocusProvider;
    focusProvider?.UnsubscribeFromPrimaryPointerChanged(OnPrimaryPointerChanged);

    // This flushes out the current primary pointer
    OnPrimaryPointerChanged(null, null);
}

Adegan PrimaryPointerExample (Aset/MRTK/Contoh/Demo/Input/Adegan/PrimaryPointer) menunjukkan cara menggunakan PrimaryPointerChangedHandler untuk peristiwa untuk merespons penunjuk utama baru.

Contoh Penunjuk Utama

Hasil pointer

Properti penunjuk Result berisi hasil saat ini untuk kueri adegan yang digunakan untuk menentukan objek dengan fokus. Untuk pointer raycast, seperti yang dibuat secara default untuk pengontrol gerakan, input tatapan dan sinar tangan, itu akan berisi lokasi dan normal hit raycast.

private void IMixedRealityPointerHandler.OnPointerClicked(MixedRealityPointerEventData eventData)
{
    var result = eventData.Pointer.Result;
    var spawnPosition = result.Details.Point;
    var spawnRotation = Quaternion.LookRotation(result.Details.Normal);
    Instantiate(MyPrefab, spawnPosition, spawnRotation);
}

Adegan PointerResultExample (Assets/MRTK/Examples/Demos/Input/Scenes/PointerResult/PointerResultExample.unity) menunjukkan cara menggunakan pointer Result untuk menelurkan objek di lokasi hit.

Hasil Pointer

Menonaktifkan penunjuk

Untuk mengaktifkan dan menonaktifkan penunjuk (misalnya, untuk menonaktifkan sinar tangan), atur PointerBehavior untuk jenis pointer tertentu melalui PointerUtils.

// Disable the hand rays
PointerUtils.SetHandRayPointerBehavior(PointerBehavior.AlwaysOff);

// Disable hand rays for the right hand only
PointerUtils.SetHandRayPointerBehavior(PointerBehavior.AlwaysOff, Handedness.Right);

// Disable the gaze pointer
PointerUtils.SetGazePointerBehavior(PointerBehavior.AlwaysOff);

// Set the behavior to match HoloLens 1
// Note, if on HoloLens 2, you must configure your pointer profile to make the GGV pointer show up for articulated hands.
public void SetHoloLens1()
{
    PointerUtils.SetPokePointerBehavior(PointerBehavior.AlwaysOff, Handedness.Any);
    PointerUtils.SetGrabPointerBehavior(PointerBehavior.AlwaysOff, Handedness.Any);
    PointerUtils.SetRayPointerBehavior(PointerBehavior.AlwaysOff, Handedness.Any);
    PointerUtils.SetGGVBehavior(PointerBehavior.Default);
}

Lihat PointerUtils dan TurnPointersOnOff untuk contoh selengkapnya.

Interaksi penunjuk melalui editor

Untuk peristiwa pointer yang ditangani oleh IMixedRealityPointerHandler, MRTK memberikan kenyamanan lebih lanjut dalam bentuk PointerHandler komponen, yang memungkinkan peristiwa pointer ditangani langsung melalui Unity Events.

Penangan Penunjuk

Tingkat penunjuk

Pointer yang jauh memiliki pengaturan yang membatasi seberapa jauh mereka akan raycast dan berinteraksi dengan objek lain di adegan. Secara default, nilai ini diatur ke 10 meter. Nilai ini dipilih untuk tetap konsisten dengan perilaku shell HoloLens.

Ini dapat diubah dengan memperbarui DefaultControllerPointer bidang komponen prefab ShellHandRayPointer :

Pointer Extent - Ini mengontrol jarak maksimum yang akan berinteraksi dengan pointer.

Jangkauan Pointer Default - Ini mengontrol panjang sinar/garis penunjuk yang akan merender saat penunjuk tidak berinteraksi dengan apa pun.

Lihat juga