Festiwal Nauki 2017 – relacja projektu
Jak co roku, razem z Sebastianem przygotowujemy projekt na Festiwal Nauki, który odbywa się na Wydziale Informatyki, Elektrotechniki i Automatyki na Uniwersytecie Zielonogórskim. Tym razem postanowiliśmy stworzyć grę, która będzie wstępem do naszych prac dyplomowych. Przede wszystkim chodziło nam o zapoznanie się z technologią rozszerzonej rzeczywistości. Dzięki temu podejście do pracy inżynierskiej będzie dla nas prostsze i nie będziemy już się męczyć z pierwszym używaniem biblioteki Vuforia.
Niestety okazało się, że na nasz pokaz nikt ze szkół się nie zapisał (nie wiem czy to kwestia niezbyt marketingowej nazwy projektu, czy co 🙁 ). Nie pozostało nam więc nic innego jak podczepić się pod pokaz naszego promotora o podobnej tematyce.
Gra, którą przygotowaliśmy polegała na zebraniu przedmiotów z listy zakupów, która była generowana przez serwer. Każdy gracz mógł z tabletem lub telefonem skanować kody QR produktów i wtedy pokazywały się informacje o produktach jak i wizualizacja 3D. Gdy gracz zeskanował kod QR to mógł dany produkt zamówić. Jeżeli pokrywał się z listą zamówienia to wtedy serwer zaznaczał prawidłowo zamówiony towar. Gra kończyła się, gdy pierwszy gracz zebrał wszystkie produkty. Jednym z minusów naszej gry, który zauważyliśmy już na pokazach, to nikt nie zwracał uwagi na animację. Animacja przedmiotu trwała ok. 3 sekund, a mimo to uczestnicy nie patrzyli na nią. Zamiast tego sprawdzali tylko, czy nazwa produktu się zgadza. Nie przemyśleliśmy tego, a trochę czasu nad tym spędziliśmy, żeby to ładnie wyglądało.
Jak to jest zrobione?
Gra składa się z 3 modułów – strony sklepu z API, serwera napisanego w Unity oraz samej grze, która uruchamiana jest na Androidzie. Sklep został napisany w .NET Core i tak naprawdę jego głównym zadaniem jest przechowywanie informacji o produktach, które są pobierane przez serwer Unity. Nie bawiliśmy się w tworzenie koszyka, bo to też nie było celem na pokaz, chcieliśmy się skupić głównie na części w Unity, która zabrała nam najwięcej czasu i było najwięcej problemów. Pierwszym i to najbardziej uciążliwym problemem był błąd w Unity, który był zgłoszony i jego rozwiązanie było dostępne w becie edytora. Gdy edytor przestał być aktywnym ekranem to zaczęły wyskakiwać wyjątki, przez które zrywało połączenie ze wszystkimi klientami połączonymi do niego. Przez ten błąd nie mogliśmy sprawnie testować funkcjonalności serwera i gry. Byliśmy zmuszeni podbić wersję projektu, ale ryzykowaliśmy, że w becie mogło coś działać nie tak. Na szczęście nie było więcej problemów i mogliśmy na spokojne kontynuować pracę.
Aplikacja kliencka nie miała dostępu do API (z małym wyjątkiem, ale o tym później), wszystkie dane pobierał serwer i przekazywał te informacje aplikacjom klienckim. Dzięki temu odizolowaliśmy dostęp do API i ograniczaliśmy możliwość wystąpienia problemów z jednoczesnym połączeniem między aplikacjami, serwerem oraz sklepem. Sklep zwracał dane w formacie JSON, który w prosty sposób przetwarzał serwer Unity z wykorzystaniem biblioteki SimpleJSON (dostępna tutaj).

Tak wygląda aplikacja serwera. Zasłonka Niebezbiecznika +10 do bezpieczeństwa 🙂
Serwerowe sprawy
Połączenie między serwerem a aplikacją kliencką było bardziej skomplikowane. Wybrałem najprostszą metodę do przesyłania danych z wykorzystaniem NetworkMessage dostępnego w Unity. API to pozwala na wysyłaniu wiadomości, które przechowują typy proste. Niestety problem pojawił się, gdy potrzebowaliśmy przesłać obrazek ze sklepu. Wymagało to przesłania zawartości obiektu Texture2D, której nie można serializować. Problem można było obejść na 2 sposoby: elegancki i działający. Jako, że był to w ostatni dzień to trochę zmieniliśmy początkowe założenia. Po prostu serwer przekazywał URL do obrazka i aplikacja pobierała bezpośrednio ze sklepu. Elegancki sposób polegał na zapisaniu kolorów obrazka do tekstu(który można już serializować) i przesłanie w częściach z wykorzystaniem NetworkMessage. Generalnie opracowałem coś podobnego do streamu dla CaptainUZ z poprzedniego festiwalu nauki, ale było za mało czasu na implementację tego mechanizmu. Zamiast tego wystarczyło nam to rozwiązać w ten sposób:
public Sprite GetImage(string url, string contentType) { var texture = new Texture2D(2, 2); StartCoroutine(DownloadImage(url, texture)); return Sprite.Create(texture, new Rect(0, 0, texture.width, texture.width), new Vector2(0, 0), 100.0f); } IEnumerator DownloadImage(string url, Texture2D tex) { WWW www = new WWW(url); yield return www; tex.LoadImage(www.bytes); } public IEnumerator GetImageCoroutine(string url, string contentType, Image image) { WWW www = new WWW(url); yield return www; image.sprite = Sprite.Create(www.texture, new Rect(0, 0, www.texture.width, www.texture.height), Vector2.zero); //image.sprite.texture.LoadImage(www.bytes); }
Klient na Androidzie
W przypadku aplikacji na Androida, głównie skupiliśmy się na wyglądzie. Działanie aplikacji było proste i chyba najtrudniejsze to było ogarnięcie Vuforii do naszych potrzeb. Jako, że ja praktycznie całą karierę w Unity bawiłem się w UI to wziąłem to na siebie. Resztę opracowywał Sebastian, który zajmował się wizualizacją i animacją tych wizualizacji z połączeniem własnie z Vuforią. Do testów aplikacji przydała się aplikacja Unity Remote, która duplikuje podgląd aplikacji na wyświetlacz monitora, ale nie jest to to samo co zainstalowanie natywnie aplikacji. W każdym bądź razie nie musieliśmy co chwila kompilować gry na Androida. Do tworzenia sekwencji animacji użyliśmy biblioteki DoTween, która posiada także darmową wersją, w zupełności wystarczającą do tak prostych rzeczy.
Podsumowanie
Generalnie jak przy każdym projekcie, który robiliśmy, nie obyło się bez ostrego deadline. Siedzieliśmy praktycznie non stop w ostatni tydzień przed pokazami, żeby wszystko dopieścić. Skończyło się to tym, że udało się skończyć testy o 7 rano, a o 9 byliśmy już na pokazie 🙂 Oprócz tego wysypał mi się system w trakcie, na szczęście codziennie robię backupy i po niecałej godzince mogliśmy dalej pracować nad projektem.
Podsumowując:
- jeżeli nie lubisz życia na krawędzi, rób wszystko prędzej niż później
- zawsze rób backup systemu, nigdy nie wiadomo czy coś się nie sypnie w trakcie (szczególnie na Windowsie)
- jeżeli gra polega na rywalizacji, nikt nie będzie zbytnio zwracać uwagi na ładną otoczkę
Uważam, że pokaz był udany mimo, że w tym roku wielkich tłumów nie było. Udało się nam zrobić kawał dobrej roboty, wszystko działało (oprócz nas, bo byliśmy wykończeni). W sumie pierwszy raz udało się bez problemów „na produkcji” i sprawnie poprowadzić pokaz. Szkoda, że najprawdopodobniej to była ostatnia nasza aplikacja na Festiwal Nauki.
Poniżej galeria screenów, które udało mi się odzyskać z naszego projektu:
- Tak wygląda aplikacja serwera. Zasłonka Niebezbiecznika +10 do bezpieczeństwa 🙂
- CRUD produktów
- Tagi Vuforii
- Wizualizacja produktu
- Wydrukowane tagi na pokazie
- Metody udostępnione przez sklep
- Scena z wizualizacji produktu