Input MR 213: Controller del movimento
Nota
Le esercitazioni di Mixed Reality Academy sono state progettate in base a HoloLens (prima generazione) e ai visori VR immersive di realtà mista. 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. Rimarranno invariate per consentire di continuare a lavorare sui dispositivi supportati. Per HoloLens 2 è stata pubblicata una nuova serie di esercitazioni.
I controller di movimento nel mondo della realtà mista aggiungono un altro livello di interattività. Con i controller di movimento, è possibile interagire direttamente con gli oggetti in modo più naturale, simile alle interazioni fisiche nella vita reale, aumentando l'immersione e la gioia nell'esperienza dell'app.
In MR Input 213 si esamineranno gli eventi di input del controller di movimento creando un'esperienza di pittura spaziale semplice. Con questa app, gli utenti possono dipingere nello spazio tridimensionale con vari tipi di pennelli e colori.
Argomenti illustrati in questa esercitazione
Visualizzazione controller | Eventi di input del controller | Controller e interfaccia utente personalizzati |
Informazioni su come eseguire il rendering dei modelli del controller di movimento in modalità gioco e runtime di Unity. | Informazioni su diversi tipi di eventi del pulsante e sulle relative applicazioni. | Informazioni su come sovrapporre gli elementi dell'interfaccia utente sopra il controller o personalizzarlo completamente. |
Supporto di dispositivi
Corso | HoloLens | Visori VR immersive |
---|---|---|
Input MR 213: Controller del movimento | ✔️ |
Prima di iniziare
Prerequisiti
Vedere l'elenco di controllo per l'installazione per visori immersivi in questa pagina.
- Questa esercitazione richiede Unity 2017.2.1p2
File di progetto
- Scaricare i file richiesti dal progetto ed estrarre i file nel desktop.
Nota
Se si vuole esaminare il codice sorgente prima di scaricare, è disponibile in GitHub.
Configurazione di Unity
Obiettivi
- Ottimizzare Unity per lo sviluppo di Windows Mixed Reality
- Configurare Realtà mista fotocamera
- Configurare l'ambiente
Istruzioni
Riavviare Unity.
Selezionare Open (Apri).
Passare a Desktop e trovare la cartella MixedReality213-master precedentemente non crittografata.
Fare clic su Seleziona cartella.
Al termine del caricamento dei file di progetto di Unity, sarà possibile visualizzare l'editor unity.
In Unity selezionare Impostazioni compilazione file>.
Selezionare piattaforma UWP (Universal Windows Platform) nell'elenco Piattaforma e fare clic sul pulsante Cambia piattaforma.
Impostare Dispositivo di destinazione su Qualsiasi dispositivo
Impostare il tipo di compilazione su D3D
Impostare SDK su Più recente installato
Controllare i progetti C# di Unity
- Ciò consente di modificare i file di script nel progetto Visual Studio senza ricompilare il progetto Unity.
Fare clic su Impostazioni lettore.
Nel pannello Controllo scorrere verso il basso
In Impostazioni XR selezionare Realtà virtuale supportata
In SDK di realtà virtuale selezionare Windows Mixed Reality
Chiudere la finestra Impostazioni di compilazione .
Struttura del progetto
Questa esercitazione usa Realtà mista Toolkit - Unity. È possibile trovare le versioni in questa pagina.
Scene completate per il riferimento
- Sono disponibili due scene di Unity completate nella cartella Scene .
- MixedReality213: Scena completata con pennello singolo
- MixedReality213Advanced: Scena completata per la progettazione avanzata con più pennelli
Nuova configurazione della scena per l'esercitazione
In Unity fare clic su Nuova scena file >
Eliminare la fotocamera principale e la luce direzionale
Nel pannello Progetto cercare e trascinare i prefab seguenti nel pannello Gerarchia :
- Asset/HoloToolkit/Input/Prefabs/MixedRealityCamera
- Asset/AppPrefabs/Environment
Esistono due prefab della fotocamera in Realtà mista Toolkit:
- MixedRealityCamera.prefab: solo fotocamera
- MixedRealityCameraParent.prefab: Fotocamera + Teleportazione + Limite
- In questa esercitazione verrà usata la funzionalità MixedRealityCamera senza teleportazione. A causa di questo, è stato aggiunto un semplice prefab Ambiente che contiene un piano di base per rendere l'utente a terra.
- Per altre informazioni sulla teleportazione con MixedRealityCameraParent, vedere Progettazione avanzata - Teleportazione e locomozione
Configurazione di Skybox
Fare clic su Impostazioni di illuminazione > finestra >
Fare clic sul cerchio sul lato destro del campo Skybox Material
Digitare "grigio" e selezionare SkyboxGray (Asset/AppPrefabs/Supporto/Materiali/SkyboxGray.mat)
Selezionare l'opzione Skybox per poter visualizzare skybox sfumatura grigia assegnata
La scena con MixedRealityCamera, Ambiente e skybox grigio sarà simile a questa.
Fare clic su Salva scena file > come
Salvare la scena nella cartella Scene con qualsiasi nome
Capitolo 1 - Visualizzazione controller
Obiettivi
- Informazioni su come eseguire il rendering dei modelli del controller di movimento in modalità gioco di Unity e in fase di esecuzione.
Windows Mixed Reality fornisce un modello di controller animato per la visualizzazione del controller. Esistono diversi approcci che è possibile adottare per la visualizzazione del controller nell'app:
- Impostazione predefinita: uso del controller predefinito senza modifiche
- Ibrido: uso del controller predefinito, ma personalizzazione di alcuni dei relativi elementi o componenti dell'interfaccia utente sovrapposti
- Sostituzione: uso del modello 3D personalizzato per il controller
In questo capitolo verranno illustrati gli esempi di queste personalizzazioni del controller.
Istruzioni
- Nel pannello Progetto digitare MotionControllers nella casella di ricerca . È anche possibile trovarlo in Assets/HoloToolkit/Input/Prefabs/.
- Trascinare il prefab MotionControllers nel pannello Hierarchy (Gerarchia ).
- Fare clic sul prefab MotionControllers nel pannello Gerarchia .
Prefab MotionControllers
Il prefab MotionControllers ha uno script MotionControllerVisualizer che fornisce gli slot per i modelli di controller alternativi. Se si assegnano modelli 3D personalizzati, ad esempio una mano o una spada e si seleziona "Usa sempre modello alternativo a sinistra/destra", verranno visualizzati anziché il modello predefinito. Questo slot verrà usato nel capitolo 4 per sostituire il modello di controller con un pennello.
Istruzioni
- Nel pannello Inspector (Controllo ) fare doppio clic su MotionControllerVisualizer script (Script MotionControllerVisualizer ) per visualizzare il codice in Visual Studio
Script MotionControllerVisualizer
Le classi MotionControllerVisualizer e MotionControllerInfo forniscono i mezzi per accedere & modificare i modelli di controller predefiniti. MotionControllerVisualizer sottoscrive l'evento InteractionSourceDetected di Unity e crea automaticamente istanze dei modelli controller quando vengono trovati.
protected override void Awake()
{
...
InteractionManager.InteractionSourceDetected += InteractionManager_InteractionSourceDetected;
InteractionManager.InteractionSourceLost += InteractionManager_InteractionSourceLost;
...
}
I modelli controller vengono forniti in base alla specifica glTF. Questo formato è stato creato per fornire un formato comune, migliorando al tempo stesso il processo di trasmissione e decompressione degli asset 3D. In questo caso, è necessario recuperare e caricare i modelli controller in fase di esecuzione, in quanto si vuole rendere l'esperienza dell'utente il più facile possibile e non è garantita quale versione dei controller di movimento l'utente potrebbe usare. Questo corso, tramite Realtà mista Toolkit, usa una versione del progetto UnityGLTF del gruppo Khronos.
Dopo aver recapitato il controller, gli script possono usare MotionControllerInfo per trovare le trasformazioni per elementi controller specifici in modo che possano posizionarsi correttamente.
In un capitolo successivo si apprenderà come usare questi script per collegare gli elementi dell'interfaccia utente ai controller.
In alcuni script sono disponibili blocchi di codice con #if ! UNITY_EDITOR o UNITY_WSA. Questi blocchi di codice vengono eseguiti solo nel runtime UWP quando si esegue la distribuzione in Windows. Questo avviene perché il set di API usate dall'editor unity e dal runtime dell'app UWP sono diversi.
- Salvare la scena e fare clic sul pulsante Riproduci .
Sarai in grado di vedere la scena con i controller del movimento nel visore VR. Puoi visualizzare animazioni dettagliate per i clic sui pulsanti, il movimento della levetta e l'evidenziazione del tocco del touchpad.
Capitolo 2 - Collegamento di elementi dell'interfaccia utente al controller
Obiettivi
- Informazioni sugli elementi dei controller del movimento
- Informazioni su come collegare oggetti a parti specifiche dei controller
In questo capitolo si apprenderà come aggiungere elementi dell'interfaccia utente al controller a cui l'utente può accedere e manipolare facilmente in qualsiasi momento. Si apprenderà anche come aggiungere un'interfaccia utente di selezione colori semplice usando l'input del touchpad.
Istruzioni
- Nel pannello Progetto cercare lo script MotionControllerInfo .
- Nel risultato della ricerca fare doppio clic su MotionControllerInfo script per visualizzare il codice in Visual Studio.
Script MotionControllerInfo
Il primo passaggio consiste nel scegliere l'elemento del controller a cui si vuole collegare l'interfaccia utente. Questi elementi sono definiti in ControllerElementEnum in MotionControllerInfo.cs.
- Casa
- Menu
- Afferrare
- Levetta
- Select
- Touchpad
- Posizione puntante : questo elemento rappresenta la punta del controller che punta verso la direzione in avanti.
Istruzioni
- Nel pannello Progetto cercare Script AttachToController .
- Nel risultato della ricerca fare doppio clic su AttachToController script (Script AttachToController ) per visualizzare il codice in Visual Studio.
Script AttachToController
Lo script AttachToController offre un modo semplice per collegare tutti gli oggetti a una mano e a un elemento controller specificati.
In AttachElementToController(),
- Controllo della mano con MotionControllerInfo.Handedness
- Ottenere un elemento specifico del controller usando MotionControllerInfo.TryGetElement()
- Dopo aver recuperato la trasformazione dell'elemento dal modello controller, padre l'oggetto sotto di esso e impostare la posizione locale dell'oggetto & rotazione su 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;
}
}
Il modo più semplice per usare lo script AttachToController consiste nell'ereditare da esso, come è stato fatto nel caso di ColorPickerWheel. È sufficiente eseguire l'override delle funzioni OnAttachToController e OnDetachFromController per eseguire la configurazione/suddivisione quando il controller viene rilevato/disconnesso.
Istruzioni
- Nel pannello Progetto digitare nella casella di ricerca ColorPickerWheel. È anche possibile trovarlo in Asset/AppPrefabs/.
- Trascinare il prefab ColorPickerWheel nel pannello Hierarchy (Gerarchia ).
- Fare clic sul prefab ColorPickerWheel nel pannello Gerarchia .
- Nel pannello Inspector (Controllo ) fare doppio clic su ColorPickerWheel Script (Script ColorPickerWheel ) per visualizzare il codice in Visual Studio.
Script ColorPickerWheel
Poiché ColorPickerWheel eredita AttachToController, mostra Handedness e Element nel pannello Inspector . L'interfaccia utente verrà collegata all'elemento Touchpad sul controller sinistro.
ColorPickerWheel esegue l'override di OnAttachToController e OnDetachFromController per sottoscrivere l'evento di input che verrà usato nel capitolo successivo per la selezione dei colori con input del touchpad.
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;
}
...
}
- Salvare la scena e fare clic sul pulsante Riproduci .
Metodo alternativo per il collegamento di oggetti ai controller
È consigliabile che gli script ereditino da AttachToController ed eseseguono l'override di OnAttachToController. Tuttavia, questo potrebbe non essere sempre possibile. Un'alternativa consiste nell'usarlo come componente autonomo. Ciò può essere utile quando si vuole collegare un prefab esistente a un controller senza effettuare il refactoring degli script. È sufficiente che la classe attenda che IsAttached sia impostata su true prima di eseguire qualsiasi configurazione. Il modo più semplice per eseguire questa operazione consiste nell'usare una coroutine per "Start".
private IEnumerator Start() {
AttachToController attach = gameObject.GetComponent<AttachToController>();
while (!attach.IsAttached) {
yield return null;
}
// Perform setup here
}
Capitolo 3 - Uso dell'input del touchpad
Obiettivi
- Informazioni su come ottenere eventi di dati di input del touchpad
- Informazioni su come usare le informazioni sulla posizione dell'asse del touchpad per l'esperienza dell'app
Istruzioni
- Nel pannello Hierarchy (Gerarchia ) fare clic su ColorPickerWheel
- Nel pannello Inspector (Controllo ) in Animator fare doppio clic su ColorPickerWheelController
- Sarà possibile visualizzare la scheda Animatore aperta
Visualizzazione/nascondere l'interfaccia utente con il controller di animazione di Unity
Per mostrare e nascondere l'interfaccia utente ColorPickerWheel con l'animazione, viene usato il sistema di animazione di Unity. Impostando la proprietà Visible di ColorPickerWheel su true o false trigger Mostra e nascondi trigger di animazione. I parametri Show e Hide sono definiti nel controller di animazione ColorPickerWheelController .
Istruzioni
- Nel pannello Hierarchy (Gerarchia ) selezionare ColorPickerWheel prefab (Prefab ColorPickerWheel )
- Nel pannello Inspector (Controllo ) fare doppio clic su ColorPickerWheel script (Script ColorPickerWheel ) per visualizzare il codice in Visual Studio
Script ColorPickerWheel
ColorPickerWheel sottoscrive l'evento InteractionSourceUpdated di Unity per ascoltare gli eventi del touchpad.
In InteractionSourceUpdated(), lo script controlla per prima cosa:
- è effettivamente un evento touchpad (obj.state).touchpadTouched)
- proviene dal controller a sinistra (obj.state.source).mano)
Se entrambi sono true, la posizione del touchpad (obj.state).touchpadPosition) viene assegnato a selectorPosition.
private void InteractionSourceUpdated(InteractionSourceUpdatedEventArgs obj)
{
if (obj.state.source.handedness == handedness && obj.state.touchpadTouched)
{
Visible = true;
selectorPosition = obj.state.touchpadPosition;
}
}
In Update(), in base alla proprietà visibile , attiva i trigger Mostra e Nascondi animazioni nel componente animatore del selettore colori
if (visible != visibleLastFrame)
{
if (visible)
{
animator.SetTrigger("Show");
}
else
{
animator.SetTrigger("Hide");
}
}
In Update(), selectorPosition viene usato per eseguire il cast di un raggio in corrispondenza del collisore mesh della ruota del colore, che restituisce una posizione UV. Questa posizione può quindi essere usata per trovare la coordinata pixel e il valore del colore della trama della ruota del colore. Questo valore è accessibile ad altri script tramite la proprietà SelectedColor .
...
// 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);
}
Capitolo 4 - Override del modello del controller
Obiettivi
- Informazioni su come eseguire l'override del modello controller con un modello 3D personalizzato.
Istruzioni
- Fare clic su MotionController nel pannello Gerarchia .
- Fare clic sul cerchio sul lato destro del campo Controller alternativo destro .
- Digitare "BrushController" e selezionare il prefab dal risultato. È possibile trovarlo in Asset/AppPrefabs/BrushController.
- Selezionare Usa sempre un modello alternativo a destra
Il prefab BrushController non deve essere incluso nel pannello Gerarchia . Tuttavia, per controllare i componenti figlio:
- Nel pannello Progetto digitare In BrushController e trascinare il prefab BrushController nel pannello Gerarchia .
Troverai il componente Tip in BrushController. Verrà usata la trasformazione per avviare/arrestare le linee di disegno.
- Eliminare BrushController dal pannello Gerarchia .
- Salvare la scena e fare clic sul pulsante play . Sarà possibile visualizzare il modello di pennello sostituito dal controller di movimento destro.
Capitolo 5 - Pittura con Selezione input
Obiettivi
- Informazioni su come usare l'evento Select button per avviare e arrestare un disegno a linee
Istruzioni
- Cercare il prefab BrushController nel pannello Progetto .
- Nel pannello Controllo fare doppio clic su BrushController Script per visualizzare il codice in Visual Studio
Script BrushController
BrushController sottoscrive gli eventi InteractionSourcePressed e InteractionSourceReleased di InteractionManager . Quando viene attivato l'evento InteractionSourcePressed , la proprietà Draw del pennello è impostata su true; quando viene attivato l'evento InteractionSourceReleased , la proprietà Draw del pennello è impostata su 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;
}
}
Mentre Draw è impostato su true, il pennello genererà punti in un'istanza di Unity LineRenderer. Un riferimento a questo prefab viene mantenuto nel campo Prefab del pennello.
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;
}
}
Per usare il colore attualmente selezionato dall'interfaccia utente della rotellina del selettore colori, BrushController deve avere un riferimento all'oggetto ColorPickerWheel . Poiché il prefab BrushController viene creata un'istanza in fase di esecuzione come controller sostitutivo, tutti i riferimenti agli oggetti nella scena dovranno essere impostati in fase di esecuzione. In questo caso si usa GameObject.FindObjectOfType per individuare 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;
...
}
- Salvare la scena e fare clic sul pulsante play . Sarà possibile disegnare le linee e disegnare usando il pulsante select sul controller a destra.
Capitolo 6 - Creazione di oggetti con Selezione input
Obiettivi
- Informazioni su come usare gli eventi di input del pulsante Select and Grasp
- Informazioni su come creare un'istanza di oggetti
Istruzioni
Nel pannello Progetto digitare ObjectSpawner nella casella di ricerca. È anche possibile trovarlo in Asset/AppPrefabs/
Trascinare il prefab ObjectSpawner nel pannello Gerarchia .
Fare clic su ObjectSpawner nel pannello Gerarchia .
ObjectSpawner ha un campo denominato Origine colori.
Nel pannello Gerarchia trascinare il riferimento ColorPickerWheel in questo campo.
Fare clic sul prefab ObjectSpawner nel pannello Gerarchia .
Nel pannello Controllo fare doppio clic su ObjectSpawner Script per visualizzare il codice in Visual Studio.
Script ObjectSpawner
L'istanza di ObjectSpawner crea un'istanza di una mesh primitiva (cubo, sfera, cilindro) nello spazio. Quando viene rilevato un oggetto InteractionSourcePressed, controlla la mano e se è un evento InteractionSourcePressType.Grasp o InteractionSourcePressType.Select.
Per un evento Grasp, incrementa l'indice del tipo mesh corrente (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;
}
}
}
Per un evento Select , in SpawnObject(), viene creata un'istanza di un nuovo oggetto, non padre e rilasciato nel mondo.
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 per impostare il colore del materiale dell'oggetto visualizzato. Gli oggetti generati vengono assegnati a un'istanza di questo materiale in modo da conservarne il colore.
- Salvare la scena e fare clic sul pulsante play .
Sarà possibile modificare gli oggetti con il pulsante Grasp e generare oggetti con il pulsante Seleziona.
Compilare e distribuire l'app nel portale di Realtà mista
- In Unity selezionare Impostazioni compilazione file>.
- Fare clic su Aggiungi scene aperte per aggiungere la scena corrente alle scene in compilazione.
- Fare clic su Compila.
- Creare una nuova cartella denominata "App".
- Fare clic sulla cartella App .
- Fare clic su Seleziona cartella.
- Al termine di Unity, verrà visualizzata una finestra Esplora file.
- Aprire la cartella App .
- Fare doppio clic su YourSceneName.sln Visual Studio Solution file.
- Usando la barra degli strumenti superiore in Visual Studio, modificare la destinazione da Debug a Versione e da ARM a X64.
- Fare clic sulla freccia a discesa accanto al pulsante Dispositivo e selezionare Computer locale.
- Fare clic su Debug -> Avvia senza eseguire il debug nel menu o premere CTRL + F5.
Ora l'app viene compilata e installata nel portale di Realtà mista. È possibile avviarlo di nuovo tramite il menu Start in Realtà mista Portale.
Progettazione avanzata - Strumenti di pennello con layout radiale
In questo capitolo si apprenderà come sostituire il modello di controller di movimento predefinito con una raccolta di strumenti pennello personalizzata. Per il riferimento, è possibile trovare la scena completata MixedReality213Advanced nella cartella Scene .
Istruzioni
Nel pannello Progetto digitare BrushSelector nella casella di ricerca . È anche possibile trovarlo in Asset/AppPrefabs/
Trascinare il prefab BrushSelector nel pannello Gerarchia .
Per l'organizzazione, creare un GameObject vuoto denominato Brushes
Trascinare i prefab seguenti dal pannello Progetto in Pennelli
- Asset/AppPrefabs/BrushFat
- Asset/AppPrefabs/BrushThin
- Asset/AppPrefabs/Eraser
- Asset/AppPrefabs/MarkerFat
- Asset/AppPrefabs/MarkerThin
- Asset/AppPrefabs/Matita
Fare clic su MotionControllers prefab nel pannello Hierarchy (Gerarchia ).
Nel pannello Inspector (Controllo ) deselezionare Always Use Alternate Right Model (Usa sempre modello a destra alternativo ) nel visualizzatore del controller di movimento
Nel pannello Gerarchia fare clic su BrushSelector
BrushSelector ha un campo denominato ColorPicker
Dal pannello Hierarchy (Gerarchia ) trascinare il campo ColorPickerWheel nel campo ColorPicker nel pannello Inspector (Controllo ).
Nel pannello Hierarchy (Gerarchia ) in BrushSelector prefab (Prefab BrushSelector ) selezionare l'oggetto Menu .
Nel pannello Inspector (Controllo ) nel componente LineObjectCollection aprire l'elenco a discesa Matrice oggetti . Verranno visualizzati 6 slot vuoti.
Dal pannello Hierarchy (Gerarchia ) trascinare ognuno dei prefab padre sotto Brushes GameObject in questi slot in qualsiasi ordine. Assicurarsi di trascinare i prefab dalla scena, non i prefab nella cartella del progetto.
Prefab BrushSelector
Poiché BrushSelector eredita AttachToController, mostra le opzioni Handedness e Element nel pannello Inspector . Abbiamo selezionato Right e Pointing Pose per collegare gli strumenti pennello al controller di destra con direzione in avanti.
BrushSelector usa due utilità:
- Ellisse: consente di generare punti nello spazio lungo una forma ellisse.
- LineObjectCollection: distribuisce gli oggetti usando i punti generati da qualsiasi classe Line (ad esempio, Ellipse). Questo è ciò che verrà usato per posizionare i pennelli lungo la forma Ellipse.
In combinazione, queste utilità possono essere usate per creare un menu radiale.
Script LineObjectCollection
LineObjectCollection include controlli per le dimensioni, la posizione e la rotazione degli oggetti distribuiti lungo la linea. Ciò è utile per la creazione di menu radiali come il selettore di pennello. Per creare l'aspetto dei pennelli che aumentano da nulla quando si avvicinano alla posizione selezionata al centro, la curva ObjectScale raggiunge il centro e tocca i bordi.
Script BrushSelector
Nel caso di BrushSelector, abbiamo scelto di usare l'animazione procedurale. Per prima cosa, i modelli pennello vengono distribuiti in un'ellisse dallo script LineObjectCollection . Ogni pennello è quindi responsabile della gestione della posizione nella mano dell'utente in base al relativo valore DisplayMode , che cambia in base alla selezione. È stato scelto un approccio procedurale a causa dell'elevata probabilità di interruzione delle transizioni di posizione del pennello quando l'utente seleziona i pennelli. Le animazioni mecanim possono gestire normalmente le interruzioni, ma tende a essere più complicate di una semplice operazione Lerp.
BrushSelector usa una combinazione di entrambe. Quando viene rilevato l'input del touchpad, le opzioni del pennello diventano visibili e aumentano lungo il menu radiale. Dopo un periodo di timeout (che indica che l'utente ha effettuato una selezione) le opzioni del pennello vengono ridimensionate di nuovo, lasciando solo il pennello selezionato.
Visualizzazione dell'input del touchpad
Anche nei casi in cui il modello controller è stato completamente sostituito, può essere utile visualizzare l'input sugli input del modello originale. Ciò consente di mettere a terra le azioni dell'utente in realtà.This helps to ground the user's actions in reality. Per BrushSelector abbiamo scelto di rendere visibile brevemente il touchpad quando viene ricevuto l'input. Questa operazione è stata eseguita recuperando l'elemento Touchpad dal controller, sostituendo il materiale con un materiale personalizzato, quindi applicando una sfumatura al colore del materiale in base all'ultimo input del touchpad ricevuto.
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);
...
}
Selezione degli strumenti pennello con input touchpad
Quando il selettore di pennello rileva l'input premuto del touchpad, controlla la posizione dell'input per determinare se si trovava a sinistra o a destra.
Spessore tratto con selectPressedAmount
Anziché l'evento InteractionSourcePressType.Selectnell'oggetto InteractionSourcePressed(), è possibile ottenere il valore analogico della quantità premuta tramite selectPressedAmount. Questo valore può essere recuperato 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 gomma
Eraser è un tipo speciale di pennello che esegue l'override della funzione DrawOverTime() di Base Brush. Mentre Draw è true, la gomma controlla se la punta interseca con qualsiasi tratto pennello esistente. In caso affermativo, vengono aggiunti a una coda per essere compattati ed eliminati.
Progettazione avanzata - Teleportazione e locomozione
Se si vuole consentire all'utente di spostarsi all'interno della scena con teletrasporto usando la levetta, usare MixedRealityCameraParent anziché MixedRealityCamera. È anche necessario aggiungere InputManager e DefaultCursor. Poiché MixedRealityCameraParent include già MotionControllers e Boundary come componenti figlio, è necessario rimuovere i prefab MotionController e Environment esistenti.
Istruzioni
Nel pannello Hierarchy (Gerarchia ) eliminare MixedRealityCamera, Environment e MotionControllers
Nel pannello Progetto cercare e trascinare i prefab seguenti nel pannello Hierarchy (Gerarchia ):
- Assets/AppPrefabs/Input/Prefabs/MixedRealityCameraParent
- Asset/AppPrefabs/Input/Prefabs/InputManager
- Asset/AppPrefabs/Input/Prefabs/Cursor/DefaultCursor
Nel pannello Gerarchia fare clic su Gestione input
Nel pannello Inspector (Controllo) scorrere verso il basso fino alla sezione Simple Single Pointer Selector (Selettore puntatore singolo semplice)
Dal pannello Hierarchy (Gerarchia) trascinare DefaultCursor nel campo Cursor
Salvare la scena e fare clic sul pulsante Riproduci . Sarà possibile usare la levetta per ruotare a sinistra/destra o teletrasportare.
La fine
E questa è la fine di questa esercitazione! Sono stati appresi i concetti seguenti:
- Come usare i modelli di controller di movimento nella modalità di gioco e nel runtime di Unity.
- Come usare diversi tipi di eventi pulsante e le relative applicazioni.
- Come sovrapporre gli elementi dell'interfaccia utente sopra il controller o personalizzarlo completamente.
A questo punto è possibile iniziare a creare un'esperienza immersiva con i controller del movimento.
Scene completate
- Nel pannello Progetto di Unity fare clic sulla cartella Scene .
- Sono disponibili due scene di Unity MixedReality213 e MixedReality213Advanced.
- MixedReality213: scena completata con un singolo pennello
- MixedReality213Advanced: Scena completata con più pennelli con l'esempio di pressione del pulsante di selezione