Sdílet prostřednictvím


VSTUP MR 213: Ovladače pohybu

Poznámka

Kurzy Mixed Reality Academy byly navrženy s ohledem na HoloLens (1. generace) a Mixed Reality Asistivní náhlavní soupravy. Proto se domníváme, že je důležité ponechat tyto kurzy pro vývojáře, kteří stále hledají pokyny při vývoji pro tato zařízení. Tyto kurzy nebudou aktualizovány nejnovějšími sadami nástrojů nebo interakcemi používanými pro HoloLens 2. Budou zachovány, aby mohly pokračovat v práci na podporovaných zařízeních. Pro HoloLens 2 byla zveřejněny nové série kurzů.

Ovladače pohybu ve světě hybridní reality přidávají další úroveň interaktivity. Pomocí ovladačů pohybu můžeme s objekty interagovat přirozeněji, podobně jako při fyzických interakcích v reálném životě, což zvyšuje ponoření a potěšení z prostředí vaší aplikace.

V MR Input 213 prozkoumáme vstupní události ovladače pohybu vytvořením jednoduchého prostorového malířství. Pomocí této aplikace mohou uživatelé malovat v trojrozměrném prostoru pomocí různých typů štětců a barev.

Témata probíraná v tomto kurzu

MixedReality213 Téma1 MixedReality213 Téma2 MixedReality213 Téma3
Vizualizace kontroleru Události vstupu kontroleru Vlastní kontroler a uživatelské rozhraní
Naučte se vykreslovat modely ovladačů pohybu v herním režimu a modulu runtime Unity. Seznamte se s různými typy událostí tlačítek a jejich aplikacemi. Zjistěte, jak překrýt prvky uživatelského rozhraní nad kontrolerem nebo ho plně přizpůsobit.

Podpora zařízení

Kurz HoloLens Imerzivní náhlavní soupravy
VSTUP MR 213: Ovladače pohybu ✔️

Než začnete

Požadavky

Podívejte se na kontrolní seznam instalace pro imerzivní náhlavní soupravy na této stránce.

Soubory projektu

Poznámka

Pokud si chcete před stažením projít zdrojový kód, je k dispozici na GitHubu.

Nastavení Unity

Cíle

  • Optimalizace Unity pro vývoj Windows Mixed Reality
  • Nastavení Mixed Reality kamery
  • Nastavení prostředí

Pokyny

  • Spusťte Unity.

  • Vyberte Otevřít.

  • Přejděte na plochu a najděte složku MixedReality213-master , kterou jste předtím nearchivovali.

  • Klikněte na tlačítko Vybrat složku.

  • Jakmile Unity dokončí načítání souborů projektu, uvidíte editor Unity.

  • V Unity vyberte Nastavení sestavení souboru>.

    MR213_BuildSettings

  • V seznamu Platforma vyberte Univerzální platforma Windows a klikněte na tlačítko Přepnout platformu.

  • Nastavte cílové zařízení na Libovolné zařízení.

  • Nastavení typu sestavení na D3D

  • Nastavte sadu SDK na nejnovější nainstalovanou verzi.

  • Kontrola projektů Unity C#

    • To vám umožní upravovat soubory skriptu v projektu sady Visual Studio bez opětovného sestavení projektu Unity.
  • Klikněte na Nastavení přehrávače.

  • Na panelu inspektoru se posuňte dolů.

  • V nastavení XR zkontrolujte, že se virtuální realita podporuje.

  • V části Sady SDK pro virtuální realitu vyberte Windows Mixed Reality

    MR213_XRSettings

  • Zavřete okno Nastavení sestavení .

Struktura projektu

V tomto kurzu se používá sada nástrojů Mixed Reality – Unity. Vydané verze najdete na této stránce.

Struktura projektu

Dokončené scény pro referenci

  • Ve složce Scenes (Scény ) najdete dvě dokončené scény Unity.
    • MixedReality213: Dokončená scéna s jedním štětcem
    • MixedReality213Advanced: Dokončená scéna pro pokročilý návrh s více štětci

Nové nastavení scény pro kurz

  • V Unity klikněte na Nová scéna souboru.>

  • Odstranění hlavní kamery a směrového světla

  • Na panelu Projekt vyhledejte následující prefabs a přetáhněte je na panel Hierarchie :

    • Assets/HoloToolkit/Input/Prefabs/MixedRealityCamera
    • Prostředky/AppPrefabs/Environment

    Kamera a prostředí

  • Sada nástrojů Mixed Reality obsahuje dva prefaby fotoaparátu:

    • MixedRealityCamera.prefab: Pouze kamera
    • MixedRealityCameraParent.prefab: Kamera + Teleportace + hranice
    • V tomto kurzu použijeme MixedRealityCamera bez funkce teleportace. Z tohoto důvodu jsme přidali jednoduchý prefab prostředí , který obsahuje základní podlaží, aby se uživatel cítil uzemněný.
    • Další informace o teleportaci pomocí MixedRealityCameraParent najdete v článku Pokročilý návrh – Teleportace a lokomoce.

Nastavení Skyboxu

  • Klikněte na Nastavení osvětlení > oken>.

  • Klikněte na kruh na pravé straně pole Materiál skyboxu.

  • Zadejte šedý text a vyberte SkyboxGray (Assets/AppPrefabs/Support/Materials/SkyboxGray.mat).

    Nastavení skyboxu

  • Zaškrtněte možnost Skybox , abyste viděli přiřazený šedý přechod skybox.

    Přepnout možnost skyboxu

  • Scéna s MixedRealityCamera, Environment a šedým skyboxem bude vypadat takto.

    Prostředí MixedReality213

  • Klikněte na Soubor Uložit scénu jako.>

  • Uložte scénu do složky Scény s libovolným názvem.

Kapitola 1 – Vizualizace kontroleru

Cíle

  • Naučte se vykreslovat modely ovladačů pohybu v herním režimu Unity a za běhu.

Windows Mixed Reality poskytuje animovaný model kontroleru pro vizualizaci kontroleru. Pro vizualizaci kontroleru ve vaší aplikaci můžete použít několik přístupů:

  • Výchozí – použití výchozího kontroleru bez úprav
  • Hybridní – použití výchozího kontroleru, ale přizpůsobení některých jeho prvků nebo překrytí komponent uživatelského rozhraní
  • Výměna – použití vlastního přizpůsobeného 3D modelu pro ovladač

V této kapitole se dozvíme o příkladech těchto přizpůsobení kontroleru.

Pokyny

  • Na panelu Projekt do vyhledávacího pole zadejte MotionControllers . Najdete ho také v části Assets/HoloToolkit/Input/Prefabs/.
  • Přetáhněte prefab MotionControllers na panel Hierarchie .
  • Na panelu Hierarchie klikněte na prefab MotionControllers.

Prefab MotionControllers

Prefab MotionControllers má skript MotionControllerVisualizer , který poskytuje sloty pro alternativní modely kontroleru. Pokud přiřadíte vlastní 3D modely, jako je ruka nebo meč, a zaškrtnete políčko Vždy používat alternativní levý/pravý model, uvidíte je místo výchozího modelu. Tento slot použijeme v kapitole 4 k nahrazení modelu ovladače štětcem.

MR213_ControllerVisualizer

Pokyny

  • Na panelu Inspektor poklikejte na skript MotionControllerVisualizer a zobrazte kód v sadě Visual Studio.

Skript MotionControllerVisualizer

Třídy MotionControllerVisualizer a MotionControllerInfo poskytují prostředky pro přístup & úpravu výchozích modelů kontroleru. MotionControllerVisualizer se přihlásí k odběru události InteractionSourceDetected Unity a automaticky vytvoří instanci modelů kontroleru, když jsou nalezeny.

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

Modely kontroleru jsou dodávány podle specifikace glTF. Tento formát byl vytvořen tak, aby poskytoval běžný formát a zároveň vylepšil proces přenosu a rozbalování 3D prostředků. V tomto případě potřebujeme načíst a načíst modely kontrolerů za běhu, protože chceme, aby uživatelské prostředí bylo co nejplynulejší, a není zaručeno, kterou verzi ovladačů pohybu může uživatel používat. V tomto kurzu se prostřednictvím sady Mixed Reality Toolkit používá verze projektu UnityGLTF skupiny Khronos.

Po doručení kontroleru můžou skripty použít MotionControllerInfo k vyhledání transformací pro konkrétní prvky kontroleru, aby se mohly správně umístit.

V pozdější kapitole se dozvíte, jak pomocí těchto skriptů připojit prvky uživatelského rozhraní k řadičům.

V některých skriptech najdete bloky kódu s #if ! UNITY_EDITOR nebo UNITY_WSA. Tyto bloky kódu se při nasazení do Windows spouští jenom v modulu runtime UPW. Důvodem je to, že sada rozhraní API používaná editorem Unity a modulem runtime aplikace pro UPW se liší.

  • Uložte scénu a klikněte na tlačítko Přehrát .

Scénu uvidíte s ovladači pohybu v náhlavní soupravě. Můžete si prohlédnout podrobné animace pro kliknutí na tlačítko, pohyby palce a zvýraznění dotykového touchpadu.

výchozí MR213_Controller vizualizace

Kapitola 2 – Připojení prvků uživatelského rozhraní k kontroleru

Cíle

  • Seznamte se s prvky ovladačů pohybu.
  • Zjistěte, jak připojit objekty ke konkrétním částem kontrolerů.

V této kapitole se dozvíte, jak do kontroleru přidat prvky uživatelského rozhraní, ke kterým může uživatel kdykoli snadno přistupovat a manipulovat s nimi. Dozvíte se také, jak přidat jednoduché uživatelské rozhraní pro výběr barev pomocí vstupu touchpadu.

Pokyny

  • Na panelu Projekt vyhledejte skript MotionControllerInfo .
  • Ve výsledku hledání poklikejte na skript MotionControllerInfo a zobrazte kód v sadě Visual Studio.

Skript MotionControllerInfo

Prvním krokem je zvolit, ke kterému prvku kontroleru se má uživatelské rozhraní připojit. Tyto prvky jsou definovány v ControllerElementEnum v MotionControllerInfo.cs.

MR213 MotionControllerElements

  • Domů
  • Nabídka
  • Pochopit
  • Palec
  • Výběr
  • Touchpad
  • Polohovací pozice – tento prvek představuje špičku kontroleru ukazující dopředu.

Pokyny

  • Na panelu Projekt vyhledejte skript AttachToController .
  • Ve výsledku hledání poklikejte na skript AttachToController a zobrazte kód v sadě Visual Studio.

Skript AttachToController

Skript AttachToController poskytuje jednoduchý způsob, jak připojit všechny objekty k zadané kontroleru rukou a elementu.

V AttachElementToController()

  • Kontrola rukou pomocí MotionControllerInfo.Handedness
  • Získání konkrétního prvku kontroleru pomocí MotionControllerInfo.TryGetElement()
  • Po načtení transformace elementu z modelu kontroleru vytvořte nadřazený objekt pod ním a nastavte místní pozici objektu & otočení na nulu.
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;
     }
}

Nejjednodušší způsob, jak použít skript AttachToController , je dědit z něj, jak jsme to udělali v případě ColorPickerWheel. Jednoduše přepište funkce OnAttachToController a OnDetachFromController a proveďte nastavení nebo rozpis při zjištění nebo odpojení kontroleru.

Pokyny

  • Na panelu Projekt zadejte do vyhledávacího pole ColorPickerWheel. Najdete ho také v části Prostředky/AppPrefabs/.
  • Přetáhněte panel ColorPickerWheel na panel Hierarchie .
  • Na panelu Hierarchie klikněte na panelu Hierarchie na panelu ColorPickerWheel.
  • Na panelu Inspektor poklikejte na ColorPickerWheel Script a zobrazte kód v sadě Visual Studio.

ColorPickerWheel prefab

Skript ColorPickerWheel

Vzhledem k tomu, že ColorPickerWheel dědí AttachToController, zobrazuje na panelu Inspektorumožnost Odevzdanost a element. Připojíme uživatelské rozhraní k elementu Touchpad na levém ovladači.

Skript ColorPickerWheel

ColorPickerWheel přepíše OnAttachToController a OnDetachFromController k odběru vstupní události, která se použije v další kapitole pro výběr barev se vstupem touchpadu.

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;
    }
    ...
}
  • Uložte scénu a klikněte na tlačítko Přehrát .

Alternativní metoda pro připojení objektů k řadičům

Doporučujeme, aby vaše skripty dědily z AttachToController a přepsaly OnAttachToController. To ale nemusí být vždy možné. Alternativou je použít ji jako samostatnou komponentu. To může být užitečné, když chcete k kontroleru připojit existující prefab bez refaktoringu skriptů. Jednoduše požádejte třídu, aby před provedením jakéhokoli nastavení počkala na nastavení IsAttached na hodnotu true. Nejjednodušším způsobem, jak to udělat, je použít korutin pro "Start".

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

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

    // Perform setup here
}

Kapitola 3 : Práce se vstupem touchpadu

Cíle

  • Informace o získání vstupních datových událostí touchpadu
  • Zjistěte, jak používat informace o poloze osy touchpadu pro prostředí aplikace.

Pokyny

  • Na panelu Hierarchie klikněte na ColorPickerWheel
  • Na panelu Inspektor v části Animator poklikejte na ColorPickerWheelController.
  • Uvidíte otevřenou kartu Animatoru .

Zobrazení nebo skrytí uživatelského rozhraní pomocí kontroleru animací Unity

K zobrazení a skrytí uživatelského rozhraní ColorPickerWheel s animací používáme animační systém Unity. Nastavení vlastnosti Visible ColorPickerWheel na hodnotu true nebo false triggers Show and Hide animation triggers Parametry Show a Hide jsou definovány v kontroleru animace ColorPickerWheelController .

Ovladač animací Unity

Pokyny

  • Na panelu Hierarchie vyberte ColorPickerWheel prefab
  • Na panelu Inspektor poklikejte na ColorPickerWheel script a zobrazte kód v sadě Visual Studio.

Skript ColorPickerWheel

ColorPickerWheel se přihlásí k odběru události InteractionSourceUpdated Unity, aby naslouchal událostem touchpadu.

V části InteractionSourceUpdated() skript nejprve zkontroluje, že:

  • je ve skutečnosti událost touchpadu (obj.state.touchpadTouched)
  • pochází z levého kontroleru (obj.state.source.rukou)

Pokud platí obojí, poloha touchpadu (obj.state.touchpadPosition) je přiřazena k selectorPosition.

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

V části Update() se na základě vlastnosti visible aktivují aktivační události pro zobrazení a skrytí animací v komponentě animátoru pro výběr barvy.

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

V update() se selektorPosition používá k odhození paprsku na s collider sítě barevného kola, který vrací uv záření. Tato pozice se pak dá použít k vyhledání souřadnice a barvy v pixelech textury barevného kola. Tato hodnota je přístupná jiným skriptům prostřednictvím SelectedColor vlastnost.

Volba barev kolo 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);
}

Kapitola 4 – Přepsání modelu kontroleru

Cíle

  • Zjistěte, jak přepsat model kontroleru vlastním 3D modelem.

MR213_BrushToolOverride

Pokyny

  • Na panelu Hierarchy (Hierarchie) klikněte na MotionControllers (Ovládací zařízení Pohybu).
  • Klikněte na kruh na pravé straně pole Alternativní pravý kontroler .
  • Zadejte "BrushController" a ve výsledku vyberte prefab. Najdete ho v části Assets/AppPrefabs/BrushController.
  • Zaškrtněte vždy používat alternativní správný model.

MR213_BrushToolOverrideSlot

Prefab BrushController nemusí být součástí panelu Hierarchie . Pokud ale chcete zkontrolovat jeho podřízené komponenty:

  • Na panelu Projekt zadejte BrushController a přetáhněte BrushController prefab na panel Hierarchie .

MR213_BrushTool_Prefab2

Komponentu Tip najdete v BrushController. Jeho transformaci použijeme k zahájení/zastavení kreslení čar.

  • Odstraňte BrushController z panelu Hierarchie .
  • Uložte scénu a klikněte na tlačítko Přehrát . Uvidíte, že model štětce nahradil pravý ovladač pohybu.

Kapitola 5 - Malování se vstupem Select

Cíle

  • Zjistěte, jak pomocí události tlačítka Vybrat spustit a zastavit kreslení čar.

Pokyny

  • Na panelu Projekt vyhledejte ovládací prvek BrushController.
  • Na panelu inspektoru poklikejte na BrushController Script a zobrazte kód v sadě Visual Studio.

Skript BrushController

BrushController se přihlásí k odběru InteractionManager InteractionManager InteractionSourcePressed a InteractionSourceReleased události. Při InteractionSourcePressed událost je aktivována, brush Draw vlastnost je nastavena na true; Při InteractionSourceReleased událost je aktivována, draw vlastnost štětce je nastavena na false.

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

Když je kreslení nastaveno na true, štětec vygeneruje body v instanci Unity LineRenderer. Odkaz na tento prefab se uchovává v poli štětce Předobrázek .

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

Chcete-li použít aktuálně vybranou barvu z uživatelského rozhraní výběru barvy, BrushController musí mít odkaz na objekt ColorPickerWheel . Vzhledem k tomu, že prefab BrushController je vytvořena za běhu jako náhradní kontroler, všechny odkazy na objekty ve scéně budou muset být nastaveny za běhu. V tomto případě použijeme GameObject.FindObjectOfType k vyhledání ColorPickerWheel:

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

    // Assign currently selected color to the brush’s material color
    brushRenderer.material.color = colorPicker.SelectedColor;
    ...
}
  • Uložte scénu a klikněte na tlačítko Přehrát . Pomocí tlačítka výběru na pravém ovladači budete moct kreslit čáry a malovat.

Kapitola 6 – Vytváření objektů se vstupem Select

Cíle

  • Naučte se používat vstupní události tlačítek Select a Grasp.
  • Informace o vytváření instancí objektů

Pokyny

  • Na panelu Projekt zadejte Do vyhledávacího pole ObjectSpawner . Najdete ho také v části Prostředky/AppPrefabs/

  • Přetáhněte objekt ObjectSpawner prefab na panel Hierarchie .

  • Na panelu Hierarchie klikněte na ObjectSpawner.

  • ObjectSpawner má pole s názvem Zdroj barev.

  • Z panelu Hierarchie přetáhněte odkaz ColorPickerWheel do tohoto pole.

    Inspektor objektu spawner

  • Klikněte na panelu Hierarchie na panelu ObjektSpawner.

  • Na panelu inspektoru poklikejte na ObjectSpawner Script a zobrazte kód v sadě Visual Studio.

Skript ObjectSpawner

Objekt ObjectSpawner vytvoří instanci kopie primitivní sítě (datová krychle, koule, válec) do prostoru. Když se zjistí InteractionSourcePressed , zkontroluje se, jestli se jedná o událost InteractionSourcePressType.Grasp nebo InteractionSourcePressType.Select .

U události Grasp zvýší index aktuálního typu sítě (koule, krychle, válec).

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

U události Select se v SpawnObject() vytvoří nová instance objektu, není nadřazená a uvolní se do světa.

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 používá ColorPickerWheel k nastavení barvy materiálu objektu zobrazení. Objekty, které vznikly, mají instanci tohoto materiálu, takže si zachovají svoji barvu.

  • Uložte scénu a klikněte na tlačítko Přehrát .

Pomocí tlačítka Uchopit budete moct změnit objekty a pomocí tlačítka Vybrat objekty vytvořit.

Sestavení a nasazení aplikace na Mixed Reality Portal

  • V Unity vyberte Nastavení sestavení souboru>.
  • Kliknutím na Přidat otevřené scény přidáte aktuální scénu do scén v sestavení.
  • Klikněte na Sestavit.
  • Vytvořte novou složku s názvem "App".
  • Klikněte na složku Aplikace .
  • Klikněte na tlačítko Vybrat složku.
  • Po dokončení Unity se zobrazí okno Průzkumník souborů.
  • Otevřete složku Aplikace .
  • Poklikejte na soubor řešení YourSceneName.sln v sadě Visual Studio.
  • Pomocí horního panelu nástrojů v sadě Visual Studio změňte cíl z Ladění na Vydání a z ARM na X64.
  • Klikněte na šipku rozevíracího seznamu vedle tlačítka Zařízení a vyberte Místní počítač.
  • V nabídce klikněte na Ladit –> Spustit bez ladění nebo stiskněte Ctrl +F5.

Teď je aplikace sestavená a nainstalovaná na portálu Mixed Reality Portal. Můžete ho znovu spustit prostřednictvím nabídky Start na portálu Mixed Reality Portal.

Pokročilý návrh – nástroje štětců s kruhovým rozložením

MixedReality213 – hlavní

V této kapitole se dozvíte, jak nahradit výchozí model ovladače pohybu vlastní kolekcí kartáčů. Dokončenou scénu MixedReality213Advanced najdete ve složce Scény .

Pokyny

  • Na panelu Projekt zadejte do vyhledávacího pole BrushSelector . Najdete ho také v části Prostředky/AppPrefabs/

  • Přetáhněte panel BrushSelector na panel Hierarchie .

  • Pro organizaci vytvořte prázdný objekt GameObject s názvem Brushes (Štětce).

  • Přetáhněte následující prefaby z panelu Projekt do štětců.

    • Prostředky/AppPrefabs/BrushFat
    • Assets/AppPrefabs/BrushThin
    • Prostředky/AppPrefabs/Eraser
    • Assets/AppPrefabs/MarkerFat
    • Assets/AppPrefabs/MarkerThin
    • Prostředky/AppPrefabs/Pencil

    Štětce

  • Na panelu Hierarchie klikněte na prefab MotionControllers.

  • Na panelu inspektoruzrušte zaškrtnutí políčka Vždy použít alternativní pravý model ve Vizualizéru pohybu.

  • Na panelu Hierarchy (Hierarchie) klikněte na BrushSelector (Výběr štětce).

  • BrushSelector obsahuje pole s názvem ColorPicker.

  • Z panelu Hierarchie přetáhněte pole ColorPickerWheel do pole ColorPicker na panelu inspektoru .

    Přiřadit ColorPickerWheel k selektoru štětce

  • Na panelu Hierarchie v části BrushSelector prefab vyberte objekt Menu .

  • Na panelu inspektoru pod komponentou LineObjectCollection otevřete rozevírací seznam Pole objektů . Uvidíte 6 prázdných slotů.

  • Z panelu Hierarchie přetáhněte všechny nadřazené objekty GameObject brushes do těchto slotů v libovolném pořadí. (Ujistěte se, že přetahujete předběžné šablony ze scény, ne z prefab ve složce projektu.)

Selektor štětců

Prefab brushSelector

Vzhledem k tomu, BrushSelector dědí AttachToController, zobrazí na panelu inspektoru možnosti Handedness a Element. Vybrali jsme vpravo a polohovací pozici , abychom k pravému ovladači připojili nástroje štětce se směrem dopředu.

BrushSelector používá dva nástroje:

  • Elipsa: slouží ke generování bodů v prostoru podél tvaru elipsy.
  • LineObjectCollection: distribuuje objekty pomocí bodů generovaných libovolnou třídou Line (např. Ellipse). Použijeme je k umístění štětců podél tvaru elipsy.

Při kombinaci lze tyto nástroje použít k vytvoření kruhové nabídky.

LineObjectCollection – skript

LineObjectCollection má ovládací prvky pro velikost, umístění a otočení objektů distribuovaných podél své čáry. To je užitečné při vytváření kruhových nabídek, jako je volič štětců. Aby se vytvořil vzhled štětců, které se při přibližování k středové vybrané pozici zvětšují z ničeho, křivka ObjectScale se vychýlí ve středu a na okrajích se zužuje.

Skript BrushSelector

V případě štětce Jsme se rozhodli použít procedurální animaci. Nejprve jsou modely štětců distribuovány ve elipse pomocí skriptu LineObjectCollection . Každý štětec pak zodpovídá za udržování své pozice v ruce uživatele na základě jeho hodnoty DisplayMode , která se mění na základě výběru. Zvolili jsme procedurální přístup kvůli vysoké pravděpodobnosti přerušení přechodů pozice štětce při výběru štětců uživatelem. Mecanim animace zvládnou přerušení elegantně, ale jsou složitější než jednoduchá lerpová operace.

BrushSelector používá kombinaci obou. Když se zjistí vstup touchpadu, zobrazí se možnosti štětce a vertikálně navýšit kapacitu podél kruhové nabídky. Po uplynutí časového limitu (který označuje, že uživatel provedl výběr) možnosti štětce znovu vertikálně snížit kapacitu a ponechat pouze vybraný štětec.

Vizualizace vstupu touchpadu

I v případech, kdy byl model kontroleru zcela nahrazen, může být užitečné zobrazit vstupy na původních vstupech modelu. To pomáhá zemnět akce uživatele v realitě. Pro BrushSelector jsme se rozhodli, že touchpad bude po přijetí vstupu krátce viditelný. To bylo provedeno načtením prvku touchpadu z ovladače, nahrazením jeho materiálu vlastním materiálem a následným použitím přechodu na barvu tohoto materiálu na základě posledního přijetí vstupu touchpadu.

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

Výběr nástroje Štětec se vstupem na touchpadu

Když volič štětce zjistí stisknutí vstupu touchpadu, zkontroluje polohu vstupu a určí, jestli byl vlevo nebo vpravo.

Tloušťka tahu s selectPressedAmount

Místo události InteractionSourcePressType.Select v InteractionSourcePressed() můžete získat analogovou hodnotu stisknutého množství prostřednictvím selectPressedAmount. Tuto hodnotu je možné načíst v interactionSourceUpdated().

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

Skript gumy

Guma je speciální typ štětce, který přepíše funkci DrawOverTime() základního štětce. Pokud je hodnota Kreslení pravdivá, guma zkontroluje, jestli se její špička protíná s existujícími tahy štětce. Pokud ano, přidají se do fronty, aby se zmenšily a odstranily.

Pokročilý návrh – teleportace a lokomoce

Pokud chcete uživateli povolit pohyb po scéně s teleportací pomocí thumbsticku, použijte MixedRealityCameraParent místo MixedRealityCameraCameraParent. Musíte také přidat InputManager a DefaultCursor. Vzhledem k tomu , MixedRealityCameraParent již obsahuje MotionControllers a Boundary jako podřízené komponenty, měli byste odebrat existující MotionControllers a prostředí prefab.

Pokyny

  • Na panelu Hierarchie odstraňte MixedRealityCamera, Environment a MotionControllers.

  • Na panelu Projekt vyhledejte následující prefabs a přetáhněte je na panel Hierarchie :

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

    Nadřazená Mixed Reality kamera

  • Na panelu Hierarchie klikněte na Správce vstupu.

  • Na panelu inspektoru se posuňte dolů do části Jednoduchý výběr jednoho ukazatele.

  • Z panelu Hierarchie přetáhněte DefaultCursor do pole Kurzor .

    Přiřazování defaultCursor

  • Uložte scénu a klikněte na tlačítko Přehrát . Budete moct pomocí thumbsticku otáčet doleva/doprava nebo teleportovat.

Konec

A to je konec tohoto kurzu! Naučili jste se:

  • Jak pracovat s modely ovladačů pohybu v herním režimu a modulu runtime Unity.
  • Jak používat různé typy událostí tlačítek a jejich aplikace.
  • Jak překrýt prvky uživatelského rozhraní nad kontrolerem nebo ho plně přizpůsobit.

Teď jste připraveni začít vytvářet vlastní imerzivní prostředí s ovladači pohybu!

Dokončené scény

  • Na panelu Project (Projekt ) v Unity klikněte na složku Scenes (Scény ).
  • Najdete zde dvě scény Unity MixedReality213 a MixedReality213Advanced.
    • MixedReality213: Dokončená scéna s jedním štětcem
    • MixedReality213Advanced: Dokončená scéna s více štětci s příkladem stisknutí tlačítka výběru

Viz také