Un plugin de browser pentru Unity

Motor și instrumente de dezvoltare Unity sunt de departe cea mai comună modalitate de a crea aplicații pentru VR și AR în prezent. Anterior, am făcut posibilă exportarea experiențelor bazate pe web din Unity. Astăzi, suntem entuziasmați să arătăm câteva lucrări timpurii care abordează celălalt mod în care dezvoltatorii Unity doresc să folosească web-ul: ca o componentă în mediile lor virtuale bazate pe Unity.

Building on our work porting a browser engine to many platforms and embedding scenarios, including as Firefox Reality AR for HoloLens 2, am construit o nouă componentă Unity bazată pe Servo, un motor web modern scris în limbajul Rust.

Motorul Unity are un sistem de plugin-uri multi-platformă foarte adaptabil, cu un ecosistem sănătos de plugin-uri de la terți, atât open-source, cât și proprietare. Sistemul de plugin-uri ne permite să rulăm module native OS și să le conectăm direct la componentele care se execută în mediul de scripting Unity.

Obiectivele experimentelor au fost de a construi un plugin nativ Unity și un set de componente de script Unity C# care să permită terților să încorporeze ferestrele browserului Servo în scenele Unity și, opțional, să ofere suport pentru utilizarea suprafeței browserului în aplicațiile VR și AR construite în Unity.

Astăzi, lansăm un prototip complet funcțional al browserului web Servo care rulează în interiorul unui plugin Unity. Aceasta este o privire în stadiul incipient al muncii noastre, dar știm că entuziasmul este mare pentru acest tip de soluție, așa că sperăm să încercați acest prototip, să ne oferiți feedback-ul dvs. și să vă alăturați nouă pentru a construi lucruri cu el. Versiunea lansată astăzi vizează platforma macOS, dar vom adăuga unele dintre celelalte platforme suportate de Servo foarte curând.

Începem

Am făcut open-source pentru plugin, la https://github.com/MozillaReality/servo-unity. Mergeți pe acolo, faceți clic pe stea și faceți un fork al codului, verificați-l pe mașina locală și apoi deschideți proiectul în interiorul Unity.

Instrucțiunile pentru dezvoltatori sunt în fișierulREADMEdin depozit.

Ce face

Puteți lucra direct cu fereastra browserului și controalele din interiorul Unity Editor. Configurația de nivel superior se află pe obiectul ServoUnityController. Alte obiecte importante din scenă includ obiectele ServoUnityWindow, ServoUnityNavbarController și ServoUnityMousePointer.

Obiectul ServoUnityWindow poate fi poziționat oriunde într-o scenă Unity. Aici, l-am aruncat în peștera cu ciuperci Mozilla (cunoscută utilizatorilor Firefox Reality, realizată de uimitoarea artistă Jasmin Habezai-Fekri) și am furnizat un manipulator de cameră care ne permite să ne deplasăm în jurul scenei și să vedem că este o vedere 3D a conținutului browserului.

Servo are o redare media de înaltă calitate prin intermediul cadrului GStreamer, inclusiv suport audio. Aici vizionăm o mostră video MPEG4, care rulează în interiorul unui player Unity implementat.

Cercetarea personalizabilă este inclusă în plugin. O mare varietate de conținut web poate fi vizualizat cu versiunea actuală a Servo, iar la o mai mare compatibilitate web se lucrează în mod activ (mai multe despre asta mai jos). Conținutul WebGL funcționează și el.

Cum funcționează

Arhitectură

Dezvoltarea în Unity folosește o arhitectură bazată pe componente, în care Unity execută codul utilizatorului atașat la GameObjectscene, organizate în scene. Utilizatorii personalizează GameObjects prin atașarea de scripturi care se execută într-un mediu C#, fie folosind runtime-ul Mono, fie compilatorul înainte de timp IL2CPP. Ciclul de viață al evenimentelor Unity este accesibil scripturilor utilizatorilor care moștenesc din clasa Unity C# MonoBehaviour. Scripturile de utilizator pot invoca codul nativ din plugin-uri (care sunt doar obiecte partajate dinamice nativ OS) prin intermediul mecanismului P/Invoke din timpul de execuție C#. De fapt, însăși nucleul Unity este implementat în C++ și oferă codului nativ din plugin-uri un al doilea set de interfețe accesibile în C/C++ pentru a ajuta la unele sarcini de nivel scăzut ale plugin-urilor.

Servo este în sine o bucată complexă de software. Prin proiectare, cea mai mare parte a funcționalității sale care nu este orientată către utilizator este compilată într-o bibliotecă Rust, libservo. Pentru această primă fază a proiectului, folosim o interfață simplificată compatibilă cu C într-o altă bibliotecă Rust numită libsimpleservo2. Această bibliotecă expune funcții apelabile în C și cârlige de callback pentru a controla browserul și a vizualiza ieșirea acestuia. În jurul valorii de libsimpleservo2, punem în aplicare abstracțiuni native C++ care încapsulează modelul Unity de fire de execuție și de redare și expunem un set de interfețe apelabile de Unity care, la rândul lor, sunt operate de componentele noastre de script C#.

Obținerea conținutului browserului în Unity

Creăm un obiect în Unity, o instanță a ServoUnityWindow, pentru a înveli o instanță a clasei Texture2D din Unity și pentru a o trata ca un panou de conținut al browserului. Atunci când se utilizează randorul OpenGL al Unity, clasa Texture2D este susținută de o textură OpenGL nativă, iar noi transmitem „numele” texturii OpenGL (adică un ID) către plugin, care leagă textura de un obiect framebuffer care primește textura finală compusă de la Servo.

Pentru că nu avem control asupra legăturii dintre textură și contextul Unity, designul actual pentru actualizarea acestei texturi utilizează un blit (copie) prin intermediul API-ului surfman-chains al Servo. În esență, Servo’s WebRender scrie într-un buffer de suprafață specific sistemului de operare pe un singur fir de execuție, iar apoi acest buffer de suprafață este legat doar pentru citire la firul de execuție al Unity și se face o copie a texturii folosind API-urile OpenGL. În implementarea inițială pentru macOS, de exemplu, buffer-ul de suprafață este un care poate fi mutat la cost zero între fire de execuție, permițând o implementare eficientă în care compozitorul browserului poate scrie într-un fir de execuție diferit de firul de execuție care afișează textura în Unity.

Meta-date de control și de pagină sunt comunicate separat, printr-un set de API-uri care permit căutarea și navigarea la URL-uri, actualizarea titlurilor paginilor și setul obișnuit de butoane back/forward/stop/home.

Pentru că, în cele din urmă, conținutul și controalele din browser sunt toate obiecte Unity, aplicația Unity pe care o construiți poate poziționa, stiliza sau controla programatic acestea în orice mod doriți.

Provocări

Aducerea proiectului în acest stadiu nu a fost lipsită de provocări, unele dintre ele fiind încă în curs de rezolvare. Mediul de scripting al Unity rulează în mare parte pe un singur fir, cu excepția operațiunilor de randare, care au loc pe un fir separat, pe o cadență diferită. Servo, cu toate acestea, generează potențial zeci de fire ușoare pentru o varietate de sarcini. Am avut grijă ca elementele de lucru care se întorc de la Servo să fie redirecționate către firele corecte din Unity. Mai sunt câteva optimizări rămase de făcut pentru a decide când să reîmprospătăm textura Unity. În prezent, se reîmprospătează doar la fiecare cadru, dar adăugăm un API la interfața de încorporare pentru a permite un control mai fin.

În calitate de incubator pentru tehnologia browserului, Servo se concentrează pe dezvoltarea de noi tehnologii. Printre tehnologiile notabile care au trecut de la Servo la motorul Gecko care alimentează Firefox se numără motorul de randare bazat pe GPU WebRender și motorul CSS Stylo. Lăsând la o parte aceste succese, compatibilitatea web completă este încă un domeniu în care Servo are un decalaj semnificativ, deoarece ne-am concentrat în primul rând pe îmbunătățiri mari pentru utilizator și pe experiențe specifice în lungul interval de timp al web-ului. Un efort recent al comunității Servo a înregistrat mari progrese în ceea ce privește compatibilitatea web a Servo, astfel încât ne așteptăm ca subsetul de web navigabil de Servo să continue să crească rapid.

Planuri de dezvoltare

Suportarea întregii game de platforme suportate în prezent de Servo este prima noastră prioritate de dezvoltare ulterioară, cu suportul Windows Win32 și Windows UWP în capul listei. Mulți dintre voi ați văzut aplicația noastră Firefox Reality AR pentru HoloLens 2, iar suportul UWP vă va permite să construiți Servo într-o aplicație AR proprie pentru platforma HoloLens folosind același motor de browser care stă la baza acesteia.

Am dori, de asemenea, să suportăm un subset mai mare din capacitatea completă a browserului. În fruntea listei se află suportul pentru ferestre multiple. În prezent, lucrăm la graduarea plugin-ului de la interfața libsimpleservo2 la o nouă interfață care va permite aplicațiilor să instanțieze mai multe ferestre, file și să implementeze caracteristici precum istoricul, marcajele și multe altele.

Această primă versiune este axată pe navigarea pe web prin intermediul paginilor web 2D. Servo suportă, de asemenea, web-ul imersiv prin API-ul WebXR și explorăm conectarea WebXR la suportul hardware XR al Unity prin intermediul interfeței plugin. Vom începe cu suportul pentru vizualizarea videoclipurilor la 360 de grade, despre care știm de la baza noastră de utilizatori Firefox Reality că este un caz de utilizare principal pentru browser.

În cele din urmă…

Dacă este vorba despre un player media, o interfață în joc pentru web-ul deschis, browser-as-UI, aducerea de experiențe web specifice sau o multitudine de alte posibilități, abia așteptăm să vedem unele dintre modalitățile imaginative prin care dezvoltatorii vor exploata puterea și performanța Servo în cadrul aplicațiilor create de Unity.

.