İşaretçiler — MRTK2
Bu makalede, uygulamada İşaretçi girişini yapılandırma ve yanıtlama açıklanmaktadır. Birden çok işaretçinin üst düzeyde nasıl denetlendiğini daha iyi anlamak için bkz . İşaretçi Mimarisi.
İşaretçiler, yeni bir denetleyici algılandığında çalışma zamanında otomatik olarak örneklenir. Bir denetleyiciye birden fazla işaretçi eklenebilir. Örneğin, varsayılan işaretçi profiliyle, Windows Mixed Reality denetleyicileri sırasıyla normal seçim ve ışınlanma için hem çizgi hem de parabolik bir işaretçi alır.
İşaretçi yapılandırması
İşaretçiler, bir aracılığıyla MRTK'daki Giriş Sisteminin bir MixedRealityPointerProfile
parçası olarak yapılandırılır. Bu profil türü MRTK Yapılandırma denetçisinde öğesine MixedRealityInputSystemProfile
atanır. İşaretçi profili imleci, çalışma zamanında kullanılabilen İşaretçi türlerini ve hangisinin etkin olduğuna karar vermek için bu işaretçilerin birbirleriyle nasıl iletişim kuracaklarını belirler.
İşaret Kapsamı - İşaretçinin GameObject ile etkileşim kurabileceği maksimum uzaklığı tanımlar.
Raycast Katman Maskelerini İşaret Etme - Bu, belirli bir İşaretçinin hangi olası GameObject'lerle etkileşim kurabileceğini ve etkileşim sırasını belirlemeye yönelik öncelikli bir LayerMask dizisidir. Bu, İşaretçilerin diğer sahne nesnelerinden önce kullanıcı arabirimi öğeleriyle etkileşim kurmasını sağlamak için yararlı olabilir.
İşaretçi seçenekleri yapılandırması
Varsayılan MRTK İşaretçi Profili yapılandırması aşağıdaki işaretçi sınıflarını ve ilişkili hazır gelen önkoşulları içerir. Çalışma zamanında sistem tarafından kullanılabilen işaretçilerin listesi, İşaretçi profilindeki İşaretçi Seçenekleri altında tanımlanır. Geliştiriciler mevcut İşaretçileri yeniden yapılandırmak, yeni İşaretçiler eklemek veya bir tane silmek için bu listeyi kullanabilir.
Her İşaretçi girişi aşağıdaki veri kümesi tarafından tanımlanır:
Denetleyici Türü - İşaretçinin geçerli olduğu denetleyici kümesi.
- Örneğin , PokePointer nesneleri parmakla "dürtmekten" sorumludur ve varsayılan olarak yalnızca ifade edilmiş el denetleyicisi türünü destekliyor olarak işaretlenir. İşaretçiler yalnızca bir denetleyici kullanılabilir olduğunda oluşturulur ve özellikle Denetleyici Türü bu işaretçinin hangi denetleyicilerle oluşturulabileceğini tanımlar.
Handness - bir işaretçinin yalnızca belirli bir el için örneklenmesini sağlar (sol/sağ)
Not
İşaretçi girişinin Handedness özelliğini Yok olarak ayarlamak, bu İşaretçiyi listeden kaldırmaya alternatif olarak bunu sistemden etkin bir şekilde devre dışı bırakır.
- İşaretçi Prefab - Belirtilen denetleyici türü ve ileticiliğiyle eşleşen bir denetleyici izlenmeye başladığında bu prefab varlığın örneği oluşturulacaktır.
Bir denetleyiciyle ilişkili birden çok işaretçi olması mümkündür. Örneğin, DefaultHoloLens2InputSystemProfile
(Assets/MRTK/SDK/Profiles/HoloLens2/) içinde, ifade edilen el denetleyicisi PokePointer, GrabPointer ve DefaultControllerPointer (el ışınları) ile ilişkilendirilir.
Not
MRTK , Varlıklar/MRTK/SDK/Özellikler/UX/Prefabs/İşaretçiler'de bir dizi işaretçi ön koşul sağlar. Varlıklar/MRTK/SDK/Özellikler/UX/Betikler/İşaretçiler veya uygulayan IMixedRealityPointer
diğer betiklerde işaretçi betiklerinden birini içerdiği sürece yeni bir özel ön bildirim oluşturulabilir.
İmleç yapılandırması
Bakış imleci, Düzenleyici'nin GazeCursorPrefab
içindeki özelliği MixedRealityInputSystemProfile
aracılığıyla doğrudan yapılandırılabilir. Diğer işaretçiler için kullanılan imleci yapılandırmak için, ilgili BaseControllerPointer
alanında kullanılan CursorPrefab
prefabrik değeri değiştirmeniz gerekir. İmleci programlı olarak değiştirmek için ilgili davranışta BaseCursor
IMixedRealityPointer
özelliğini değiştirin.
İmleç davranışının uygulamaları için Varlıklar/MRTK/SDK/Özellikler/UX/Prefabs/İmleçler'deki imleç ön uygulamalarımıza bakın. Özellikle DefaultGazeCursor , bağlamsal duruma göre imlecin grafiğini değiştirmenin güçlü bir uygulamasını sağlar.
Varsayılan işaretçi sınıfları
Aşağıdaki sınıflar, yukarıda özetlenen varsayılan MRTK İşaretçi Profilinde tanımlanan kullanıma hazır MRTK işaretçileridir . Varlıklar/MRTK/SDK/Özellikler/UX/Prefabs/İşaretçiler altında sağlanan her işaretçi önceden hazırlanmış öğesi, ekli işaretçi bileşenlerinden birini içerir.
Uzak işaretçiler
LinePointer
Bir temel işaretçi sınıfı olan LinePointer, işaretçi yönünde girişin kaynağından (yani denetleyici) bir çizgi çizer ve bu yönde tek bir ışın atamasını destekler. Genel olarak, ve ışınlama işaretçileri gibi alt sınıflar, öncelikli olarak ShellHandRayPointer
ortak işlevler sağlayan bu sınıf yerine örneklenir ve kullanılır (ışınlanmanın nereye varacağını belirtmek için çizgiler çizer).
Oculus, Vive ve Windows Mixed Reality gibi hareket denetleyicileri için döndürme, denetleyicinin dönüşüyle eşleşecektir. HoloLens 2 ifade edilmiş eller gibi diğer denetleyiciler için döndürme, elin sistem tarafından sağlanan işaret duruşuyla eşleşir.
CurvePointer
CurvePointer , bir eğri boyunca çok adımlı ışın atamalarına izin vererek LinePointer sınıfını genişletir. Bu temel işaretçi sınıfı, çizginin sürekli olarak bir parabolaya büküldüğü ışınlama işaretçileri gibi eğri örnekler için kullanışlıdır.
ShellHandRayPointer
'den LinePointer
genişletilen ShellHandRayPointer uygulaması, MRTK İşaretçi Profili için varsayılan olarak kullanılır. DefaultControllerPointer prefab sınıfını ShellHandRayPointer
uygular.
GGVPointer
Bakış/Hareket/Ses (GGV) işaretçisi olarak da bilinen GGVPointer, HoloLens'in öncelikle Bakış ve Hava Dokunuşu veya Bakış ve ses Seçimi etkileşimi aracılığıyla 1 stilde görünüm ve dokunma etkileşimlerini çalıştırır. GGV işaretçisinin konumu ve yönü, başın konumu ve döndürmesi tarafından yönlendirilir.
TouchPointer
TouchPointer, Unity Touch girişi (dokunmatik ekran) ile çalışmaktan sorumludur. Bunlar 'uzak etkileşimler', çünkü ekrana dokunma eylemi kameradan sahnenin uzak olabilecek bir konumuna bir ışın atacaktır.
MousePointer
MousePointer, uzak etkileşimler için, ancak dokunma yerine fare için bir ekranı dünya raycast'a çalıştırır.
Not
MRTK'de fare desteği varsayılan olarak kullanılamaz, ancak MRTK giriş profiline türünde yeni bir Giriş Veri SağlayıcısıMouseDeviceManager
eklenip veri sağlayıcısına atanarak MixedRealityMouseInputProfile
etkinleştirilebilir.
İşaretçilerin yakınında
PokePointer
PokePointer, "neredeyse etkileşime dokunılabilir" destekleyen oyun nesneleriyle etkileşim kurmak için kullanılır. ekli NearInteractionTouchable
betiği olan GameObject'lerdir. UnityUI söz konusu olduğunda, bu işaretçi NearInteractionTouchableUnityUIs öğesini arar. PokePointer, en yakın dokunılabilir öğeyi belirlemek için bir SphereCast kullanır ve basılabilir düğmeler gibi şeyleri desteklemek için kullanılır.
GameObject'i bileşenle NearInteractionTouchable
yapılandırırken, localForward parametresini düğmenin veya dokunulabilir hale getirilecek diğer nesnenin önüne işaret eden şekilde yapılandırdığınızdan emin olun. Ayrıca, dokunılabilir sınırların , dokunılabilir nesnenin sınırlarıyla eşleştiğinden emin olun.
Yararlı Dürtme İşaretçisi özellikleri:
- TouchableDistance: Dokunmatik bir yüzeyin etkileşime geçebileceği maksimum uzaklık
- Görseller: Parmak ucu görselini işlemek için kullanılan oyun nesnesi (varsayılan olarak parmak üzerindeki halka).
- Çizgi: Parmak ucundan etkin giriş yüzeyine çizmek için isteğe bağlı çizgi.
- Katman Maskelerini Dürt - İşaretçinin hangi olası GameObject'lerle etkileşim kurabileceğini ve etkileşim sırasını belirlemeye yönelik öncelikli bir LayerMasks dizisi. Bir GameObject'in bir dürtme işaretçisiyle etkileşim kurmak için bir
NearInteractionTouchable
bileşeni de olması gerektiğini unutmayın.
SpherePointer
SpherePointer, etkileşim için en NearInteractionGrabbable
yakın nesneyi tanımlamak için UnityEngine.Physics.OverlapSphere kullanır. Bu, gibi ManipulationHandler
"yakalanabilir" giriş için kullanışlıdır. İşlev çiftine PokePointer
/NearInteractionTouchable
benzer şekilde, Sphere İşaretçisi ile etkileşime geçmek için oyun nesnesi betik olan NearInteractionGrabbable
bir bileşen içermelidir.
Yararlı Sphere İşaretçisi özellikleri:
- Küre Atama Yarıçapı: Kaplanabilir nesneleri sorgulamak için kullanılan kürenin yarıçapı.
- Nesne Kenar Boşluğuna Yakın: Bir nesnenin işaretçiye yakın olup olmadığını algılamak için sorgulama yapmak için Sphere Atama Yarıçapı'nın üstündeki uzaklık. Total Near Object detection radius is Sphere Cast Radius + Near Object Margin
- Nesne Kesimi Açısının Yakınında: Yakındaki nesneleri sorgulamak için işaretçinin ileri ekseni etrafındaki açı. Sorgu işlevini
IsNearObject
bir koni gibi yapar. Bu, Hololens 2 davranışıyla eşleşecek şekilde varsayılan olarak 66 dereceye ayarlanır
- NesneYe Yakın Düzeltme Faktörü: NesneYe Yakın algılama için düzeltme faktörü. Yakın Nesne Yarıçapı'nda bir nesne algılanırsa sorgulanan yarıçap, duyarlılığı azaltmak ve bir nesnenin algılama aralığından ayrılmasını zorlaştırmak için Nesne Yarıçapına Yakın * (1 + NesneYe Yakın Düzeltme Faktörü) olur.
- Katman Maskelerini Al - İşaretçinin hangi olası GameObject'lerle etkileşim kurabileceğini ve etkileşim sırasını belirlemek için öncelikli bir LayerMasks dizisi. Bir GameObject'in SpherePointer ile etkileşime geçmek için de bir değeri
NearInteractionGrabbable
olması gerektiğini unutmayın.Not
Uzamsal Farkındalık katmanı, MRTK tarafından sağlanan varsayılan GrabPointer önfabrikinde devre dışı bırakılmıştır. Bu, uzamsal ağ ile küre çakışması sorgusu gerçekleştirmenin performans etkisini azaltmak için yapılır. GrabPointer prefabını değiştirerek bunu etkinleştirebilirsiniz.
- Harmanlayıcıları Yoksay FOV'de Değil - İşaretçiye yakın olan ancak aslında görsel FOV'de olmayan harmanlayıcıların yoksayılıp yoksayılmayacağı. Bu, yanlışlıkla kapmayı önleyebilir ve bir kapılabilirin yakınında olduğunuzda ancak göremediğiniz durumlarda el ışınlarının açmasına izin verir. Visual FOV, performans nedenleriyle tipik frustum yerine koni aracılığıyla tanımlanır. Bu koni ortalanmış ve yarım ekran yüksekliğine (veya dikey FOV) eşit yarıçapa sahip kameranın frustum'ıyla aynı şekilde yönlendirilir.
ışınlayıcı işaretçileri
TeleportPointer
, kullanıcıyı taşımak için eylem gerçekleştirildiğinde (yani ışınla düğmesine basıldığında) bir ışınlanan istek oluşturur.ParabolicTeleportPointer
, kullanıcıyı taşımak için bir parabolik çizgi raycast ile eylem gerçekleştirildiğinde (yani ışınla düğmesine basıldığında) bir ışın isteği oluşturur.
Karma gerçeklik platformları için işaretçi desteği
Aşağıdaki tabloda, MRTK'daki yaygın platformlar için genellikle kullanılan işaretçi türleri ayrıntılı olarak açıklanıyor. NOT: Bu platformlara farklı işaretçi türleri eklemek mümkündür. Örneğin, VR'ye bir Poke işaretçisi veya Sphere işaretçisi ekleyebilirsiniz. Buna ek olarak, oyun yüzeyi olan VR cihazları GGV işaretçisini kullanabilir.
İşaretçi | OpenVR | Windows Mixed Reality | HoloLens 1 | HoloLens 2 |
---|---|---|---|---|
ShellHandRayPointer | Geçerli | Geçerli | Geçerli | |
TeleportPointer | Geçerli | Geçerli | ||
GGVPointer | Geçerli | |||
SpherePointer | Geçerli | |||
PokePointer | Geçerli |
Kod aracılığıyla işaretçi etkileşimleri
İşaretçi olayı arabirimleri
Aşağıdaki arabirimlerden birini veya daha fazlasını uygulayan ve ile bir GameObject'e Collider
atanan MonoBehaviours, ilişkili arabirim tarafından tanımlanan İşaretçi etkileşimleri olaylarını alır.
Olay | Description | İşleyici |
---|---|---|
Odak Değiştirilmeden Önce / Odak Değiştirilmeden Önce | Hem odağı kaybeden oyun nesnesine hem de işaretçi odağı her değiştirişinde bu nesneye sahip olan nesneye yükseltildi. | IMixedRealityFocusChangedHandler |
Odak Enter / Çıkış | İlk işaretçi girdiğinde odak kazanan oyun nesnesine ve son işaretçi ayrıldığında odağı kaybeden nesneye yükseltilir. | IMixedRealityFocusHandler |
İşaretçi Aşağı / Sürüklenmiş / Yukarı / Tıklanmış | Rapor işaretçisine yükseltildi tuşuna basın, sürükleyin ve bırakın. | IMixedRealityPointerHandler |
Dokunmatik Başlatıldı / Güncelleştirildi / Tamamlandı | Dokunma etkinliğini raporlamak gibi PokePointer dokunarak algılayan işaretçiler tarafından yükseltildi. |
IMixedRealityTouchHandler |
Not
IMixedRealityFocusChangedHandler
ve IMixedRealityFocusHandler
üzerinde yükseltildikleri nesnelerde işlenmelidir. Odak olaylarını genel olarak almak mümkündür, ancak diğer giriş olaylarının aksine, genel olay işleyicisi odağı temel alan olayları engellemez (olay hem genel işleyici hem de odaktaki ilgili bir nesne tarafından alınır).
İşaretçi giriş olayları iş başında
İşaretçi giriş olayları MRTK giriş sistemi tarafından normal giriş olaylarıyla benzer şekilde tanınır ve işlenir. İşaretçi giriş olaylarının yalnızca, giriş olayını tetikleyen işaretçi ve genel giriş işleyicileri tarafından odaktaki GameObject tarafından işlenmesi farktır. Normal giriş olayları, tüm etkin işaretçiler için odaktaki GameObjects tarafından işlenir.
- MRTK giriş sistemi bir giriş olayının gerçekleştiğini algılar
- MRTK giriş sistemi, giriş olayı için ilgili arabirim işlevini tüm kayıtlı genel giriş işleyicilerine tetikler
- Giriş sistemi, olayı tetikleyen işaretçi için hangi GameObject'in odakta olduğunu belirler
- Giriş sistemi, Unity'nin Olay Sistemi'ni kullanarak odaklanmış GameObject'te eşleşen tüm bileşenler için ilgili arabirim işlevini tetikler
- Herhangi bir noktada bir giriş olayı kullanıldı olarak işaretlendiyse, işlem sona erer ve başka GameObjects geri çağırma almaz.
- Örnek: Arabirimi
IMixedRealityFocusHandler
uygulayan bileşenler GameObject kazançları veya odağı kaybeder için aranacak - Not: Unity Olay Sistemi, geçerli GameObject'te istenen arabirimle eşleşen hiçbir bileşen bulunamazsa üst GameObject'te arama yapmak için kabarcık oluşturur..
- Örnek: Arabirimi
- Hiçbir genel giriş işleyicisi kaydedilmezse ve eşleşen bir bileşen/arabirim ile GameObject bulunmazsa, giriş sistemi her geri dönüş kayıtlı giriş işleyicisini çağırır
Örnek
Aşağıda, işaretçi odağı aldığında veya bıraktığında ya da işaretçi nesneyi seçtiğinde ekli işleyicinin rengini değiştiren örnek bir betik verilmiştir.
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;
}
}
Sorgu işaretçileri
Kullanılabilir giriş kaynakları (örn. denetleyiciler ve kullanılabilir girişler) arasında döngü yaparak etkin durumdaki tüm işaretçileri toplamak mümkündür ve bunlara hangi işaretçilerin eklendiğini keşfedebilirsiniz.
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);
}
}
}
Birincil işaretçi
Geliştiriciler odaktaki birincil işaretçi değiştiğinde bildirim almak için FocusProviders PrimaryPointerChanged olayına abone olabilir. Bu, kullanıcının bakış veya el ışını ya da başka bir giriş kaynağı aracılığıyla bir sahneyle etkileşimde olup olmadığını belirlemek için son derece yararlı olabilir.
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);
}
PrimaryPointerExample
(Assets/MRTK/Examples/Demos/Input/Scenes/PrimaryPointer) sahnesi, olayların yeni bir birincil işaretçiye yanıt vermek için nasıl kullanılacağını PrimaryPointerChangedHandler
gösterir.
İşaretçi sonucu
işaretçi Result
özelliği, odaklı nesneyi belirlemek için kullanılan sahne sorgusunun geçerli sonucunu içerir. Hareket denetleyicileri, bakış girişi ve el ışınları için varsayılan olarak oluşturulanlar gibi bir raycast işaretçisi için, raycast isabetinin konumunu ve normalini içerir.
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);
}
Sahne PointerResultExample
(Assets/MRTK/Examples/Demos/Input/Scenes/PointerResult/PointerResultExample.unity) işaretçiyi Result
kullanarak bir nesneyi isabet konumunda nasıl oluşturacaklarını gösterir.
İşaretçileri devre dışı bırakma
İşaretçileri etkinleştirmek ve devre dışı bırakmak için (örneğin, el ışınını devre dışı bırakmak için), üzerinden PointerUtils
verilen işaretçi türünün değerini ayarlayınPointerBehavior
.
// 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);
}
Daha fazla örnek için bkz PointerUtils
. ve TurnPointersOnOff
.
Düzenleyici aracılığıyla işaretçi etkileşimleri
tarafından IMixedRealityPointerHandler
işlenen işaretçi olayları için MRTK, bileşen biçiminde daha fazla kolaylık sağlar ve bu da işaretçi olaylarının PointerHandler
doğrudan Unity Olayları aracılığıyla işlenmesini sağlar.
İşaretçi kapsamı
Uzak işaretçiler, sahnedeki diğer nesnelerle ne kadar uzağa ışınlanacaklarını ve etkileşim kuracaklarını sınırlayan ayarlara sahiptir. Varsayılan olarak, bu değer 10 metre olarak ayarlanır. Bu değer HoloLens kabuğunun davranışıyla tutarlı kalmak için seçilmiştir.
Bu, prefabrik ShellHandRayPointer
bileşenin DefaultControllerPointer
alanları güncelleştirilerek değiştirilebilir:
İşaretçi Kapsamı - Bu, işaretçilerin etkileşim kuracağı maksimum uzaklığı denetler.
Varsayılan İşaretçi Kapsamı - Bu, işaretçi hiçbir şeyle etkileşim kurmadığında işlenecek işaretçi ışınının/çizginin uzunluğunu denetler.