HoloLens (prima generazione) Informazioni di base 101E: Completare il progetto con l'emulatore
Importante
Le esercitazioni di Realtà mista Academy sono state progettate con HoloLens (prima generazione), Unity 2017 e Realtà mista visori VR immersive. Pertanto, riteniamo importante lasciarle a disposizione degli sviluppatori a cui serve ancora materiale sussidiario per lo sviluppo di questi dispositivi. Queste esercitazioni non verranno aggiornate con i set di strumenti o le interazioni più recenti usati per HoloLens 2 e potrebbero non essere compatibili con le versioni più recenti di Unity. Rimarranno invariate per consentire di continuare a lavorare sui dispositivi supportati. Per HoloLens 2 è stata pubblicata una nuova serie di esercitazioni.
Questa esercitazione illustra un progetto completo, integrato in Unity, che illustra le principali funzionalità di Windows Mixed Reality in HoloLens, tra cui sguardo fisso, movimenti, input vocale, audio spaziale e mapping spaziale. Il completamento dell'esercitazione richiederà circa 1 ora.
Supporto di dispositivi
Corso | HoloLens | Visori VR immersive |
---|---|---|
Nozioni di base MR 101E: Progetto completo con emulatore | ✔️ |
Prima di iniziare
Prerequisiti
- Un PC Windows 10 configurato con gli strumenti corretti installati.
File di progetto
- Scaricare i file richiesti dal progetto. Richiede Unity 2017.2 o versione successiva.
- Se è ancora necessario il supporto di Unity 5.6, usare questa versione.
- Se è ancora necessario il supporto di Unity 5.5, usare questa versione.
- Se è ancora necessario il supporto di Unity 5.4, usare questa versione.
- Annullare l'archiviazione dei file nel desktop o in un altro percorso facile da raggiungere. Mantenere il nome della cartella come Origami.
Nota
Se si vuole esaminare il codice sorgente prima del download, è disponibile in GitHub.
Capitolo 1 - Mondo "Holo"
In questo capitolo verrà configurato il primo progetto Unity e verrà illustrato il processo di compilazione e distribuzione.
Obiettivi
- Configurare Unity per lo sviluppo olografico.
- Creare un ologramma.
- Vedi un ologramma creato.
Istruzioni
- Riavviare Unity.
- Selezionare Open (Apri).
- Immettere il percorso come cartella Origami non archiviata in precedenza.
- Selezionare Origami e fare clic su Seleziona cartella.
- Salvare la nuova scena: Salva / scena file con nome.
- Assegnare alla scena il nome Origami e premere il pulsante Salva .
Configurare la fotocamera principale
- Nel Pannello di gerarchia, selezionare Fotocamera principale.
- In Inspector imposta la posizione di trasformazione su 0.0.0.
- Trovare la proprietà Clear Flags e modificare l'elenco a discesa da Skybox a Tinta unita.
- Fare clic sul campo Sfondo per aprire un editor dei colori.
- Impostare R, G, B e A su 0.
Configurare la scena
- Nel pannello Gerarchia fare clic su Crea e crea vuoto.
- Fare clic con il pulsante destro del mouse sul nuovo GameObject e scegliere Rinomina. Rinominare GameObject in OrigamiCollection.
- Dalla cartella Holograms nel pannello del progetto:
- Trascinare Stage nella gerarchia per essere un elemento figlio di OrigamiCollection.
- Trascinare Sphere1 nella gerarchia come elemento figlio di OrigamiCollection.
- Trascinare Sphere2 nella gerarchia come figlio di OrigamiCollection.
- Fare clic con il pulsante destro del mouse sull'oggetto Directional Light nel pannello Gerarchia e scegliere Elimina.
- Dalla cartella Holograms trascinare Lights nella radice del Pannello gerarchia.
- Nella gerarchia selezionare OrigamiCollection.
- In Inspector (Controllo) impostare la posizione di trasformazione su 0, -0.5, 2.0.
- Premere il pulsante Riproduci in Unity per visualizzare in anteprima gli ologrammi.
- Gli oggetti Origami verranno visualizzati nella finestra di anteprima.
- Premere Riproduci una seconda volta per arrestare la modalità di anteprima.
Esportare il progetto da Unity a Visual Studio
- In Unity selezionare Impostazioni compilazione file>.
- Selezionare Windows Store nell'elenco Piattaforma e fare clic su Cambia piattaforma.
- Impostare SDK su Universale 10 e Tipo di compilazione su D3D.
- Selezionare Progetti C# unity.
- Fare clic su Aggiungi scene aperte per aggiungere la scena.
- Fare clic su Impostazioni lettore....
- Nel Pannello di controllo selezionare il logo di Windows Store. Selezionare quindi Impostazioni di pubblicazione.
- Nella sezione Funzionalità selezionare le funzionalità Microfono e SpatialPerception .
- Nella finestra Build Settings (Impostazioni compilazione) fare clic su Build (Compila).
- Creare una nuova cartella denominata "App".
- Fare clic sulla cartella dell'app.
- Premere Seleziona cartella.
- Al termine di Unity, verrà visualizzata una finestra di Esplora file.
- Aprire la cartella App .
- Aprire la soluzione Origami di Visual Studio.
- Usando la barra degli strumenti superiore in Visual Studio, modificare la destinazione da Debug a Rilascio e da ARM a X86.
- Fare clic sulla freccia accanto al pulsante Dispositivo e selezionare Emulatore HoloLens.
- Fare clic su Debug -> Avvia senza eseguire il debug o premere CTRL+F5.
- Dopo qualche tempo l'emulatore inizierà con il progetto Origami. Quando si avvia per la prima volta l'emulatore, l'avvio dell'emulatore può richiedere fino a 15 minuti. Una volta avviato, non chiuderlo.
Capitolo 2 - Sguardo fisso
In questo capitolo verranno presentati i primi tre modi per interagire con gli ologrammi, ovvero lo sguardo fisso.
Obiettivi
- Visualizzare lo sguardo fisso usando un cursore bloccato dal mondo.
Istruzioni
- Indietro al progetto Unity e chiudere la finestra Impostazioni di compilazione se è ancora aperta.
- Selezionare la cartella Holograms nel pannello Progetto.
- Trascinare l'oggetto Cursor nel pannello Hierarchy (Gerarchia ) a livello radice.
- Fare doppio clic sull'oggetto Cursor per esaminarlo più da vicino.
- Fare clic con il pulsante destro del mouse sulla cartella Script nel pannello Progetto.
- Fare clic sul sottomenu Crea .
- Selezionare Script C#.
- Assegnare allo script il nome WorldCursor. Nota: il nome fa distinzione tra maiuscole e minuscole. Non è necessario aggiungere l'estensione cs.
- Selezionare l'oggetto Cursor nel pannello Hierarchy (Gerarchia).
- Trascinare e rilasciare lo script WorldCursor nel pannello Inspector (Controllo).
- Fare doppio clic sullo script WorldCursor per aprirlo in Visual Studio.
- Copiare e incollare questo codice in WorldCursor.cs e Salvare tutto.
using UnityEngine;
public class WorldCursor : MonoBehaviour
{
private MeshRenderer meshRenderer;
// Use this for initialization
void Start()
{
// Grab the mesh renderer that's on the same object as this script.
meshRenderer = this.gameObject.GetComponentInChildren<MeshRenderer>();
}
// Update is called once per frame
void Update()
{
// Do a raycast into the world based on the user's
// head position and orientation.
var headPosition = Camera.main.transform.position;
var gazeDirection = Camera.main.transform.forward;
RaycastHit hitInfo;
if (Physics.Raycast(headPosition, gazeDirection, out hitInfo))
{
// If the raycast hit a hologram...
// Display the cursor mesh.
meshRenderer.enabled = true;
// Move thecursor to the point where the raycast hit.
this.transform.position = hitInfo.point;
// Rotate the cursor to hug the surface of the hologram.
this.transform.rotation = Quaternion.FromToRotation(Vector3.up, hitInfo.normal);
}
else
{
// If the raycast did not hit a hologram, hide the cursor mesh.
meshRenderer.enabled = false;
}
}
}
- Ricompilare l'app dalle impostazioni di compilazione file>.
- Tornare alla soluzione di Visual Studio usata in precedenza per la distribuzione nell'emulatore.
- Selezionare "Ricarica tutto" quando richiesto.
- Fare clic su Debug -> Avvia senza eseguire il debug o premere CTRL+F5.
- Usa il controller Xbox per esaminare la scena. Si noti che il cursore interagisce con la forma degli oggetti.
Capitolo 3 - Movimenti
In questo capitolo verrà aggiunto il supporto per i movimenti. Quando l'utente seleziona una sfera di carta, la sfera cadrà attivando la gravità usando il motore di fisica di Unity.
Obiettivi
- Controllare gli ologrammi con il movimento Seleziona.
Istruzioni
Si inizierà creando uno script rispetto a quello che è possibile rilevare il movimento Seleziona.
- Nella cartella Scripts creare uno script denominato GazeGestureManager.
- Trascinare lo script GazeGestureManager nell'oggetto OrigamiCollection nella gerarchia.
- Aprire lo script GazeGestureManager in Visual Studio e aggiungere il codice seguente:
using UnityEngine;
using UnityEngine.XR.WSA.Input;
public class GazeGestureManager : MonoBehaviour
{
public static GazeGestureManager Instance { get; private set; }
// Represents the hologram that is currently being gazed at.
public GameObject FocusedObject { get; private set; }
GestureRecognizer recognizer;
// Use this for initialization
void Start()
{
Instance = this;
// Set up a GestureRecognizer to detect Select gestures.
recognizer = new GestureRecognizer();
recognizer.Tapped += (args) =>
{
// Send an OnSelect message to the focused object and its ancestors.
if (FocusedObject != null)
{
FocusedObject.SendMessageUpwards("OnSelect", SendMessageOptions.DontRequireReceiver);
}
};
recognizer.StartCapturingGestures();
}
// Update is called once per frame
void Update()
{
// Figure out which hologram is focused this frame.
GameObject oldFocusObject = FocusedObject;
// Do a raycast into the world based on the user's
// head position and orientation.
var headPosition = Camera.main.transform.position;
var gazeDirection = Camera.main.transform.forward;
RaycastHit hitInfo;
if (Physics.Raycast(headPosition, gazeDirection, out hitInfo))
{
// If the raycast hit a hologram, use that as the focused object.
FocusedObject = hitInfo.collider.gameObject;
}
else
{
// If the raycast did not hit a hologram, clear the focused object.
FocusedObject = null;
}
// If the focused object changed this frame,
// start detecting fresh gestures again.
if (FocusedObject != oldFocusObject)
{
recognizer.CancelGestures();
recognizer.StartCapturingGestures();
}
}
}
- Creare un altro script nella cartella Scripts, questa volta denominata SphereCommands.
- Espandere l'oggetto OrigamiCollection nella visualizzazione Hierarchy.Expand the OrigamiCollection object in the Hierarchy view.
- Trascinare lo script SphereCommands nell'oggetto Sphere1 nel pannello Hierarchy (Gerarchia).
- Trascinare lo script SphereCommands nell'oggetto Sphere2 nel pannello Hierarchy (Gerarchia).
- Aprire lo script in Visual Studio per la modifica e sostituire il codice predefinito con questo:
using UnityEngine;
public class SphereCommands : MonoBehaviour
{
// Called by GazeGestureManager when the user performs a Select gesture
void OnSelect()
{
// If the sphere has no Rigidbody component, add one to enable physics.
if (!this.GetComponent<Rigidbody>())
{
var rigidbody = this.gameObject.AddComponent<Rigidbody>();
rigidbody.collisionDetectionMode = CollisionDetectionMode.Continuous;
}
}
}
- Esportare, compilare e distribuire l'app nell'emulatore HoloLens.
- Guarda la scena e centra una delle sfere.
- Premere il pulsante A sul controller Xbox o premere la barra spaziatrice per simulare il movimento Seleziona.
Capitolo 4 - Voce
In questo capitolo si aggiungerà il supporto per due comandi vocali: "Reset world" per restituire le sfere rilasciate nella posizione originale e "Drop sphere" per far cadere la sfera.
Obiettivi
- Aggiungere comandi vocali che sono sempre in ascolto in background.
- Creare un ologramma che reagisca a un comando vocale.
Istruzioni
- Nella cartella Scripts creare uno script denominato SpeechManager.
- Trascinare lo script SpeechManager nell'oggetto OrigamiCollection nella gerarchia
- Aprire lo script SpeechManager in Visual Studio.
- Copiare e incollare questo codice in SpeechManager.cs e salvare tutto:
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.Windows.Speech;
public class SpeechManager : MonoBehaviour
{
KeywordRecognizer keywordRecognizer = null;
Dictionary<string, System.Action> keywords = new Dictionary<string, System.Action>();
// Use this for initialization
void Start()
{
keywords.Add("Reset world", () =>
{
// Call the OnReset method on every descendant object.
this.BroadcastMessage("OnReset");
});
keywords.Add("Drop Sphere", () =>
{
var focusObject = GazeGestureManager.Instance.FocusedObject;
if (focusObject != null)
{
// Call the OnDrop method on just the focused object.
focusObject.SendMessage("OnDrop", SendMessageOptions.DontRequireReceiver);
}
});
// Tell the KeywordRecognizer about our keywords.
keywordRecognizer = new KeywordRecognizer(keywords.Keys.ToArray());
// Register a callback for the KeywordRecognizer and start recognizing!
keywordRecognizer.OnPhraseRecognized += KeywordRecognizer_OnPhraseRecognized;
keywordRecognizer.Start();
}
private void KeywordRecognizer_OnPhraseRecognized(PhraseRecognizedEventArgs args)
{
System.Action keywordAction;
if (keywords.TryGetValue(args.text, out keywordAction))
{
keywordAction.Invoke();
}
}
}
- Aprire lo script SphereCommands in Visual Studio.
- Aggiornare lo script per la lettura come indicato di seguito:
using UnityEngine;
public class SphereCommands : MonoBehaviour
{
Vector3 originalPosition;
// Use this for initialization
void Start()
{
// Grab the original local position of the sphere when the app starts.
originalPosition = this.transform.localPosition;
}
// Called by GazeGestureManager when the user performs a Select gesture
void OnSelect()
{
// If the sphere has no Rigidbody component, add one to enable physics.
if (!this.GetComponent<Rigidbody>())
{
var rigidbody = this.gameObject.AddComponent<Rigidbody>();
rigidbody.collisionDetectionMode = CollisionDetectionMode.Continuous;
}
}
// Called by SpeechManager when the user says the "Reset world" command
void OnReset()
{
// If the sphere has a Rigidbody component, remove it to disable physics.
var rigidbody = this.GetComponent<Rigidbody>();
if (rigidbody != null)
{
rigidbody.isKinematic = true;
Destroy(rigidbody);
}
// Put the sphere back into its original local position.
this.transform.localPosition = originalPosition;
}
// Called by SpeechManager when the user says the "Drop sphere" command
void OnDrop()
{
// Just do the same logic as a Select gesture.
OnSelect();
}
}
- Esportare, compilare e distribuire l'app nell'emulatore HoloLens.
- L'emulatore supporterà il microfono del PC e risponderà alla voce: regolare la visualizzazione in modo che il cursore si trova su una delle sfere e pronunciare "Drop Sphere".
- Pronunciare "Reset World" per riportarli alle loro posizioni iniziali.
Capitolo 5 - Suono spaziale
In questo capitolo si aggiungerà musica all'app e quindi si attiveranno effetti sonori su determinate azioni. Verrà usato il suono spaziale per dare suoni a una posizione specifica nello spazio 3D.
Obiettivi
- Senti gli ologrammi nel tuo mondo.
Istruzioni
- In Unity selezionare dal menu in alto Modifica > impostazioni progetto Audio >
- Trovare l'impostazione Del plug-in spatializer e selezionare MS HRTF Spatializer.Find the Spatializer setting Spatializer and select MS HRTF Spatializer.
- Dalla cartella Holograms trascinare l'oggetto Ambience nell'oggetto OrigamiCollection nel Pannello gerarchia.
- Selezionare OrigamiCollection e trovare il componente Origine audio . Modificare queste proprietà:
- Controllare la proprietà Spatialize .
- Controlla Play On Awake.
- Modificare Spatial Blend in 3D trascinando il dispositivo di scorrimento a destra.
- Controllare la proprietà Loop .
- Espandere Impostazioni audio 3D e immettere 0.1 per Livello Doppler.
- Impostare Rolloff volume su Rolloff logaritmico.
- Impostare Max Distance (Distanza massima ) su 20.
- Nella cartella Scripts creare uno script denominato SphereSounds.
- Trascinare SphereSounds negli oggetti Sphere1 e Sphere2 nella gerarchia.
- Aprire SphereSounds in Visual Studio, aggiornare il codice seguente e Salvare tutto.
using UnityEngine;
public class SphereSounds : MonoBehaviour
{
AudioSource impactAudioSource = null;
AudioSource rollingAudioSource = null;
bool rolling = false;
void Start()
{
// Add an AudioSource component and set up some defaults
impactAudioSource = gameObject.AddComponent<AudioSource>();
impactAudioSource.playOnAwake = false;
impactAudioSource.spatialize = true;
impactAudioSource.spatialBlend = 1.0f;
impactAudioSource.dopplerLevel = 0.0f;
impactAudioSource.rolloffMode = AudioRolloffMode.Logarithmic;
impactAudioSource.maxDistance = 20f;
rollingAudioSource = gameObject.AddComponent<AudioSource>();
rollingAudioSource.playOnAwake = false;
rollingAudioSource.spatialize = true;
rollingAudioSource.spatialBlend = 1.0f;
rollingAudioSource.dopplerLevel = 0.0f;
rollingAudioSource.rolloffMode = AudioRolloffMode.Logarithmic;
rollingAudioSource.maxDistance = 20f;
rollingAudioSource.loop = true;
// Load the Sphere sounds from the Resources folder
impactAudioSource.clip = Resources.Load<AudioClip>("Impact");
rollingAudioSource.clip = Resources.Load<AudioClip>("Rolling");
}
// Occurs when this object starts colliding with another object
void OnCollisionEnter(Collision collision)
{
// Play an impact sound if the sphere impacts strongly enough.
if (collision.relativeVelocity.magnitude >= 0.1f)
{
impactAudioSource.Play();
}
}
// Occurs each frame that this object continues to collide with another object
void OnCollisionStay(Collision collision)
{
Rigidbody rigid = gameObject.GetComponent<Rigidbody>();
// Play a rolling sound if the sphere is rolling fast enough.
if (!rolling && rigid.velocity.magnitude >= 0.01f)
{
rolling = true;
rollingAudioSource.Play();
}
// Stop the rolling sound if rolling slows down.
else if (rolling && rigid.velocity.magnitude < 0.01f)
{
rolling = false;
rollingAudioSource.Stop();
}
}
// Occurs when this object stops colliding with another object
void OnCollisionExit(Collision collision)
{
// Stop the rolling sound if the object falls off and stops colliding.
if (rolling)
{
rolling = false;
impactAudioSource.Stop();
rollingAudioSource.Stop();
}
}
}
- Salvare lo script e tornare a Unity.
- Esportare, compilare e distribuire l'app nell'emulatore HoloLens.
- Indossare le cuffie per ottenere l'effetto completo, e muoversi più vicino e più lontano dalla fase per ascoltare il cambiamento dei suoni.
Capitolo 6 - Mapping spaziale
Ora useremo il mapping spaziale per posizionare la lavagna del gioco su un oggetto reale nel mondo reale.
Obiettivi
- Portare il mondo reale nel mondo virtuale.
- Posizionare gli ologrammi in cui sono più importanti per te.
Istruzioni
- Fare clic sulla cartella Holograms nel pannello Progetto.
- Trascinare l'asset Mapping spaziale nella radice della gerarchia.
- Fare clic sull'oggetto Mapping spaziale nella gerarchia.
- Nel pannello Inspector (Controllo) modificare le proprietà seguenti:
- Selezionare la casella Disegna mesh visive .
- Individuare Disegna materiale e fare clic sul cerchio a destra. Digitare "wireframe" nel campo di ricerca nella parte superiore. Fare clic sul risultato e quindi chiudere la finestra.
- Esportare, compilare e distribuire l'app nell'emulatore HoloLens.
- Quando l'app viene eseguita, verrà eseguito il rendering di una mesh di un soggiorno reale analizzato in precedenza in wireframe.
- Guarda come una sfera rotolante cadrà fuori dal palco, e sul pavimento!
Verrà ora illustrato come spostare OrigamiCollection in una nuova posizione:
- Nella cartella Scripts creare uno script denominato TapToPlaceParent.
- Nella gerarchia espandere OrigamiCollection e selezionare l'oggetto Stage .
- Trascinare lo script TapToPlaceParent nell'oggetto Stage.
- Aprire lo script TapToPlaceParent in Visual Studio e aggiornarlo in modo che sia il seguente:
using UnityEngine;
public class TapToPlaceParent : MonoBehaviour
{
bool placing = false;
// Called by GazeGestureManager when the user performs a Select gesture
void OnSelect()
{
// On each Select gesture, toggle whether the user is in placing mode.
placing = !placing;
// If the user is in placing mode, display the spatial mapping mesh.
if (placing)
{
SpatialMapping.Instance.DrawVisualMeshes = true;
}
// If the user is not in placing mode, hide the spatial mapping mesh.
else
{
SpatialMapping.Instance.DrawVisualMeshes = false;
}
}
// Update is called once per frame
void Update()
{
// If the user is in placing mode,
// update the placement to match the user's gaze.
if (placing)
{
// Do a raycast into the world that will only hit the Spatial Mapping mesh.
var headPosition = Camera.main.transform.position;
var gazeDirection = Camera.main.transform.forward;
RaycastHit hitInfo;
if (Physics.Raycast(headPosition, gazeDirection, out hitInfo,
30.0f, SpatialMapping.PhysicsRaycastMask))
{
// Move this object's parent object to
// where the raycast hit the Spatial Mapping mesh.
this.transform.parent.position = hitInfo.point;
// Rotate this object's parent object to face the user.
Quaternion toQuat = Camera.main.transform.localRotation;
toQuat.x = 0;
toQuat.z = 0;
this.transform.parent.rotation = toQuat;
}
}
}
}
- Esportare, compilare e distribuire l'app.
- A questo punto si dovrebbe essere in grado di posizionare il gioco in una posizione specifica guardandolo, usando il movimento Select (A o Barra spaziatrice) e quindi spostandosi in una nuova posizione e usando di nuovo il movimento Seleziona.
La fine
E questa è la fine di questa esercitazione!
Sono stati appresi i concetti seguenti:
- Come creare un'app olografica in Unity.
- Come usare lo sguardo fisso, il movimento, la voce, i suoni e il mapping spaziale.
- Come compilare e distribuire un'app con Visual Studio.
È ora possibile iniziare a creare app olografiche personalizzate.