Tijdens het project voor Velicus hebben we een tutorial app ontwikkeld voor de hololens. Voor deze app hadden wij meerdere mechanics nodig per level, op deze manier kunnen we het de speler duidelijker maken wat de hololens inhoud.
Het doel van de app is om de speler duidelijk maken dat hij kan rondlopen en niet stil hoeft te staan op een plek. Hiervoor zijn meerdere concepten bedacht met als resultaat een product op te leveren waar je een kip moet volgen die rondloopt in een ruimte. In de blog van vandaag ga ik wat dieper in op één van de mechanics die wij hebben gemaakt.
Onderzoeksvraag
Hoe laten wij een kip rondlopen in de virtuele wereld terwijl hij de objecten en obstakels in de echte wereld ontwijkt?
Het onderzoek
Voordat we beginnen met het maken van een systeem, moeten we eerst weten wat we tot beschikking hebben binnen de MRTK (Mixed Reality Toolkit): Bestaat er bijvoorbeeld al een systeem voor navigation en heeft iemand anders er al iets over geschreven?
Nadat ik een poosje had gezocht op het internet, had ik veel verschillende bronnen gevonden. Waaronder Scene Understanding en Spatial Awareness. Een Spatial Awareness systeem probeert de real-world environmental geografisch vast te leggen in een mixed reality applicatie door een mesh laag over de echte wereld heen te leggen. Als je vervolgens een virtueel karakter door een ruimte wilt laten lopen, snapt het programma waar de grond en muren zijn bijvoorbeeld. Bij Scene Understanding herkent het systeem ook wat zich in de omgeving bevindt, maar dan gebruikt het deep learning algoritmes om objecten in de ruimte te herkennen. Bij Spatial Awarness herkent het programma dus dat er een blok uit de grond komt waar hij rekening mee moet houden, maar met Scene Understanding snapt het programma dat het blok een koffietafel is.
Scene understanding
Volgens de documentatie van Microsoft zelf is het relatieve nieuwe systeem Scene Understanding gemaakt met het idee dat het gebruikt kan worden voor navigation. Echter na het installeren en testen van de scene understanding, bleek het niet te werken zoals gehoopt.
We verloren heel veel frames per second (fps) en konden blij zijn als we 30+ fps hadden tijdens het gebruik van scene understanding. Na wat onderzoek bleek dat het niet slim was om path finding hierbij toe te voegen, dus dit idee hebben wij later liggen en zullen hier later op terugkomen.
Spatial Awareness Mesh Observer
Onze tweede poging was het gebruik van de Spatial Awareness, dit was de voorganger van de Scene Understanding SDK en zou ook voor navigation gebruikt kunnen worden. Na het aanzetten van de Spatial Awareness Observer merkte wewel dat we wat performance miste maar een stuk minder dan de Scene Understanding SDK. Met dit systeem halen wij op zijn minst 40+ fps, een performance waar wij wel tevreden mee zijn.
Voor de volgende stap moesten we bedenken hoe we de kiplaten rondlopen over de grond, maar hoe weet de kip eigenlijk waar hij kan lopen?
Mijn concept was om een raycast omlaag te sturen zodat de kip kan zien waar hij de grond kan raken (laagste punt in de mesh). Hier houden we een internal value bij voor de hoogte van de grond. Indien de raycast een punt raakt met ongeveer dezelfde hoogte, kunnen we ervan uitgaan dat het de grond is.
Terwijl dit systeem actief was, merkte ik dat de performance heel slecht was, zeker tijdens path finding. Dit gebeurde omdat hij constant veel raycasts omlaag moet sturen om te weten waar hij kan lopen, daarnaast moet hij ook nog een path finding algoritme erover heen doen. Toch wilde ik hier verder mee experimenteren, het was niet perfect maar het werkte wel! Na het implementeren van A* path finding search algoritme werkte het systeem van begin tot eind. We haalden in het begin van de applicatie 30+fps en voor een eerste prototype was ik tevreden, al was dit niet wat ik hoopte. Zeker wanneer de speler de kip een nieuwe route liet kiezen werkte de applicatie heel slecht omdat hij dus heel veel notes door moet gaan voor goede path finding. Omdat het toch niet op een niveau zat waar ik het wilde hebben, ben ik nog één laatste systeem gaan proberen: Spatial awareness met navmesh.
Spatial awareness met navmesh
Omdat het vorige systeem werkte maar niet zoals gewild, wilde ik nog een laatste oplossing proberen. In het begin had ik het idee om Unity's build-in navmesh te gebruiken. Echter na het lezen van Microsoft’s documentatie ben ik hiervan af gegaan. In de documentatie werd aangegeven dat het niet mogelijk was, omdat de nav-mesh eerst gebaked moest worden. Ook werd er aangegeven dat Despatial Awareness mesh niet beschikbaar was voor de project build.
Na wat onderzoek heb ik een library gevonden binnen Unity met de naam [NavMeshConponents]. Door het gebruik van deze library kunnen we de navmesh in runtime baken. Dit systeem werkte uiteindelijk zoals behoren en met de minste performance problemen. Om dit systeem werkende te krijgen, maakte ik een empty prefab waar ik de ‘NavMeshSurface’ component gebruik. Hierbij gebruikte ik de volgende settings:
Agent type: Chicken
Collect: Objects children
Include layer: Spatial awareness
Use geometry: Physics Collider
Voor meer informatie over wat deze settings doen raad ik je aan de documentatie te lezen.
Mijn volgende stap was het baken van de navmesh. Dit doe ik door de NavMeshSurface component in de scene op de vragen. In ons geval hebben we maar 1 NavMeshSurface component, dus konden we ‘FindObjectOfType();’ gebruiken. Na het opvragen van het component kan je de public function 'BuildNavMesh' aanroepen wat automatisch de navmesh opnieuw build en bruikbaar maakt. Wanneer we nu een NavMeshAgent in de scene hebben, snapped hij automatisch naar de
nieuwe navmesh indien hij niet al op een navmesh zit. Waarna je hem kan laten rondlopen zoals je altijd doet met je navmesh.