Entrada de realidad mixta (213): Controladores de movimientoMR Input 213: Motion controllers

Nota

Los tutoriales de Mixed Reality Academy se han diseñado teniendo en cuenta HoloLens (1.ª generación) y los cascos envolventes de realidad mixta.The Mixed Reality Academy tutorials were designed with HoloLens (1st gen) and Mixed Reality Immersive Headsets in mind. Por lo tanto, creemos que es importante conservar estos tutoriales para los desarrolladores que sigan buscando instrucciones sobre el desarrollo para esos dispositivos.As such, we feel it is important to leave these tutorials in place for developers who are still looking for guidance in developing for those devices. Estos tutoriales no se actualizarán con los conjuntos de herramientas o las interacciones más recientes que se usan para HoloLens 2.These tutorials will not be updated with the latest toolsets or interactions being used for HoloLens 2. Se mantendrán para que sigan funcionando en los dispositivos compatibles.They will be maintained to continue working on the supported devices. Se ha publicado una nueva serie de tutoriales para HoloLens 2.A new series of tutorials has been posted for HoloLens 2.

Los controladores de movimiento del mundo de la realidad mixta agregan otro nivel de interactividad.Motion controllers in the mixed reality world add another level of interactivity. Con los controladores de movimiento, podemos interactuar directamente con los objetos de una manera más natural, de forma similar a las interacciones físicas en la vida real, lo que aumenta la inmersión y la alegría en la experiencia de la aplicación.With motion controllers, we can directly interact with objects in a more natural way, similar to our physical interactions in real life, increasing immersion and delight in your app experience.

En la entrada MR 213, exploraremos los eventos de entrada del controlador de movimiento mediante la creación de una sencilla experiencia de dibujo espacial.In MR Input 213, we will explore the motion controller's input events by creating a simple spatial painting experience. Con esta aplicación, los usuarios pueden pintar en un espacio tridimensional con varios tipos de pinceles y colores.With this app, users can paint in three-dimensional space with various types of brushes and colors.

Temas tratados en este tutorialTopics covered in this tutorial

MixedReality213 Topic1 MixedReality213 Topic2 MixedReality213 Topic3
Visualización del controladorController visualization Eventos de entrada del controladorController input events Controlador y interfaz de usuario personalizadosCustom controller and UI
Aprenda a representar los modelos de control de movimiento en el modo de juego y el tiempo de ejecución de Unity.Learn how to render motion controller models in Unity's game mode and runtime. Comprenda los distintos tipos de eventos de botón y sus aplicaciones.Understand different types of button events and their applications. Obtenga información sobre cómo superponer los elementos de la interfaz de usuario sobre el controlador o personalizarlos totalmente.Learn how to overlay UI elements on top of the controller or fully customize it.

Compatibilidad con dispositivosDevice support

CursoCourse HoloLensHoloLens Cascos envolventesImmersive headsets
Entrada de realidad mixta (213): Controladores de movimientoMR Input 213: Motion controllers ✔️✔️

Antes de comenzarBefore you start

Requisitos previosPrerequisites

Consulte la lista de comprobación de instalación para los auriculares que se envolverán en esta página.See the installation checklist for immersive headsets on this page.

Archivos de proyectoProject files

Nota

Si desea examinar el código fuente antes de la descarga, está disponible en github.If you want to look through the source code before downloading, it's available on GitHub.

Configuración de UnityUnity setup

ObjetivosObjectives

  • Optimizar el desarrollo de Unity para Windows Mixed RealityOptimize Unity for Windows Mixed Reality development
  • Configuración de una cámara de realidad mixtaSetup Mixed Reality Camera
  • Entorno de configuraciónSetup environment

InstructionsInstructions

  • Inicie Unity.Start Unity.

  • seleccione Open (Abrir).Select Open .

  • Navegue hasta el escritorio y busque la carpeta MixedReality213-Master que ha desarchivado anteriormente.Navigate to your Desktop and find the MixedReality213-master folder you previously unarchived.

  • Haga clic en Seleccionar carpeta .Click Select Folder .

  • Una vez que Unity termine de cargar los archivos de proyecto, podrá ver el editor de Unity.Once Unity finishes loading project files, you will be able to see Unity editor.

  • En Unity, seleccione archivo > configuración de compilación .In Unity, select File > Build Settings .

    MR213_BuildSettings

  • Seleccione plataforma universal de Windows en la lista plataforma y haga clic en el botón cambiar plataforma .Select Universal Windows Platform in the Platform list and click the Switch Platform button.

  • Establecimiento del dispositivo de destino en cualquier dispositivoSet Target Device to Any device

  • Establecer el tipo de compilación en D3DSet Build Type to D3D

  • Establecer SDK en la versión más reciente instaladaSet SDK to Latest Installed

  • Comprobar los proyectos de C# de UnityCheck Unity C# Projects

    • Esto permite modificar archivos de script en el proyecto de Visual Studio sin volver a generar el proyecto de Unity.This allows you modify script files in the Visual Studio project without rebuilding Unity project.
  • Haga clic en configuración del reproductor .Click Player Settings .

  • En el panel Inspector , desplácese hacia abajo hasta la parte inferior.In the Inspector panel, scroll down to the bottom

  • En configuración de XR, Active realidad compatibleIn XR Settings, check Virtual Reality Supported

  • En SDK de realidad virtual, seleccione Windows Mixed Reality .Under Virtual Reality SDKs, select Windows Mixed Reality

    MR213_XRSettings

  • Cierre la ventana de configuración de compilación .Close Build Settings window.

Estructura del proyectoProject structure

En este tutorial se usa Mixed Reality Toolkit-Unity .This tutorial uses Mixed Reality Toolkit - Unity . Puede encontrar las versiones en esta página.You can find the releases on this page.

ProjectStructure

Escenas completadas para su referenciaCompleted scenes for your reference

  • Encontrará dos escenas de Unity completadas en la carpeta Scenes .You will find two completed Unity scenes under Scenes folder.
    • MixedReality213 : escena completada con un solo pincelMixedReality213 : Completed scene with single brush
    • MixedReality213Advanced : escena completada para diseño avanzado con varios pincelesMixedReality213Advanced : Completed scene for advanced design with multiple brushes

Nueva configuración de escenas para el tutorialNew Scene setup for the tutorial

  • En Unity, haga clic en archivo > nueva escena .In Unity, click File > New Scene

  • Eliminar la cámara principal y la luz direccionalDelete Main Camera and Directional Light

  • En el panel Proyecto , busque y arrastre el siguiente Prefabs al panel jerarquía :From the Project panel , search and drag the following prefabs into the Hierarchy panel:

    • Assets/HoloToolkit/INPUT/Prefabs/ MixedRealityCameraAssets/HoloToolkit/Input/Prefabs/ MixedRealityCamera
    • Activos/AppPrefabs/ entornoAssets/AppPrefabs/ Environment

    Cámara y entorno

  • Hay dos Prefabs de cámara en el kit de herramientas de realidad mixta:There are two camera prefabs in Mixed Reality Toolkit:

    • MixedRealityCamera. recurso prefabricado : solo cámaraMixedRealityCamera.prefab : Camera only
    • MixedRealityCameraParent. recurso prefabricado : cámara + teleportabilidad + límiteMixedRealityCameraParent.prefab : Camera + Teleportation + Boundary
    • En este tutorial, usaremos MixedRealityCamera sin la característica de teleportabilidad.In this tutorial, we will use MixedRealityCamera without teleportation feature. Por este motivo, hemos agregado recurso prefabricado de entorno sencillo, que contiene una planta básica para que el usuario sienta.Because of this, we added simple Environment prefab which contains a basic floor to make the user feel grounded.
    • Para obtener más información acerca de la teleportabilidad con MixedRealityCameraParent , consulte el artículo sobre el diseño avanzado: teleportabilidad y LocomotionTo learn more about the teleportation with MixedRealityCameraParent , see Advanced design - Teleportation and locomotion

Configuración de SKYBOXSkybox setup

  • Haga clic en ventana > iluminación > configuraciónClick Window > Lighting > Settings

  • Haga clic en el círculo en el lado derecho del campo material de SKYBOXClick the circle on the right side of the Skybox Material field

  • Escriba "Gray" y seleccione SkyboxGray (assets/AppPrefabs/support/Materials/SkyboxGray. MAT)Type in ‘gray’ and select SkyboxGray (Assets/AppPrefabs/Support/Materials/SkyboxGray.mat)

    Establecer SKYBOX

  • Active la opción SKYBOX para poder ver el degradado gris asignado SKYBOXCheck Skybox option to be able to see assigned gray gradient skybox

    Alternar opción SKYBOX

  • La escena con MixedRealityCamera, entorno y gris SKYBOX tendrá el siguiente aspecto.The scene with MixedRealityCamera, Environment and gray skybox will look like this.

    Entorno de MixedReality213

  • Haga clic en archivo > guardar escena comoClick File > Save Scene as

  • Guardar la escena en la carpeta Scenes con cualquier nombreSave your scene under Scenes folder with any name

Capítulo 1: visualización del controladorChapter 1 - Controller visualization

ObjetivosObjectives

  • Aprenda a representar modelos de controlador de movimiento en el modo de juego de Unity y en tiempo de ejecución.Learn how to render motion controller models in Unity's game mode and at runtime.

Windows Mixed Reality proporciona un modelo de controlador animado para la visualización del controlador.Windows Mixed Reality provides an animated controller model for controller visualization. Hay varios enfoques que puede realizar para la visualización del controlador en la aplicación:There are several approaches you can take for controller visualization in your app:

  • Predeterminado: uso del controlador predeterminado sin modificaciónDefault - Using default controller without modification
  • Híbrido: uso del controlador predeterminado, pero personalización de algunos de sus elementos o de la superposición de componentes de interfaz de usuarioHybrid - Using default controller, but customizing some of its elements or overlaying UI components
  • Reemplazo: usar su propio modelo 3D personalizado para el controladorReplacement - Using your own customized 3D model for the controller

En este capítulo, veremos los ejemplos de estas personalizaciones del controlador.In this chapter, we will learn about the examples of these controller customizations.

InstructionsInstructions

  • En el panel proyecto , escriba MotionControllers en el cuadro de búsqueda.In the Project panel, type MotionControllers in the search box . También puede encontrarlo en assets/HoloToolkit/INPUT/Prefabs/.You can also find it under Assets/HoloToolkit/Input/Prefabs/.
  • Arrastre MotionControllers recurso prefabricado en el panel jerarquía .Drag the MotionControllers prefab into the Hierarchy panel.
  • Haga clic en MotionControllers recurso prefabricado en el panel jerarquía .Click on the MotionControllers prefab in the Hierarchy panel.

MotionControllers recurso prefabricadoMotionControllers prefab

MotionControllers recurso prefabricado tiene un script MotionControllerVisualizer que proporciona las ranuras para los modelos de controladores alternativos.MotionControllers prefab has a MotionControllerVisualizer script which provides the slots for alternate controller models. Si asigna sus propios modelos 3D personalizados, como una mano o un valor de espada, y activa la casilla "usar siempre el modelo alternativo de la izquierda o la derecha", se verán en lugar del modelo predeterminado.If you assign your own custom 3D models such as a hand or a sword and check 'Always Use Alternate Left/Right Model', you will see them instead of the default model. Usaremos esta ranura en el capítulo 4 para reemplazar el modelo de controlador por un pincel.We will use this slot in Chapter 4 to replace the controller model with a brush.

MR213_ControllerVisualizer

InstruccionesInstructions

  • En el panel Inspector , haga doble clic en MotionControllerVisualizer script para ver el código en Visual StudioIn the Inspector panel, double click MotionControllerVisualizer script to see the code in the Visual Studio

Script MotionControllerVisualizerMotionControllerVisualizer script

Las clases MotionControllerVisualizer y MotionControllerInfo proporcionan los medios para tener acceso a & modificar los modelos de controlador predeterminados.The MotionControllerVisualizer and MotionControllerInfo classes provide the means to access & modify the default controller models. MotionControllerVisualizer se suscribe al evento InteractionSourceDetected de Unity y crea automáticamente instancias de los modelos de controlador cuando se encuentran.MotionControllerVisualizer subscribes to Unity's InteractionSourceDetected event and automatically instantiates controller models when they are found.

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

Los modelos de controlador se entregan según la especificación glTF.The controller models are delivered according to the glTF specification. Este formato se ha creado para proporcionar un formato común, a la vez que mejora el proceso que subyace a la transmisión y desempaquetado de recursos 3D.This format has been created to provide a common format, while improving the process behind transmitting and unpacking 3D assets. En este caso, es necesario recuperar y cargar los modelos de controlador en tiempo de ejecución, ya que queremos que la experiencia del usuario sea lo más fluida posible y no se garantice qué versión de los controladores de movimiento puede estar usando el usuario.In this case, we need to retrieve and load the controller models at runtime, as we want to make the user's experience as seamless as possible, and it's not guaranteed which version of the motion controllers the user might be using. Este curso, a través del kit de herramientas de la realidad mixta, usa una versión del proyecto UnityGLTFdel Grupo Khronos.This course, via the Mixed Reality Toolkit, uses a version of the Khronos Group's UnityGLTF project.

Una vez que se ha entregado el controlador, los scripts pueden usar MotionControllerInfo para buscar las transformaciones de elementos de controlador específicos para que puedan colocarse correctamente.Once the controller has been delivered, scripts can use MotionControllerInfo to find the transforms for specific controller elements so they can correctly position themselves.

En un capítulo posterior, se aprenderá a usar estos scripts para adjuntar elementos de interfaz de usuario a los controladores.In a later chapter, we will learn how to use these scripts to attach UI elements to the controllers.

En algunos scripts, encontrará bloques de código con #if. UNITY_EDITOR o UNITY_WSA . Estos bloques de código solo se ejecutan en el tiempo de ejecución de UWP al implementar en Windows. Esto se debe a que el conjunto de API que usa el editor de Unity y el tiempo de ejecución de la aplicación para UWP son diferentes.In some scripts, you will find code blocks with #if !UNITY_EDITOR or UNITY_WSA . These code blocks run only on the UWP runtime when you deploy to Windows. This is because the set of APIs used by the Unity editor and the UWP app runtime are different.

  • Guarde la escena y haga clic en el botón reproducir .Save the scene and click the play button.

Podrá ver la escena con controladores de movimiento en el casco.You will be able to see the scene with motion controllers in your headset. Puede ver animaciones detalladas para los clics de botón, el movimiento del stick analógico y el resaltado táctil de Touchpad.You can see detailed animations for button clicks, thumbstick movement, and touchpad touch highlighting.

MR213_Controller valor predeterminado de visualización

Capítulo 2: adjuntar elementos de la interfaz de usuario al controladorChapter 2 - Attaching UI elements to the controller

ObjetivosObjectives

  • Más información sobre los elementos de los controladores de movimientoLearn about the elements of the motion controllers
  • Obtenga información acerca de cómo adjuntar objetos a partes específicas de los controladoresLearn how to attach objects to specific parts of the controllers

En este capítulo, aprenderá a agregar elementos de la interfaz de usuario al controlador, al que el usuario puede acceder y manipular fácilmente en cualquier momento.In this chapter, you will learn how to add user interface elements to the controller which the user can easily access and manipulate at anytime. También aprenderá a agregar una interfaz de usuario del selector de colores simple mediante la entrada del panel táctil.You will also learn how to add a simple color picker UI using the touchpad input.

InstructionsInstructions

  • En el panel proyecto , busque el script MotionControllerInfo .In the Project panel, search MotionControllerInfo script.
  • En el resultado de la búsqueda, haga doble clic en MotionControllerInfo script para ver el código en Visual Studio.From the search result, double click MotionControllerInfo script to see the code in Visual Studio.

Script MotionControllerInfoMotionControllerInfo script

El primer paso es elegir a qué elemento del controlador desea asociar la interfaz de usuario.The first step is to choose which element of the controller you want the UI to attach to. Estos elementos se definen en ControllerElementEnum en MotionControllerInfo.CS .These elements are defined in ControllerElementEnum in MotionControllerInfo.cs .

MR213 MotionControllerElements

  • Página principalHome
  • MENUMenu
  • VisiónGrasp
  • PalancaThumbstick
  • SelectSelect
  • Panel táctilTouchpad
  • Pose de puntero : este elemento representa la punta de la dirección de reenvío hacia delante del controlador.Pointing pose – this element represents the tip of the controller pointing forward direction.

InstruccionesInstructions

  • En el panel proyecto , busque el script AttachToController .In the Project panel, search AttachToController script.
  • En el resultado de la búsqueda, haga doble clic en AttachToController script para ver el código en Visual Studio.From the search result, double click AttachToController script to see the code in Visual Studio.

Script AttachToControllerAttachToController script

El script AttachToController proporciona una manera sencilla de adjuntar cualquier objeto a un elemento y una manecilla de controlador especificados.The AttachToController script provides a simple way to attach any objects to a specified controller handedness and element.

En AttachElementToController () ,In AttachElementToController() ,

  • Comprobar la mano mediante MotionControllerInfo. HandlCheck handedness using MotionControllerInfo.Handedness
  • Obtiene un elemento específico del controlador mediante MotionControllerInfo. TryGetElement ()Get specific element of the controller using MotionControllerInfo.TryGetElement()
  • Después de recuperar la transformación del elemento del modelo del controlador, el objeto primario que se encuentra en él y establecer la posición local del objeto & la rotación en cero.After retrieving the element's transform from the controller model, parent the object under it and set object's local position & rotation to zero.
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;
     }
}

La manera más sencilla de usar el script AttachToController es heredar de él, como hemos hecho en el caso de ColorPickerWheel.The simplest way to use AttachToController script is to inherit from it, as we've done in the case of ColorPickerWheel. Simplemente invalide las funciones OnAttachToController y OnDetachFromController para realizar la instalación o el desglose cuando el controlador se detecta o se desconecta.Simply override the OnAttachToController and OnDetachFromController functions to perform your setup / breakdown when the controller is detected / disconnected.

InstruccionesInstructions

  • En el panel proyecto , escriba en el cuadro de búsqueda ColorPickerWheel .In the Project panel, type in the search box ColorPickerWheel . También puede encontrarlo en assets/AppPrefabs/.You can also find it under Assets/AppPrefabs/.
  • Arrastre ColorPickerWheel recurso prefabricado en el panel jerarquía .Drag ColorPickerWheel prefab into the Hierarchy panel.
  • Haga clic en ColorPickerWheel recurso prefabricado en el panel jerarquía .Click the ColorPickerWheel prefab in the Hierarchy panel.
  • En el panel Inspector , haga doble clic en ColorPickerWheel script para ver el código en Visual Studio.In the Inspector panel, double click ColorPickerWheel Script to see the code in Visual Studio.

ColorPickerWheel recurso prefabricado

Script ColorPickerWheelColorPickerWheel script

Dado que ColorPickerWheel hereda AttachToController , muestra la mano y el elemento en el panel del Inspector .Since ColorPickerWheel inherits AttachToController , it shows Handedness and Element in the Inspector panel. Vamos a asociar la interfaz de usuario al elemento Touchpad del controlador izquierdo.We'll be attaching the UI to the Touchpad element on the left controller.

Script ColorPickerWheel

ColorPickerWheel invalida OnAttachToController y OnDetachFromController para suscribirse al evento de entrada que se usará en el capítulo siguiente para la selección de color con entrada de Touchpad.ColorPickerWheel overrides the OnAttachToController and OnDetachFromController to subscribe to the input event which will be used in next chapter for color selection with touchpad input.

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;
    }
    ...
}
  • Guarde la escena y haga clic en el botón reproducir .Save the scene and click the play button.

Método alternativo para adjuntar objetos a los controladoresAlternative method for attaching objects to the controllers

Se recomienda que los scripts hereden de AttachToController e invalide OnAttachToController .We recommend that your scripts inherit from AttachToController and override OnAttachToController . Sin embargo, esto no siempre es posible.However, this may not always be possible. Una alternativa es usarla como componente independiente.An alternative is using it as a standalone component. Esto puede ser útil si desea adjuntar un recurso prefabricado existente a un controlador sin refactorizar los scripts.This can be useful when you want to attach an existing prefab to a controller without refactoring your scripts. Basta con que la clase espere a que Isattached (se establezca en true antes de realizar la instalación.Simply have your class wait for IsAttached to be set to true before performing any setup. La manera más sencilla de hacerlo es usar una corutina para ' Start '.The simplest way to do this is by using a coroutine for 'Start.'

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

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

    // Perform setup here
}

Capítulo 3: trabajar con la entrada de TouchpadChapter 3 - Working with touchpad input

ObjetivosObjectives

  • Obtenga información sobre cómo obtener eventos de datos de entrada de TouchpadLearn how to get touchpad input data events
  • Aprenda a usar la información de posición del eje Touchpad para la experiencia de la aplicaciónLearn how to use touchpad axis position information for your app experience

InstructionsInstructions

  • En el panel jerarquía , haga clic en ColorPickerWheelIn the Hierarchy panel, click ColorPickerWheel
  • En el panel Inspector , en animación , haga doble clic en ColorPickerWheelControllerIn the Inspector panel, under Animator , double click ColorPickerWheelController
  • Podrá ver la pestaña animador abiertaYou will be able to see Animator tab opened

Mostrar u ocultar la interfaz de usuario con el controlador de animación de UnityShowing/hiding UI with Unity's Animation controller

Para mostrar y ocultar la interfaz de usuario de ColorPickerWheel con la animación, usamos el sistema de animación de Unity.To show and hide the ColorPickerWheel UI with animation, we are using Unity's animation system. Si se establece la propiedad visible de ColorPickerWheel en los desencadenadores true o false, se muestran y ocultan los desencadenadores de animación.Setting the ColorPickerWheel 's Visible property to true or false triggers Show and Hide animation triggers. Los parámetros de Mostrar y ocultar se definen en el controlador de animación ColorPickerWheelController .Show and Hide parameters are defined in the ColorPickerWheelController animation controller.

Controlador de animación de Unity

InstruccionesInstructions

  • En el panel jerarquía , seleccione ColorPickerWheel recurso prefabricadoIn the Hierarchy panel, select ColorPickerWheel prefab
  • En el panel Inspector , haga doble clic en ColorPickerWheel script para ver el código en Visual StudioIn the Inspector panel, double click ColorPickerWheel script to see the code in the Visual Studio

Script ColorPickerWheelColorPickerWheel script

ColorPickerWheel se suscribe al evento InteractionSourceUpdated de Unity para escuchar eventos Touchpad.ColorPickerWheel subscribes to Unity's InteractionSourceUpdated event to listen for touchpad events.

En InteractionSourceUpdated () , el script primero comprueba para asegurarse de que:In InteractionSourceUpdated() , the script first checks to ensure that it:

  • es realmente un evento Touchpad (obj. state. touchpadTouched )is actually a touchpad event (obj.state. touchpadTouched )
  • se origina desde el controlador izquierdo (obj. state. Source). zurdo )originates from the left controller (obj.state.source. handedness )

Si ambos son true, la posición del panel táctil (obj. state. touchpadPosition ) se asigna a selectorPosition .If both are true, the touchpad position (obj.state. touchpadPosition ) is assigned to selectorPosition .

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

En Update () , en función de la propiedad visible , desencadena los desencadenadores Mostrar y ocultar animación en el componente de animación del selector de colores.In Update() , based on visible property, it triggers Show and Hide animation triggers in the color picker's animator component

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

En Update () , selectorPosition se usa para convertir un rayo en el Colisionador de malla de la rueda de colores, que devuelve una posición UV.In Update() , selectorPosition is used to cast a ray at the color wheel's mesh collider, which returns a UV position. Esta posición se puede usar para buscar la coordenada de píxeles y el valor de color de la textura de la rueda de colores.This position can then be used to find the pixel coordinate and color value of the color wheel's texture. Este valor es accesible para otros scripts a través de la propiedad SelectedColor .This value is accessible to other scripts via the SelectedColor property.

Rueda del selector de colores 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);
}

Capítulo 4: invalidación del modelo de controladorChapter 4 - Overriding controller model

ObjetivosObjectives

  • Obtenga información sobre cómo invalidar el modelo de controlador con un modelo 3D personalizado.Learn how to override the controller model with a custom 3D model.

MR213_BrushToolOverride

InstructionsInstructions

  • Haga clic en MotionControllers en el panel jerarquía .Click MotionControllers in the Hierarchy panel.
  • Haga clic en el círculo en el lado derecho del campo alternativo de controlador derecho .Click the circle on the right side of the Alternate Right Controller field.
  • Escriba "BrushController " y seleccione recurso prefabricado en el resultado.Type in 'BrushController ' and select the prefab from the result. Puede encontrarlo en assets/AppPrefabs/ BrushController .You can find it under Assets/AppPrefabs/ BrushController .
  • Comprobar usar siempre el modelo derecho alternativoCheck Always Use Alternate Right Model

MR213_BrushToolOverrideSlot

No es necesario que BrushController recurso prefabricado esté incluido en el panel de jerarquías .The BrushController prefab does not have to be included in the Hierarchy panel. Sin embargo, para desproteger sus componentes secundarios:However, to check out its child components:

  • En el panel proyecto , escriba BrushController y arrastre BrushController recurso prefabricado al panel jerarquía .In the Project panel, type in BrushController and drag BrushController prefab into the Hierarchy panel.

MR213_BrushTool_Prefab2

Encontrará el componente de información en BrushController .You will find the Tip component in BrushController . Usaremos su transformación para iniciar o detener las líneas de dibujo.We will use its transform to start/stop drawing lines.

  • Elimine el BrushController en el panel de jerarquías .Delete the BrushController from the Hierarchy panel.
  • Guarde la escena y haga clic en el botón reproducir .Save the scene and click the play button. Podrá ver el modelo de pincel reemplazado por el controlador de movimiento de la derecha.You will be able to see the brush model replaced the right-hand motion controller.

Capítulo 5: pintar con seleccionar entradaChapter 5 - Painting with Select input

ObjetivosObjectives

  • Obtenga información sobre cómo usar el evento de botón Seleccionar para iniciar y detener un dibujo de líneaLearn how to use the Select button event to start and stop a line drawing

InstructionsInstructions

  • Busque BrushController recurso prefabricado en el panel proyecto .Search BrushController prefab in the Project panel.
  • En el panel Inspector , haga doble clic en BrushController script para ver el código en Visual StudioIn the Inspector panel, double click BrushController Script to see the code in Visual Studio

Script BrushControllerBrushController script

BrushController se suscribe a los eventos InteractionSourcePressed y InteractionSourceReleased de InteractionManager.BrushController subscribes to the InteractionManager's InteractionSourcePressed and InteractionSourceReleased events. Cuando se desencadena el evento InteractionSourcePressed , la propiedad Draw del pincel se establece en true. Cuando se desencadena el evento InteractionSourceReleased , la propiedad Draw del pincel se establece en false.When InteractionSourcePressed event is triggered, the brush's Draw property is set to true; when InteractionSourceReleased event is triggered, the brush's Draw property is set to 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;
    }
}

Mientras Draw está establecido en true, el pincel generará puntos en una instancia de Unity LineRenderer .While Draw is set to true, the brush will generate points in an instantiated Unity LineRenderer . Se mantiene una referencia a este recurso prefabricado en el campo Stroke recurso prefabricado del pincel.A reference to this prefab is kept in the brush's Stroke Prefab field.

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

Para usar el color seleccionado actualmente en la interfaz de usuario de la rueda del selector de colores, BrushController debe tener una referencia al objeto ColorPickerWheel .To use the currently selected color from the color picker wheel UI, BrushController needs to have a reference to the ColorPickerWheel object. Dado que se crea una instancia de recurso prefabricado de BrushController en tiempo de ejecución como controlador de reemplazo, cualquier referencia a los objetos de la escena tendrá que establecerse en tiempo de ejecución.Because the BrushController prefab is instantiated at runtime as a replacement controller, any references to objects in the scene will have to be set at runtime. En este caso, usamos GameObject. FindObjectOfType para encontrar ColorPickerWheel :In this case we use GameObject.FindObjectOfType to locate the 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;
    ...
}
  • Guarde la escena y haga clic en el botón reproducir .Save the scene and click the play button. Podrá dibujar las líneas y pintar con el botón seleccionar del controlador de la derecha.You will be able to draw the lines and paint using the select button on the right-hand controller.

Capítulo 6: generación de objetos con selección de entradaChapter 6 - Object spawning with Select input

ObjetivosObjectives

  • Obtenga información sobre cómo usar los eventos de entrada del botón seleccionar y agarreLearn how to use Select and Grasp button input events
  • Obtener información sobre cómo crear instancias de objetosLearn how to instantiate objects

InstructionsInstructions

  • En el panel proyecto , escriba ObjectSpawner en el cuadro de búsqueda.In the Project panel, type ObjectSpawner in the search box. También puede encontrarlo en assets/AppPrefabs/You can also find it under Assets/AppPrefabs/

  • Arrastre ObjectSpawner recurso prefabricado en el panel jerarquía .Drag the ObjectSpawner prefab into the Hierarchy panel.

  • Haga clic en ObjectSpawner en el panel jerarquía .Click ObjectSpawner in the Hierarchy panel.

  • ObjectSpawner tiene un campo denominado origen de color .ObjectSpawner has a field named Color Source .

  • En el panel jerarquía , arrastre la referencia ColorPickerWheel a este campo.From the Hierarchy panel, drag the ColorPickerWheel reference into this field.

    Inspector de generación de objetos

  • Haga clic en ObjectSpawner recurso prefabricado en el panel jerarquía .Click the ObjectSpawner prefab in the Hierarchy panel.

  • En el panel Inspector , haga doble clic en ObjectSpawner script para ver el código en Visual Studio.In the Inspector panel, double click ObjectSpawner Script to see the code in Visual Studio.

Script ObjectSpawnerObjectSpawner script

El ObjectSpawner crea instancias de las copias de una malla primitiva (cubo, esfera, cilindro) en el espacio.The ObjectSpawner instantiates copies of a primitive mesh (cube, sphere, cylinder) into the space. Cuando se detecta un InteractionSourcePressed , comprueba la mano y si se trata de un evento InteractionSourcePressType. agarre o InteractionSourcePressType. Select .When a InteractionSourcePressed is detected it checks the handedness and if it's an InteractionSourcePressType.Grasp or InteractionSourcePressType.Select event.

Para un evento de agarre , incrementa el índice del tipo de malla actual (esfera, Cube, cylinder)For a Grasp event, it increments the index of current mesh type (sphere, cube, cylinder)

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

En el caso de un evento Select , en SpawnObject () , se crea una instancia de un nuevo objeto, no primario y se publica en el mundo.For a Select event, in SpawnObject() , a new object is instantiated, un-parented and released into the world.

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 usa ColorPickerWheel para establecer el color del material del objeto de presentación.The ObjectSpawner uses the ColorPickerWheel to set the color of the display object's material. A los objetos generados se les asigna una instancia de este material para conservar su color.Spawned objects are given an instance of this material so they will retain their color.

  • Guarde la escena y haga clic en el botón reproducir .Save the scene and click the play button.

Podrá cambiar los objetos con el botón de agarre y generar objetos con el botón seleccionar.You will be able to change the objects with the Grasp button and spawn objects with the Select button.

Creación e implementación de una aplicación en el portal de realidad mixtaBuild and deploy app to Mixed Reality Portal

  • En Unity, seleccione archivo > configuración de compilación .In Unity, select File > Build Settings .
  • Haga clic en Agregar escenas abiertas para agregar la escena actual a las escenas de la compilación .Click Add Open Scenes to add current scene to the Scenes In Build .
  • Haga clic en Generar .Click Build .
  • Cree una nueva carpeta denominada "app".Create a New Folder named "App".
  • Haga clic en la carpeta de la aplicación .Single click the App folder.
  • Haga clic en Seleccionar carpeta .Click Select Folder .
  • Cuando se haya realizado Unity, aparecerá una ventana del explorador de archivos.When Unity is done, a File Explorer window will appear.
  • Abra la carpeta de la aplicación .Open the App folder.
  • Haga doble clic en el archivo de solución de Visual Studio YourSceneName. sln .Double click YourSceneName.sln Visual Studio Solution file.
  • Con la barra de herramientas superior de Visual Studio, cambie el destino de Debug a Release y de ARM a x64 .Using the top toolbar in Visual Studio, change the target from Debug to Release and from ARM to X64 .
  • Haga clic en la flecha desplegable situada junto al botón dispositivo y seleccione equipo local .Click on the drop-down arrow next to the Device button, and select Local Machine .
  • Haga clic en depurar-> iniciar sin depurar en el menú o presione Ctrl + F5 .Click Debug -> Start Without debugging in the menu or press Ctrl + F5 .

Ahora la aplicación se crea e instala en el portal de realidad mixta.Now the app is built and installed in Mixed Reality Portal. Puede volver a iniciarlo a través del menú Inicio en el portal de realidad mixta.You can launch it again through Start menu in Mixed Reality Portal.

Herramientas de pincel de diseño avanzadas con diseño radialAdvanced design - Brush tools with radial layout

MixedReality213 Main

En este capítulo, obtendrá información sobre cómo reemplazar el modelo de controlador de movimiento predeterminado con una colección de herramientas de pincel personalizada.In this chapter, you will learn how to replace the default motion controller model with a custom brush tool collection. Como referencia, puede encontrar la escena completada MixedReality213Advanced en la carpeta Scenes .For your reference, you can find the completed scene MixedReality213Advanced under Scenes folder.

InstructionsInstructions

  • En el panel proyecto , escriba BrushSelector en el cuadro de búsqueda.In the Project panel, type BrushSelector in the search box . También puede encontrarlo en assets/AppPrefabs/You can also find it under Assets/AppPrefabs/

  • Arrastre BrushSelector recurso prefabricado en el panel jerarquía .Drag the BrushSelector prefab into the Hierarchy panel.

  • Para la organización, cree un GameObject vacío denominado brushes .For organization, create an empty GameObject called Brushes

  • Arrastre los siguientes Prefabs desde el panel proyecto a los pincelesDrag following prefabs from the Project panel into Brushes

    • Assets/AppPrefabs/ BrushFatAssets/AppPrefabs/ BrushFat
    • Assets/AppPrefabs/ BrushThinAssets/AppPrefabs/ BrushThin
    • Activos/AppPrefabs/ borradorAssets/AppPrefabs/ Eraser
    • Assets/AppPrefabs/ MarkerFatAssets/AppPrefabs/ MarkerFat
    • Assets/AppPrefabs/ MarkerThinAssets/AppPrefabs/ MarkerThin
    • Activos/AppPrefabs/ lápizAssets/AppPrefabs/ Pencil

    Pinceles

  • Haga clic en MotionControllers recurso prefabricado en el panel jerarquía .Click MotionControllers prefab in the Hierarchy panel.

  • En el panel Inspector , desactive usar modelo de derecho alternativo siempre en el visualizador de controlador de movimientoIn the Inspector panel, uncheck Always Use Alternate Right Model on the Motion Controller Visualizer

  • En el panel jerarquía , haga clic en BrushSelectorIn the Hierarchy panel, click BrushSelector

  • BrushSelector tiene un campo denominado ColorPickerBrushSelector has a field named ColorPicker

  • En el panel jerarquía , arrastre el campo ColorPickerWheel al ColorPicker en el panel Inspector .From the Hierarchy panel, drag the ColorPickerWheel into ColorPicker field in the Inspector panel.

    Asignar ColorPickerWheel al selector de pincel

  • En el panel jerarquía , en BrushSelector recurso prefabricado, seleccione el objeto de menú .In the Hierarchy panel, under BrushSelector prefab, select the Menu object.

  • En el panel Inspector , en el componente LineObjectCollection , abra la lista desplegable de la matriz de objetos .In the Inspector panel, under the LineObjectCollection component, open the Objects array dropdown. Verá 6 ranuras vacías.You will see 6 empty slots.

  • En el panel jerarquía , arrastre cada uno de los Prefabs primarios bajo los pinceles GameObject a estas ranuras en cualquier orden.From the Hierarchy panel, drag each of the prefabs parented under the Brushes GameObject into these slots in any order. (Asegúrese de que está arrastrando el Prefabs de la escena, no el Prefabs en la carpeta del proyecto).(Make sure you're dragging the prefabs from the scene, not the prefabs in the project folder.)

Selector de pincel

BrushSelector recurso prefabricadoBrushSelector prefab

Dado que BrushSelector hereda AttachToController , muestra las opciones de la mano y el elemento en el panel del Inspector .Since the BrushSelector inherits AttachToController , it shows Handedness and Element options in the Inspector panel. Hemos seleccionado right y Pointing para adjuntar herramientas de pincel al controlador de la derecha con dirección hacia delante.We selected Right and Pointing Pose to attach brush tools to the right hand controller with forward direction.

El BrushSelector hace uso de dos utilidades:The BrushSelector makes use of two utilities:

  • Ellipse : se usa para generar puntos en el espacio a lo largo de una forma de elipse.Ellipse : used to generate points in space along an ellipse shape.
  • LineObjectCollection : distribuye objetos usando los puntos generados por cualquier clase de línea (por ejemplo, elipse).LineObjectCollection : distributes objects using the points generated by any Line class (eg, Ellipse). Esto es lo que vamos a usar para colocar los pinceles a lo largo de la forma de elipse.This is what we'll be using to place our brushes along the Ellipse shape.

Cuando se combinan, estas utilidades se pueden usar para crear un menú radial.When combined, these utilities can be used to create a radial menu.

Script LineObjectCollectionLineObjectCollection script

LineObjectCollection tiene controles para el tamaño, la posición y la rotación de objetos distribuidos a lo largo de su línea.LineObjectCollection has controls for the size, position and rotation of objects distributed along its line. Esto resulta útil para crear menús radiales como el selector de pincel.This is useful for creating radial menus like the brush selector. Para crear la apariencia de los pinceles que se escalan verticalmente desde cero a medida que se aproximan a la posición seleccionada del centro, los picos de la curva ObjectScale en el centro y en las cintas se desconectan en los bordes.To create the appearance of brushes that scale up from nothing as they approach the center selected position, the ObjectScale curve peaks in the center and tapers off at the edges.

Script BrushSelectorBrushSelector script

En el caso de BrushSelector , hemos elegido usar la animación de procedimientos.In the case of the BrushSelector , we've chosen to use procedural animation. En primer lugar, el script LineObjectCollection distribuye los modelos de pincel en una elipse.First, brush models are distributed in an ellipse by the LineObjectCollection script. Después, cada pincel es responsable de mantener su posición en la mano del usuario en función de su valor de DisplayMode , que cambia en función de la selección.Then, each brush is responsible for maintaining its position in the user's hand based on its DisplayMode value, which changes based on the selection. Elegimos un enfoque de procedimiento debido a la alta probabilidad de que las transiciones de posición del pincel se interrumpan cuando el usuario selecciona pinceles.We chose a procedural approach because of the high probability of brush position transitions being interrupted as the user selects brushes. Las animaciones Mecanim pueden controlar las interrupciones correctamente, pero suelen ser más complicadas que una sencilla operación lerp.Mecanim animations can handle interruptions gracefully, but it tends to be more complicated than a simple Lerp operation.

BrushSelector usa una combinación de ambos.BrushSelector uses a combination of both. Cuando se detecta la entrada del panel táctil, las opciones de pincel se vuelven visibles y se escalan verticalmente a lo largo del menú radial.When touchpad input is detected, brush options become visible and scale up along the radial menu. Después de un período de tiempo de espera (que indica que el usuario ha realizado una selección), las opciones de pincel se vuelven a reducir de nuevo y solo se mantiene el pincel seleccionado.After a timeout period (which indicates that the user has made a selection) the brush options scale down again, leaving only the selected brush.

Visualización de la entrada del panel táctilVisualizing touchpad input

Incluso en los casos en los que el modelo de controlador se ha reemplazado por completo, puede resultar útil Mostrar la entrada en las entradas del modelo original.Even in cases where the controller model has been completely replaced, it can be helpful to show input on the original model inputs. Esto ayuda a realizar las acciones del usuario en realidad.This helps to ground the user's actions in reality. En el caso de BrushSelector , hemos optado por hacer que el Touchpad esté brevemente visible cuando se recibe la entrada.For the BrushSelector we've chosen to make the touchpad briefly visible when the input is received. Para ello, se recupera el elemento Touchpad del controlador, se sustituye su material por un material personalizado y, después, se aplica un degradado al color de ese material en función de la última vez que se recibió la entrada Touchpad.This was done by retrieving the Touchpad element from the controller, replacing its material with a custom material, then applying a gradient to that material's color based on the last time touchpad input was received.

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

Selección de la herramienta pincel con entrada TouchpadBrush tool selection with touchpad input

Cuando el selector de pincel detecta la entrada presionada del Touchpad, comprueba la posición de la entrada para determinar si estaba a la izquierda o a la derecha.When the brush selector detects touchpad's pressed input, it checks the position of the input to determine if it was to the left or right.

Grosor del trazo con selectPressedAmountStroke thickness with selectPressedAmount

En lugar del evento InteractionSourcePressType. Select en InteractionSourcePressed () , puede obtener el valor analógico de la cantidad presionada a través de selectPressedAmount .Instead of the InteractionSourcePressType.Select event in the InteractionSourcePressed() , you can get the analog value of the pressed amount through selectPressedAmount . Este valor se puede recuperar en InteractionSourceUpdated () .This value can be retrieved in 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;
            }
        }
    }
}

Script de borradorEraser script

El borrador es un tipo especial de pincel que reemplaza la función DrawOverTime () del pincel base.Eraser is a special type of brush that overrides the base Brush 's DrawOverTime() function. Mientras que Draw es true, el borrador comprueba si su sugerencia se corta con cualquier trazo de pincel existente.While Draw is true, the eraser checks to see if its tip intersects with any existing brush strokes. Si lo hace, se agregan a una cola para que se reduzcan y se eliminen.If it does, they are added to a queue to be shrunk down and deleted.

Diseño avanzado: teleportabilidad y LocomotionAdvanced design - Teleportation and locomotion

Si desea permitir que el usuario se mueva por la escena con la teleportabilidad mediante el Stick, use MixedRealityCameraParent en lugar de MixedRealityCamera .If you want to allow the user to move around the scene with teleportation using thumbstick, use MixedRealityCameraParent instead of MixedRealityCamera . También debe agregar InputManager y DefaultCursor .You also need to add InputManager and DefaultCursor . Dado que MixedRealityCameraParent ya incluye MotionControllers y el límite como componentes secundarios, debe quitar MotionControllers y recurso prefabricado de entorno existentes.Since MixedRealityCameraParent already includes MotionControllers and Boundary as child components, you should remove existing MotionControllers and Environment prefab.

InstructionsInstructions

  • En el panel jerarquía , elimine MixedRealityCamera , Environment y MotionControllersIn the Hierarchy panel, delete MixedRealityCamera , Environment and MotionControllers

  • En el panel Proyecto , busque y arrastre el siguiente Prefabs al panel jerarquía :From the Project panel , search and drag the following prefabs into the Hierarchy panel:

    • Assets/AppPrefabs/INPUT/Prefabs/ MixedRealityCameraParentAssets/AppPrefabs/Input/Prefabs/ MixedRealityCameraParent
    • Assets/AppPrefabs/INPUT/Prefabs/ InputManagerAssets/AppPrefabs/Input/Prefabs/ InputManager
    • Assets/AppPrefabs/INPUT/Prefabs/cursor/ DefaultCursorAssets/AppPrefabs/Input/Prefabs/Cursor/ DefaultCursor

    Cámara principal de realidad mixta

  • En el panel jerarquía , haga clic en Administrador de entrada .In the Hierarchy panel, click Input Manager

  • En el panel Inspector , desplácese hacia abajo hasta la sección selector simple de puntero único .In the Inspector panel, scroll down to the Simple Single Pointer Selector section

  • En el panel jerarquía , arrastre DefaultCursor al campo cursor .From the Hierarchy panel, drag DefaultCursor into Cursor field

    Asignación de DefaultCursor

  • Guarde la escena y haga clic en el botón reproducir .Save the scene and click the play button. Podrá usar el stick analógico para girar izquierda/derecha o teletranspórtate.You will be able to use the thumbstick to rotate left/right or teleport.

FinThe end

Y este es el final de este tutorial.And that's the end of this tutorial! Ha aprendido:You learned:

  • Cómo trabajar con modelos de controlador de movimiento en el modo de juego y el tiempo de ejecución de Unity.How to work with motion controller models in Unity's game mode and runtime.
  • Cómo usar diferentes tipos de eventos de botón y sus aplicaciones.How to use different types of button events and their applications.
  • Cómo superponer los elementos de la interfaz de usuario en la parte superior del controlador o personalizarlos totalmente.How to overlay UI elements on top of the controller or fully customize it.

Ya está listo para empezar a crear su propia experiencia envolvente con los controladores de movimiento.You are now ready to start creating your own immersive experience with motion controllers!

Escenas completadasCompleted scenes

  • En el panel del proyecto de Unity, haga clic en la carpeta Scenes .In Unity's Project panel click on the Scenes folder.
  • Encontrará dos escenas de Unity MixedReality213 y MixedReality213Advanced .You will find two Unity scenes MixedReality213 and MixedReality213Advanced .
    • MixedReality213 : escena completada con un solo pincelMixedReality213 : Completed scene with single brush
    • MixedReality213Advanced : escena completada con varios pinceles en el ejemplo de la cantidad de imprenta del botón seleccionarMixedReality213Advanced : Completed scene with multiple brush with select button's press amount example

Consulte tambiénSee also