Aracılığıyla paylaş


MR Giriş 213: Hareket denetleyicileri

Not

Karma Gerçeklik Academy öğreticileri HoloLens (1. nesil) ve Karma Gerçeklik Immersive Headsets düşünülerek tasarlanmıştır. Bu nedenle, bu cihazlar için geliştirme konusunda hala rehberlik arayan geliştiriciler için bu öğreticileri yerinde bırakmanın önemli olduğunu hissediyoruz. Bu öğreticiler, HoloLens 2 için kullanılan en son araç kümeleri veya etkileşimlerle güncelleştirilmez. Desteklenen cihazlarda çalışmaya devam etmek için bakımları yapılır. HoloLens 2 için yeni bir öğretici serisi yayınlanmıştır.

Karma gerçeklik dünyasındaki hareket denetleyicileri başka bir etkileşim düzeyi daha ekler. Hareket denetleyicileriyle, gerçek hayattaki fiziksel etkileşimlerimize benzer şekilde nesnelerle doğrudan daha doğal bir şekilde etkileşim kurarak uygulama deneyiminize daha fazla daldırma ve keyif verebiliriz.

MR Input 213'te basit bir uzamsal boyama deneyimi oluşturarak hareket denetleyicisinin giriş olaylarını keşfedeceğiz. Bu uygulamayla, kullanıcılar çeşitli fırça ve renk türleriyle üç boyutlu alanda boyama yapabilir.

Bu öğreticide ele alınan konular

MixedReality213 Konu1 MixedReality213 Konu2 MixedReality213 Konu3
Denetleyici görselleştirmesi Denetleyici giriş olayları Özel denetleyici ve kullanıcı arabirimi
Unity'nin oyun modunda ve çalışma zamanında hareket denetleyicisi modellerini işlemeyi öğrenin. Farklı türlerdeki düğme olaylarını ve bunların uygulamalarını anlayın. Kullanıcı arabirimi öğelerini denetleyicinin üzerine bindirmeyi veya tam olarak özelleştirmeyi öğrenin.

Cihaz desteği

Kurs HoloLens Çevreleyici kulaklıklar
MR Giriş 213: Hareket denetleyicileri ✔️

Başlamadan önce

Önkoşullar

Bu sayfadaki çevreleyici mikrofonlu kulaklıklar için yükleme denetim listesine bakın.

Proje dosyaları

Not

İndirmeden önce kaynak kodu incelemek isterseniz GitHub'da kullanılabilir.

Unity kurulumu

Hedefler

  • Unity'i Windows Mixed Reality geliştirme için iyileştirme
  • Kamera Karma Gerçeklik Kurulumu
  • Kurulum ortamı

Yönergeler

  • Unity'i başlatın.

  • ’ı seçin.

  • Masaüstünüze gidin ve daha önce arşivlediğiniz MixedReality213-master klasörünü bulun.

  • Klasör Seç’e tıklayın.

  • Unity proje dosyalarını yüklemeyi tamamladıktan sonra Unity düzenleyicisini görebilirsiniz.

  • Unity'de Dosya > Derleme Ayarları'nı seçin.

    MR213_BuildSettings

  • Platformlistesinden Evrensel Windows Platformu seçin ve Platform Değiştir düğmesine tıklayın.

  • Hedef Cihazı Herhangi bir cihaz olarak ayarlama

  • Derleme Türünü D3D olarak ayarlama

  • SDK'yı En Son Yüklü olarak ayarlama

  • Unity C# Projelerini Denetleme

    • Bu, Unity projesini yeniden oluşturmadan Visual Studio projesindeki betik dosyalarını değiştirmenize olanak tanır.
  • Player Ayarları'nı tıklatın.

  • Denetçi panelinde aşağı kaydırarak en alta gelin

  • XR Ayarları'nda Sanal Gerçeklik Desteği'ne bakın

  • Sanal Gerçeklik SDK'ları'nın altında Windows Mixed Reality

    MR213_XRSettings

  • Derleme Ayarları penceresini kapatın.

Proje yapısı

Bu öğreticide Karma Gerçeklik Toolkit - Unity kullanılır. Sürümleri bu sayfada bulabilirsiniz.

ProjectStructure

Başvurunuz için tamamlanmış sahneler

  • Sahneler klasörünün altında tamamlanmış iki Unity sahnesi bulacaksınız.
    • MixedReality213: Tek fırça ile tamamlanmış sahne
    • MixedReality213Gelişmiş: Birden çok fırçayla gelişmiş tasarım için tamamlanmış sahne

Öğretici için yeni Sahne kurulumu

  • Unity'de Dosya > Yeni Sahne'ye tıklayın

  • Ana Kamerayı ve Yön Işığını Sil

  • Proje panelinden aşağıdaki önkoşulları arayın ve Hiyerarşi paneline sürükleyin:

    • Assets/HoloToolkit/Input/Prefabs/MixedRealityCamera
    • Varlıklar/AppPrefabs/Ortam

    Kamera ve Ortam

  • Karma Gerçeklik Toolkit'te iki ön kamera vardır:

    • MixedRealityCamera.prefab: Yalnızca kamera
    • MixedRealityCameraParent.prefab: Kamera + ışınlanma + Sınır
    • Bu öğreticide ışınlanma özelliği olmadan MixedRealityCamera kullanacağız. Bu nedenle, kullanıcının topraklanmış hissetmesini sağlamak için temel bir zemin içeren basit Ortam ön donanımı ekledik.
    • MixedRealityCameraParent ile ışınlanma hakkında daha fazla bilgi edinmek için bkz. Gelişmiş tasarım - ışınlanma ve lokomosyon

Skybox kurulumu

  • Pencere Aydınlatma > Ayarları'nı > tıklatın

  • Skybox Malzeme alanının sağ tarafındaki daireye tıklayın

  • 'gray' yazın ve SkyboxGray (Assets/AppPrefabs/Support/Materials/SkyboxGray.mat) öğesini seçin

    Skybox'ın ayarlanması

  • Atanan gri gradyan skybox'ı görebilmek için Skybox seçeneğini işaretleyin

    Skybox seçeneğini değiştirme

  • MixedRealityCamera, Environment ve gri skybox'ın sahnesi şöyle görünür.

    MixedReality213 Ortamı

  • Dosya > Görünümü Farklı Kaydet'e tıklayın

  • Sahnenizi herhangi bir adla Sahneler klasörünün altına kaydedin

1. Bölüm - Denetleyici görselleştirmesi

Hedefler

  • Unity'nin oyun modunda ve çalışma zamanında hareket denetleyicisi modellerini işlemeyi öğrenin.

Windows Mixed Reality, denetleyici görselleştirmesi için animasyonlu bir denetleyici modeli sağlar. Uygulamanızda denetleyici görselleştirmesi için kullanabileceğiniz çeşitli yaklaşımlar vardır:

  • Varsayılan - Varsayılan denetleyiciyi değiştirmeden kullanma
  • Karma - Varsayılan denetleyiciyi kullanma, ancak bazı öğelerini özelleştirme veya UI bileşenlerini katmanlama
  • Değiştirme - Denetleyici için kendi özelleştirilmiş 3B modelinizi kullanma

Bu bölümde, bu denetleyici özelleştirmelerinin örnekleri hakkında bilgi edineceğiz.

Yönergeler

  • Proje panelinde, arama kutusuna MotionControllers yazın. Varlıklar/HoloToolkit/Input/Prefabs/ altında da bulabilirsiniz.
  • MotionControllers prefab'ını Hiyerarşi paneline sürükleyin.
  • Hiyerarşi panelinde MotionControllers prefab öğesine tıklayın.

MotionControllers prefab

MotionControllers prefab, alternatif denetleyici modelleri için yuvalar sağlayan bir MotionControllerVisualizer betiğine sahiptir. El veya kılıç gibi kendi özel 3B modellerinizi atar ve 'Her Zaman Alternatif Sol/Sağ Modeli Kullan' seçeneğini belirlerseniz, bunları varsayılan model yerine görürsünüz. Bu yuvayı Bölüm 4'te denetleyici modelini fırçayla değiştirmek için kullanacağız.

MR213_ControllerVisualizer

Yönergeler

  • Denetçi panelinde, Visual Studio'da kodu görmek için MotionControllerVisualizer betiğine çift tıklayın

MotionControllerVisualizer betiği

MotionControllerVisualizer ve MotionControllerInfo sınıfları, varsayılan denetleyici modellerine erişmek & değiştirmek için araçlar sağlar. MotionControllerVisualizer Unity'nin InteractionSourceDetected olayına abone olur ve bulunduğunda denetleyici modellerini otomatik olarak başlatır.

protected override void Awake()
{
    ...
    InteractionManager.InteractionSourceDetected += InteractionManager_InteractionSourceDetected;
    InteractionManager.InteractionSourceLost += InteractionManager_InteractionSourceLost;
    ...
}

Denetleyici modelleri glTF belirtimine göre teslim edilir. Bu biçim, ortak bir biçim sağlamak için oluşturulurken, 3B varlıkların iletilmesi ve paketten çıkarılma sürecini geliştirir. Bu durumda, kullanıcının deneyimini olabildiğince sorunsuz hale getirmek istediğimiz için denetleyici modellerini çalışma zamanında alıp yüklememiz gerekir ve kullanıcının hangi hareket denetleyicileri sürümünü kullanacağı garanti değildir. Bu kurs, Karma Gerçeklik Araç Seti aracılığıyla Khronos Grubu'nun UnityGLTF projesinin bir sürümünü kullanır.

Denetleyici teslim edildikten sonra betikler, belirli denetleyici öğelerinin dönüşümlerini bulmak için MotionControllerInfo kullanabilir ve böylece kendilerini doğru bir şekilde konumlandırabilir.

Sonraki bir bölümde, denetleyicilere kullanıcı arabirimi öğeleri eklemek için bu betiklerin nasıl kullanılacağını öğreneceğiz.

Bazı betiklerde , #if ! UNITY_EDITOR veya UNITY_WSA. Bu kod blokları yalnızca Windows'a dağıttığınızda UWP çalışma zamanında çalışır. Bunun nedeni Unity düzenleyicisi ve UWP uygulama çalışma zamanı tarafından kullanılan API kümesinin farklı olmasıdır.

  • Sahneyi kaydedin ve yürüt düğmesine tıklayın.

Mikrofonlu kulaklığınızda hareket denetleyicileriyle sahneyi görebilirsiniz. Düğme tıklamaları, kontrol çubuğu hareketi ve dokunmatik yüzey dokunmatik vurgulama için ayrıntılı animasyonlar görebilirsiniz.

MR213_Controller Görselleştirme Varsayılanı

2. Bölüm - Kullanıcı arabirimi öğelerini denetleyiciye ekleme

Hedefler

  • Hareket denetleyicilerinin öğeleri hakkında bilgi edinin
  • Denetleyicilerin belirli bölümlerine nesne eklemeyi öğrenin

Bu bölümde, kullanıcının istediği zaman kolayca erişebileceği ve işleyebileceği denetleyiciye kullanıcı arabirimi öğeleri eklemeyi öğreneceksiniz. Dokunmatik yüzey girişini kullanarak basit bir renk seçici kullanıcı arabirimi eklemeyi de öğreneceksiniz.

Yönergeler

  • Proje panelinde MotionControllerInfo betiğini arayın.
  • Visual Studio'da kodu görmek için arama sonucunda MotionControllerInfo betiğine çift tıklayın.

MotionControllerInfo betiği

İlk adım, kullanıcı arabiriminin denetleyicinin hangi öğesine eklenmesini istediğinizi seçmektir. Bu öğeler, MotionControllerInfo.cs içindeki ControllerElementEnum içinde tanımlanır.

MR213 MotionControllerElements

  • Giriş Ekranı
  • Menü
  • Kavramak
  • Parmak çubuğu
  • Seç
  • Touchpad
  • İşaret etme pozu – Bu öğe denetleyicinin ileri yönü gösteren ucunu temsil eder.

Yönergeler

  • Proje panelinde AttachToController betiğini arayın.
  • Visual Studio'da kodu görmek için arama sonucunda AttachToController betiğine çift tıklayın.

AttachToController betiği

AttachToController betiği, herhangi bir nesneyi belirtilen denetleyicinin kullanımına ve öğesine eklemek için basit bir yol sağlar.

AttachElementToController() içinde,

  • MotionControllerInfo.Handedness kullanarak elle kullanım durumunu denetleme
  • MotionControllerInfo.TryGetElement() kullanarak denetleyicinin belirli bir öğesini alma
  • Öğenin dönüştürmesini denetleyici modelinden aldıktan sonra, altındaki nesneyi üst öğe yapın ve nesnenin yerel konumunu döndürme & sıfır olarak ayarlayın.
public MotionControllerInfo.ControllerElementEnum Element { get { return element; } }

private void AttachElementToController(MotionControllerInfo newController)
{
     if (!IsAttached && newController.Handedness == handedness)
     {
          if (!newController.TryGetElement(element, out elementTransform))
          {
               Debug.LogError("Unable to find element of type " + element + " under controller " + newController.ControllerParent.name + "; not attaching.");
               return;
          }

          controller = newController;

          SetChildrenActive(true);

          // Parent ourselves under the element and set our offsets
          transform.parent = elementTransform;
          transform.localPosition = positionOffset;
          transform.localEulerAngles = rotationOffset;
          if (setScaleOnAttach)
          {
               transform.localScale = scale;
          }

          // Announce that we're attached
          OnAttachToController();
          IsAttached = true;
     }
}

AttachToController betiğini kullanmanın en basit yolu, ColorPickerWheel örneğinde yaptığımız gibi bu betiğin devralınır. Denetleyici algılandığında / bağlantısı kesildiğinde kurulumunuzu / dökümünüzü gerçekleştirmek için OnAttachToController ve OnDetachFromController işlevlerini geçersiz kılmanız yeterlidir.

Yönergeler

  • Proje panelinde, ColorPickerWheel arama kutusuna yazın. Varlıklar/AppPrefabs/ altında da bulabilirsiniz.
  • ColorPickerWheel prefab öğesini Hiyerarşi paneline sürükleyin.
  • Hiyerarşi panelinde ColorPickerWheel prefab öğesine tıklayın.
  • Visual Studio'da kodu görmek için Denetçi panelinde ColorPickerWheel Betiği'ne çift tıklayın.

ColorPickerWheel prefab

ColorPickerWheel betiği

ColorPickerWheelAttachToController'ı devraldığından, Denetçi panelinde Handedness ve Element'i gösterir. Kullanıcı arabirimini sol denetleyicideki Touchpad öğesine ekleyeceğiz.

ColorPickerWheel betiği

ColorPickerWheel , dokunmatik yüzey girişiyle renk seçimi için bir sonraki bölümde kullanılacak olan giriş olayına abone olmak için OnAttachToController ve OnDetachFromController'ı geçersiz kılar.

public class ColorPickerWheel : AttachToController, IPointerTarget
{
    protected override void OnAttachToController()
    {
        // Subscribe to input now that we're parented under the controller
        InteractionManager.InteractionSourceUpdated += InteractionSourceUpdated;
    }

    protected override void OnDetachFromController()
    {
        Visible = false;

        // Unsubscribe from input now that we've detached from the controller
        InteractionManager.InteractionSourceUpdated -= InteractionSourceUpdated;
    }
    ...
}
  • Sahneyi kaydedin ve yürüt düğmesine tıklayın.

Nesneleri denetleyicilere eklemek için alternatif yöntem

Betiklerinizin AttachToController'dan devralmalarını ve OnAttachToController'ı geçersiz kılmalarını öneririz. Ancak, bu her zaman mümkün olmayabilir. Alternatif olarak bunu tek başına bir bileşen olarak kullanmak da kullanılabilir. Bu, betiklerinizi yeniden düzenlemeden mevcut bir prefab'ı bir denetleyiciye eklemek istediğinizde yararlı olabilir. Herhangi bir kurulum gerçekleştirmeden önce sınıfınızın IsAttached'in true olarak ayarlanmasını beklemesi yeterlidir. Bunu yapmanın en basit yolu 'Başlat' için bir eş yordam kullanmaktır.

private IEnumerator Start() {
    AttachToController attach = gameObject.GetComponent<AttachToController>();

    while (!attach.IsAttached) {
        yield return null;
    }

    // Perform setup here
}

3. Bölüm - Dokunmatik yüzey girişiyle çalışma

Hedefler

  • Dokunmatik yüzey giriş verileri olaylarını almayı öğrenin
  • Uygulama deneyiminiz için dokunmatik yüzey ekseni konum bilgilerini kullanmayı öğrenin

Yönergeler

  • Hiyerarşi panelinde ColorPickerWheel öğesine tıklayın
  • Denetçi panelinde, Animator'ın altında ColorPickerWheelController'a çift tıklayın
  • Animator sekmesinin açık olduğunu görebilirsiniz

Unity'nin Animasyon denetleyicisiyle kullanıcı arabirimini gösterme/gizleme

ColorPickerWheel kullanıcı arabirimini animasyonla göstermek ve gizlemek için Unity'nin animasyon sistemini kullanıyoruz. ColorPickerWheel'inVisible özelliğini true veya false tetikleyicilerine ayarlama Animasyon tetikleyicilerini göster ve gizle. Göster ve Gizle parametreleri ColorPickerWheelController animasyon denetleyicisinde tanımlanır.

Unity Animasyon Denetleyicisi

Yönergeler

  • Hiyerarşi panelinde ColorPickerWheel prefab öğesini seçin
  • Visual Studio'da kodu görmek için Denetçi panelinde ColorPickerWheel betiğine çift tıklayın

ColorPickerWheel betiği

ColorPickerWheel , dokunmatik yüzey olaylarını dinlemek için Unity'nin InteractionSourceUpdated olayına abone olur.

InteractionSourceUpdated() içinde betik önce şunların doğru olduğundan emin olmak için denetler:

  • aslında bir dokunmatik yüzey olayıdır (obj.state.dokunmatik yüzeyTouched)
  • sol denetleyiciden (obj.state.source) kaynaklanır.elle kullanım)

Her ikisi de doğruysa dokunmatik yüzey konumu (obj.state).touchpadPosition) selectorPosition'a atanır.

private void InteractionSourceUpdated(InteractionSourceUpdatedEventArgs obj)
{
    if (obj.state.source.handedness == handedness && obj.state.touchpadTouched)
    {
        Visible = true;
        selectorPosition = obj.state.touchpadPosition;
    }
}

Update() içinde, görünür özelliğine bağlı olarak renk seçicinin animatör bileşeninde Animasyon tetikleyicilerini göster ve gizle tetikleyicilerini tetikler

if (visible != visibleLastFrame)
{
    if (visible)
    {
        animator.SetTrigger("Show");
    }
    else
    {
        animator.SetTrigger("Hide");
    }
}

Update() içinde selectorPosition, renk tekerleğinin uv pozisyonu döndüren ağ çarpıştırıcısında bir ışın oluşturmak için kullanılır. Bu konum daha sonra renk tekerleğinin dokusunun piksel koordinatını ve renk değerini bulmak için kullanılabilir. Bu değere SelectedColor özelliği aracılığıyla diğer betikler erişebilir.

Renk Seçici Tekerleği Raycasting

...
    // Clamp selector position to a radius of 1
    Vector3 localPosition = new Vector3(selectorPosition.x * inputScale, 0.15f, selectorPosition.y * inputScale);
    if (localPosition.magnitude > 1)
    {
        localPosition = localPosition.normalized;
    }
    selectorTransform.localPosition = localPosition;

    // Raycast the wheel mesh and get its UV coordinates
    Vector3 raycastStart = selectorTransform.position + selectorTransform.up * 0.15f;
    RaycastHit hit;
    Debug.DrawLine(raycastStart, raycastStart - (selectorTransform.up * 0.25f));

    if (Physics.Raycast(raycastStart, -selectorTransform.up, out hit, 0.25f, 1 << colorWheelObject.layer, QueryTriggerInteraction.Ignore))
    {
        // Get pixel from the color wheel texture using UV coordinates
        Vector2 uv = hit.textureCoord;
        int pixelX = Mathf.FloorToInt(colorWheelTexture.width * uv.x);
        int pixelY = Mathf.FloorToInt(colorWheelTexture.height * uv.y);
        selectedColor = colorWheelTexture.GetPixel(pixelX, pixelY);
        selectedColor.a = 1f;
    }
    // Set the selector's color and blend it with white to make it visible on top of the wheel
    selectorRenderer.material.color = Color.Lerp (selectedColor, Color.white, 0.5f);
}

4. Bölüm - Denetleyici modelini geçersiz kılma

Hedefler

  • Denetleyici modelini özel bir 3B modelle geçersiz kılmayı öğrenin.

MR213_BrushToolOverride

Yönergeler

  • Hiyerarşi panelinde MotionControllers'a tıklayın.
  • Diğer Sağ Denetleyici alanının sağ tarafındaki daireye tıklayın.
  • 'BrushController' yazın ve sonuçtan prefabrik değeri seçin. Bunu Varlıklar/AppPrefabs/BrushController altında bulabilirsiniz.
  • Her zaman alternatif doğru modeli kullan seçeneğini işaretleyin

MR213_BrushToolOverrideSlot

BrushController prefabrik düzeninin Hiyerarşi paneline eklenmesi gerekmez. Ancak, alt bileşenlerini kullanıma almak için:

  • Proje panelinde BrushController yazın ve BrushController prefab öğesini Hiyerarşi paneline sürükleyin.

MR213_BrushTool_Prefab2

İpucu bileşenini BrushController'da bulabilirsiniz. Çizim çizgilerini başlatmak/durdurmak için dönüşümünü kullanacağız.

  • BrushController'iHiyerarşi panelinden silin.
  • Sahneyi kaydedin ve yürüt düğmesine tıklayın. Fırça modelinin sağ taraftaki hareket denetleyicisini değiştirdiğini görebilirsiniz.

5. Bölüm - Giriş seç ile boyama

Hedefler

  • Çizgi çizimi başlatmak ve durdurmak için Seç düğmesi olayını kullanmayı öğrenin

Yönergeler

  • Proje panelinde BrushController prefab'da arama.
  • Visual Studio'da kodu görmek için Denetçi panelinde BrushController Betiği'ne çift tıklayın

BrushController betiği

BrushController , InteractionManager'ın InteractionSourcePressed ve InteractionSourceReleased olaylarına abone olur. InteractionSourcePressed olayı tetiklendiğinde fırçanın Draw özelliği true olarak ayarlanır; InteractionSourceReleased olayı tetiklendiğinde fırçanın Draw özelliği false olarak ayarlanır.

private void InteractionSourcePressed(InteractionSourcePressedEventArgs obj)
{
    if (obj.state.source.handedness == InteractionSourceHandedness.Right && obj.pressType == InteractionSourcePressType.Select)
    {
        Draw = true;
    }
}

private void InteractionSourceReleased(InteractionSourceReleasedEventArgs obj)
{
    if (obj.state.source.handedness == InteractionSourceHandedness.Right && obj.pressType == InteractionSourcePressType.Select)
    {
        Draw = false;
    }
}

Çiz değeri true olarak ayarlanmış olsa da fırça, örnek bir Unity LineRenderer içinde noktalar oluşturur. Bu prefabrik başvuru fırçanın Vuruş Prefab alanında tutulur.

private IEnumerator DrawOverTime()
{
    // Get the position of the tip
    Vector3 lastPointPosition = tip.position;

    ...

    // Create a new brush stroke
    GameObject newStroke = Instantiate(strokePrefab);
    LineRenderer line = newStroke.GetComponent<LineRenderer>();
    newStroke.transform.position = startPosition;
    line.SetPosition(0, tip.position);
    float initialWidth = line.widthMultiplier;

    // Generate points in an instantiated Unity LineRenderer
    while (draw)
    {
        // Move the last point to the draw point position
        line.SetPosition(line.positionCount - 1, tip.position);
        line.material.color = colorPicker.SelectedColor;
        brushRenderer.material.color = colorPicker.SelectedColor;
        lastPointAddedTime = Time.unscaledTime;
        // Adjust the width between 1x and 2x width based on strength of trigger pull
        line.widthMultiplier = Mathf.Lerp(initialWidth, initialWidth * 2, width);

        if (Vector3.Distance(lastPointPosition, tip.position) > minPositionDelta || Time.unscaledTime > lastPointAddedTime + maxTimeDelta)
        {
            // Spawn a new point
            lastPointAddedTime = Time.unscaledTime;
            lastPointPosition = tip.position;
            line.positionCount += 1;
            line.SetPosition(line.positionCount - 1, lastPointPosition);
        }
        yield return null;
    }
}

Renk seçici tekerleği kullanıcı arabiriminden seçili olan rengi kullanmak için BrushController'ınColorPickerWheel nesnesine bir başvurusu olması gerekir. BrushController prefab çalışma zamanında yedek denetleyici olarak örneklendiğinden, sahnedeki nesnelere yapılan tüm başvuruların çalışma zamanında ayarlanması gerekir. Bu durumda ColorPickerWheel'i bulmak için GameObject.FindObjectOfType kullanıyoruz:

private void OnEnable()
{
    // Locate the ColorPickerWheel
    colorPicker = FindObjectOfType<ColorPickerWheel>();

    // Assign currently selected color to the brush’s material color
    brushRenderer.material.color = colorPicker.SelectedColor;
    ...
}
  • Sahneyi kaydedin ve yürüt düğmesine tıklayın. Sağ kumandadaki seç düğmesini kullanarak çizgileri çizebilecek ve boyayabileceksiniz.

6. Bölüm - Girişi seç ile nesne oluşturma

Hedefler

  • Seç ve Kavra düğmesi giriş olaylarını kullanmayı öğrenin
  • Nesnelerin örneğini oluşturma hakkında bilgi edinin

Yönergeler

  • Proje panelinde, arama kutusuna ObjectSpawner yazın. Varlıklar/AppPrefabs/ altında da bulabilirsiniz

  • ObjectSpawner prefab'ını Hiyerarşi paneline sürükleyin.

  • Hiyerarşi panelinde ObjectSpawner'a tıklayın.

  • ObjectSpawner'daRenk Kaynağı adlı bir alan vardır.

  • Hiyerarşipanelinden ColorPickerWheel başvuruyu bu alana sürükleyin.

    Nesne Oluşturucu Denetçisi

  • Hiyerarşi panelinde ObjectSpawner prefab öğesine tıklayın.

  • Visual Studio'da kodu görmek için Denetçi panelinde ObjectSpawner Betiği'ne çift tıklayın.

ObjectSpawner betiği

ObjectSpawner, ilkel bir ağın (küp, küre, silindir) kopyalarını boşlukta örneğini oluşturur. InteractionSourcePressed algılandığında, kullanım durumunu ve bunun bir InteractionSourcePressType.Grasp veya InteractionSourcePressType.Select olayı olup olmadığını denetler.

Bir Kavrama olayı için geçerli ağ türünün (küre, küp, silindir) dizinini artırır

private void InteractionSourcePressed(InteractionSourcePressedEventArgs obj)
{
    // Check handedness, see if it is left controller
    if (obj.state.source.handedness == handedness)
    {
        switch (obj.pressType)
        {
            // If it is Select button event, spawn object
            case InteractionSourcePressType.Select:
                if (state == StateEnum.Idle)
                {
                    // We've pressed the grasp - enter spawning state
                    state = StateEnum.Spawning;
                    SpawnObject();
                }
                break;

            // If it is Grasp button event
            case InteractionSourcePressType.Grasp:

                // Increment the index of current mesh type (sphere, cube, cylinder)
                meshIndex++;
                if (meshIndex >= NumAvailableMeshes)
                {
                    meshIndex = 0;
                }
                break;

            default:
                break;
        }
    }
}

Bir Select olayı için SpawnObject() içinde yeni bir nesne örneği oluşturulur, üst öğesi oluşturulmaz ve dünyaya yayımlanır.

private void SpawnObject()
{
    // Instantiate the spawned object
    GameObject newObject = Instantiate(displayObject.gameObject, spawnParent);
    // Detach the newly spawned object
    newObject.transform.parent = null;
    // Reset the scale transform to 1
    scaleParent.localScale = Vector3.one;
    // Set its material color so its material gets instantiated
    newObject.GetComponent<Renderer>().material.color = colorSource.SelectedColor;
}

ObjectSpawner, görüntüleme nesnesinin malzemesinin rengini ayarlamak için ColorPickerWheel kullanır. Oluşturulan nesnelere bu malzemenin bir örneği verilir, böylece renklerini korurlar.

  • Sahneyi kaydedin ve yürüt düğmesine tıklayın.

Kavra düğmesiyle nesneleri değiştirebilecek ve Seç düğmesiyle nesneleri ortaya çıkacaksınız.

Uygulamayı derleme ve Karma Gerçeklik Portalı'na dağıtma

  • Unity'de Dosya > Derleme Ayarları'nı seçin.
  • Derlemedeki Sahneler'e geçerli sahneyi eklemek için Açık Sahne Ekle'ye tıklayın.
  • Oluştur'a tıklayın.
  • "Uygulama" adlı yeni bir Klasör oluşturun.
  • Uygulama klasörüne tek tıklayın.
  • Klasör Seç’e tıklayın.
  • Unity tamamlandığında bir Dosya Gezgini penceresi görüntülenir.
  • Uygulama klasörünü açın.
  • YourSceneName.sln Visual Studio Çözüm dosyasına çift tıklayın.
  • Visual Studio'daki üst araç çubuğunu kullanarak hedefi Hata Ayıklama'dan Yayın'a ve ARM'den X64'e değiştirin.
  • Cihaz düğmesinin yanındaki açılan oka tıklayın ve Yerel Makine'yi seçin.
  • Menüde Hata Ayıkla -> Hata Ayıklama olmadan Başlat'a tıklayın veya Ctrl + F5 tuşlarına basın.

Artık uygulama Karma Gerçeklik Portalı'nda derlenir ve yüklenir. Karma Gerçeklik Portalı'ndaki Başlat menüsü aracılığıyla yeniden başlatabilirsiniz.

Gelişmiş tasarım - Radyal düzene sahip fırça araçları

MixedReality213 Ana

Bu bölümde, varsayılan hareket denetleyicisi modelini özel fırça aracı koleksiyonuyla değiştirmeyi öğreneceksiniz. Başvurunuz için tamamlanan MixedReality213Advanced sahnesini Sahneler klasörünün altında bulabilirsiniz.

Yönergeler

  • Proje panelinde, arama kutusuna BrushSelector yazın. Varlıklar/AppPrefabs/ altında da bulabilirsiniz

  • BrushSelector prefab'ını Hiyerarşi paneline sürükleyin.

  • Kuruluş için Brushes adlı boş bir GameObject oluşturun

  • Proje panelinden Fırçalar'a aşağıdaki önkoşulları sürükleyin

    • Assets/AppPrefabs/BrushFat
    • Assets/AppPrefabs/BrushThin
    • Varlıklar/AppPrefabs/Silgi
    • Assets/AppPrefabs/MarkerFat
    • Assets/AppPrefabs/MarkerThin
    • Varlıklar/AppPrefabs/Pencil

    Fırçalar

  • Hiyerarşi panelinde MotionControllers prefab öğesine tıklayın.

  • Denetçi panelinde, Hareket Denetleyicisi Görselleştiricisi'ndeHer Zaman Alternatif Sağ Modeli Kullan seçeneğinin işaretini kaldırın

  • Hiyerarşi panelinde Fırça Seçici'ye tıklayın

  • BrushSelector'ınColorPicker adlı bir alanı var

  • Hiyerarşipanelinden ColorPickerWheel öğesini Denetçi panelindeki ColorPicker alanına sürükleyin.

    Fırça Seçiciye ColorPickerWheel Atama

  • Hiyerarşi panelinde, BrushSelector prefab'ın altında Menü nesnesini seçin.

  • Denetçi panelinde, LineObjectCollection bileşeninin altında Nesneler dizisi açılan listesini açın. 6 boş yuva göreceksiniz.

  • Hiyerarşi panelinden Brushes GameObject'in altında üst öğe olarak kullanılan ön eklerin her birini herhangi bir sırada bu yuvalara sürükleyin. (Proje klasöründeki prefabları değil, sahnedeki ön ekleri sürüklediğinizden emin olun.)

Fırça Seçici

BrushSelector prefab

BrushSelectorAttachToController'ı devraldığından, DenetçipanelindeKimlik ve Öğe seçeneklerini gösterir. Fırça araçlarını ileri yönde sağ el kumandasına iliştirmek için Sağ ve İşaret Eden Poz'ı seçtik.

BrushSelector iki yardımcı program kullanır:

  • Elips: Üç nokta şekli boyunca boşlukta noktalar oluşturmak için kullanılır.
  • LineObjectCollection: Nesneleri herhangi bir Line sınıfı (örneğin, Ellipse) tarafından oluşturulan noktaları kullanarak dağıtır. Fırçalarımızı Elips şekline yerleştirmek için bunu kullanacağız.

Bu yardımcı programlar birleştirildiğinde radyal menü oluşturmak için kullanılabilir.

LineObjectCollection betiği

LineObjectCollection , çizgisi boyunca dağıtılmış nesnelerin boyutu, konumu ve döndürmesi için denetimlere sahiptir. Bu, fırça seçici gibi radyal menüler oluşturmak için kullanışlıdır. Ortadaki seçili konuma yaklaşırken hiç bir şeyden ölçeklendirilmeyen fırçaların görünümünü oluşturmak için ObjectScale eğrisi ortada zirveye çıkar ve kenarlarda kılavuzlar kapanır.

BrushSelector betiği

BrushSelector söz konusu olduğunda yordam animasyonu kullanmayı seçtik. İlk olarak, fırça modelleri LineObjectCollection betiği tarafından üç nokta halinde dağıtılır. Ardından her fırça, seçime göre değişen DisplayMode değerine göre kullanıcının elindeki konumunu korumakla sorumludur. Kullanıcı fırçaları seçtiğinde fırça konumu geçişlerinin kesintiye uğrama olasılığının yüksek olması nedeniyle yordamsal bir yaklaşım seçtik. Mecanim animasyonları kesintileri düzgün bir şekilde işleyebilir, ancak basit bir Lerp işleminden daha karmaşık olma eğilimindedir.

BrushSelector her ikisinin bir bileşimini kullanır. Dokunmatik yüzey girişi algılandığında fırça seçenekleri görünür hale gelir ve radyal menü boyunca ölçeklendirilir. Bir zaman aşımı süresinden sonra (kullanıcının seçim yaptığını gösterir) fırça seçenekleri yeniden ölçek daraltılarak yalnızca seçili fırça bırakılır.

Dokunmatik yüzey girişini görselleştirme

Denetleyici modelinin tamamen değiştirildiği durumlarda bile, özgün model girişlerinde girişi göstermek yararlı olabilir. Bu, kullanıcının gerçek hayattaki eylemlerini temele kaldırmaya yardımcı olur. BrushSelector için, giriş alındığında dokunmatik yüzeyi kısa bir süre görünür yapmayı seçtik. Bu, dokunmatik yüzey öğesini denetleyiciden alarak, malzemeyi özel bir malzemeyle değiştirerek ve ardından dokunmatik yüzey girişinin son alındığı zamana göre bu malzemenin rengine bir gradyan uygulanarak gerçekleştirilir.

protected override void OnAttachToController()
{
    // Turn off the default controller's renderers
    controller.SetRenderersVisible(false);

    // Get the touchpad and assign our custom material to it
    Transform touchpad;
    if (controller.TryGetElement(MotionControllerInfo.ControllerElementEnum.Touchpad, out touchpad))
    {
        touchpadRenderer = touchpad.GetComponentInChildren<MeshRenderer>();
        originalTouchpadMaterial = touchpadRenderer.material;
        touchpadRenderer.material = touchpadMaterial;
        touchpadRenderer.enabled = true;
    }

    // Subscribe to input now that we're parented under the controller
    InteractionManager.InteractionSourceUpdated += InteractionSourceUpdated;
}

private void Update()
{
    ...
    // Update our touchpad material
    Color glowColor = touchpadColor.Evaluate((Time.unscaledTime - touchpadTouchTime) / touchpadGlowLossTime);
    touchpadMaterial.SetColor("_EmissionColor", glowColor);
    touchpadMaterial.SetColor("_Color", glowColor);
    ...
}

Dokunmatik yüzey girişi ile fırça aracı seçimi

Fırça seçici dokunmatik yüzeyi basılı giriş algıladığında, girişin sol mu yoksa sağ mı olduğunu belirlemek için girişin konumunu denetler.

selectPressedAmount ile vuruş kalınlığı

InteractionSourcePressed() içindeki InteractionSourcePressType.Select olayı yerine, selectPressedAmount aracılığıyla basılan miktarın analog değerini alabilirsiniz. Bu değer InteractionSourceUpdated() içinde alınabilir.

private void InteractionSourceUpdated(InteractionSourceUpdatedEventArgs obj)
{
    if (obj.state.source.handedness == handedness)
    {
        if (obj.state.touchpadPressed)
        {
            // Check which side we clicked
            if (obj.state.touchpadPosition.x < 0)
            {
                currentAction = SwipeEnum.Left;
            }
            else
            {
                currentAction = SwipeEnum.Right;
            }

            // Ping the touchpad material so it gets bright
            touchpadTouchTime = Time.unscaledTime;
        }

        if (activeBrush != null)
        {
            // If the pressed amount is greater than our threshold, draw
            if (obj.state.selectPressedAmount >= selectPressedDrawThreshold)
            {
                activeBrush.Draw = true;
                activeBrush.Width = ProcessSelectPressedAmount(obj.state.selectPressedAmount);
            }
            else
            {
                // Otherwise, stop drawing
                activeBrush.Draw = false;
                selectPressedSmooth = 0f;
            }
        }
    }
}

Silgi betiği

Silgi , temel FırçanınDrawOverTime() işlevini geçersiz kılan özel bir fırça türüdür. Çiz doğru olsa da silgi, ucunun mevcut fırça darbeleriyle kesişip kesişmediğini denetler. Varsa, küçültülmek ve silinmek üzere kuyruğa eklenirler.

Gelişmiş tasarım - ışınlanma ve lokomosyon

Kullanıcının parmak çubuğunu kullanarak ışınlanma ile sahnede gezinmesine izin vermek istiyorsanız, MixedRealityCamera yerine MixedRealityCameraParent kullanın. InputManager ve DefaultCursor da eklemeniz gerekir. MixedRealityCameraParent zaten alt bileşenler olarak MotionControllers ve Boundary içerdiğinden, mevcut MotionControllers ve Environment prefab'ını kaldırmanız gerekir.

Yönergeler

  • Hiyerarşi panelinde MixedRealityCamera, Environment ve MotionControllers'ı silin

  • Proje panelinde aşağıdaki önkoşulları arayın ve Hiyerarşi paneline sürükleyin:

    • Assets/AppPrefabs/Input/Prefabs/MixedRealityCameraParent
    • Assets/AppPrefabs/Input/Prefabs/InputManager
    • Assets/AppPrefabs/Input/Prefabs/Cursor/DefaultCursor

    Karma Gerçeklik Kamera Ebeveyni

  • Hiyerarşi panelinde Giriş Yöneticisi'ne tıklayın

  • Denetçi panelinde aşağı kaydırarak Basit Tek İşaretçi Seçicisi bölümüne gelin

  • Hiyerarşi panelinde DefaultCursor'ıİmleç alanına sürükleyin

    DefaultCursor Atama

  • Sahneyi kaydedin ve yürüt düğmesine tıklayın. Parmak çubuğunu kullanarak sola/sağa döndürebilecek veya ışınlayabileceksiniz.

Son

Ve bu öğreticinin sonu geldi! Öğrendikleriniz:

  • Unity'nin oyun modunda ve çalışma zamanında hareket denetleyicisi modelleriyle çalışma.
  • Farklı türlerdeki düğme olaylarını ve uygulamalarını kullanma.
  • Kullanıcı arabirimi öğelerini denetleyicinin üzerine bindirme veya tamamen özelleştirme.

Artık hareket denetleyicileriyle kendi çevreleyici deneyiminizi oluşturmaya başlamaya hazırsınız!

Tamamlanan sahneler

  • Unity'nin Proje panelinde Sahneler klasörüne tıklayın.
  • MixedReality213 veMixedReality213Advanced iki Unity sahnesini bulacaksınız.
    • MixedReality213: Tek fırçayla tamamlanan sahne
    • MixedReality213Gelişmiş: Seçme düğmesinin basılı tutar örneğiyle birden çok fırçayla tamamlanan sahne

Ayrıca bkz.