Character Animation in Unity3d
Het is bijna ongelofelijk. Zat je vroeger nog weken te zwoegen op het exporteren en importeren van de bones en bijbehorende animaties en de daarmee gepaard gaande errors en glitches, met Unity3d is het een kwestie van slepen en plakken. Hier een stappenplannetje om in een kwartiertje een character 3rd-person te besturen. Van scratch, zonder programmeerwerk (nou ja, twee regeltjes plakken).
Character
We gaan in dat kwartier natuurlijk niet zelf een character modelleren — dat duurt langer en kan ik bovendien helemaal niet volgens mij. Uitkomst wordt geboden door MakeHuman — een open source tool voor het genereren van 3d karakters aan de hand van parameters. Dit is natuurlijk een beetje valsspelen, omdat je er geen stijlvol of veelzeggend model uit krijgt. Aan de andere kant heb je snel resultaat en voor de artiesten onder ons is het model wellicht een goed begin voor eigen werk.

Een karakter bouwen in MakeHuman.
MakeHuman exporteert een OBJ-bestand. Let op: als je onder Windows Vista of Windows 7 wilt exporteren moet je MakeHuman als administrator draaien. Het programma exporteert namelijk naar de export map in Program Files en mag daar anders niet schrijven. In 3D Studio Max kun je het bestand met import openen en je hebt dan een prima character mesh.

Een mesh in 3dsmax vanuit MakeHuman.
Rig
Om te kunnen animeren, heeft het karakter een interne bones structuur nodig. Deze kun je zelf opbouwen, maar je kunt ook gebruik maken van de ingebouwde biped (tweevoeter). Deze vind je onder het Systems paneel en je kunt hem van onder naar boven naast je character tekenen.

Een biped naast je karakter tekenen.
Daarna is het zaak de biped zo goed mogelijk te matchen met het karakter. Het makkelijkst gaat dit wanneer ze qua omvang en plaatsing samenvallen, maar dat is niet vereist. Eventueel kun je de biped opnieuw tekenen met Snap aan, zodat deze beter op je mesh past. Je kunt ook de ledematen bijdraaien tot de biped goed past. Het aanpassen van de houding gaat het best in figure mode; deze knop vind je onder het Hierarchy panel. Let op dat je steeds de root van de biped selecteert (Bip01); dit is de diamand in het kruis van de biped (maar makkelijker te selecteren via de selection list, sneltoets H).
Verder kun je het character model bevriezen (freeze). Hierbij is het wel makkelijk om in de object properties de optie show frozen in grey uit te zetten en bijvoorbeeld see-through in te schakelen.

Een biped bones-structuur in het karakter.
Skin
Om het model met het skelet (biped) mee te laten bewegen moet je het model skinnen. Dat klinkt gevaarlijker dan het is. De skin geeft aan hoe elk bot het lichaam (de huid) beïnvloedt. Als je je teen beweegt, gaat je teen bewegen maar ook een stukje voet. Het zou echter raar zijn als je linker hand ging bewegen.
Voeg de Skin modifier toe op het model en voeg dan met Add alle bones van de biped toe. Als je nu een bot (tijdelijk) roteert, gaat het lichaam mee.

Een snel geskinde groet.
Misschien gaat het niet zoals bedoelt: er steken vast polygonen uit of er bewegen delen mee die niet de bedoeling zijn. Via Edit Envelopes kun je dit beïnvloeden, maar dat gaan we nu niet doen. In het algemeen geldt wel dat de kwaliteit sterk verbetert naar mate het character beter is geskinned.
Animate
Nu kunnen we gaan animeren. Dat gaan we natuurlijk ook niet zelf doen. Een alternatief is motion capturing, maar die apparatuur heeft ook niet iedereen bij de hand. Gelukkig wordt er een en ander op internet gedeeld (zoek naar BVH- of BIP-bestanden). Bij cgspeed vind je een verzameling animaties uit motion capturing die alvast voor 3D Studio Max zijn voorbereid.
We moeten nu een paar stappen doen om de animatie toe te passen. Sla je character nu eerst op.
Selecteer de biped (Bip01) en klap onder het Hiearchy panel het motion capture menu uit. Klik op Load Motion Capture File (camera icon) en open een van de BVH-bestanden. Je kunt de foutmelding negeren. De Up Vector moet in dit geval nog op Y in plaats van Z ingesteld worden. Het kan zijn dat het karakter er nu nogal vreemd uit ziet maar dat is niet erg — maar je moet je max-bestand niet opslaan nu! Als je de tijdlijn afspeelt (play) zie je dat de animatie wel klopt en het skelet goed loopt.

Het ziet er vreemd uit maar gaat goed.
Klik nu onder Biped op Save File (diskette icon) en sla de animatie op als BIP-bestand (als je al een BIP-bestand had gedownload, hoef je dit niet te doen en is je animatie al klaar). Open je opgeslagen character opnieuw in 3D Studio Max en laadt op dezelfde manier de net opgeslagen BIP-animatie. Nu moet het goed gaan, op de fouten uit de skinning-fase na natuurlijk.
Motion-captured animatie loop.
Zoals je ziet loopt het character nu van A naar B. In deze motion capture sessie keert hij zelfs om en loopt terug. Voor een in-game animatie heb je eigelijk een loop (herhaling) nodig die goed aansluit. Bovendien is het handig als het karakter blijft staan — de verplaatsing regelen we dan in-game wel.
Onder Modes and Display vind je een knop In Place die de hele animatie on-the-spot uitvoert, precies zoals nodig. Door de tijdsspanne aan te passen kun je een redelijke loop krijgen.
In-place animatie loop.
Export en Import
Nu komt het makkelijke. Via export kun je vanuit 3D Studio Max het character als Autodesk FBX exporteren. Start nu Unity op (als je Unity3d nog niet hebt kun je de gratis Indie versie downloaden). Maak een nieuw project en klik met de rechter muisknop in het project panel — kies Import New Asset… en selecteer het FBX-bestand. Let er op dat de Scale Factor (onder FBXImporter) op 1 staat.
Voeg met het plusje onderaan een animatie toe en stel de lengte goed in (neem het aantal frames uit 3D Studio Max over). Zet de WrapMode op Loop. Sleep de Prefab nu de scene in en druk op Play: je hebt een lopend karakter in Unity!

Een geanimeerd character in Unity3d.
Control
Nu willen we het character natuurlijk ook kunnen besturen, op een 3rd-person manier waarbij we het karakter zien bewegen en de camera meebeweegt. Positioneer hiervoor eerst de camera zo achter het karakter dat het karakter in het preview scherm goed zichtbaar is. De positie van de camera bepaalt hier de blik op het character — het best werkt een beetje boven en achter het karakter. Let op dat de camera wel precies in dezelfde richting als het character kijkt.

Positioneer de camera achter het karakter.
Maak een nieuw game object aan (empty) en noem deze player. Plaats het karakter en de camera in deze groep, zodat we ze gezamenlijk kunnen verplaatsen. Maak een nieuw script aan en kopieer de inhoud van het standaard FirstPersonWalker-script er in. Met een kleine aanpassing kunnen we daar namelijk een third-person-walker van maken. Bij een first-person walker valt de camera samen met het karakter en kun je beiden tegelijk besturen en verplaatsen. Nu willen we het karakter kunnen sturen, maar de hele groep verplaatsen.
Waar nu dus de verplaatsingsvector voor de groep wordt getransformeerd met
moveDirection = transform.TransformDirection(moveDirection);
moet men nu dus gebruik maken van de transform van het karakter. Deze vind je als volgt:
var character = transform.find( "dude" );
waarbij je dude moet vervangen door de naam van het karakter object in je eigen scene. Nu kunnen we die transform gebruiken met:
moveDirection = character.transform.TransformDirection(moveDirection);
Pas dit script toe op de player groep door het er op te slepen. Je zult zien dat er automatisch een Character Controller component wordt toegevoegd, die in de scene zichtbaar wordt als een tonnetje. Door met de afmetingen en center te spelen, kun je deze cylinder precies om je karakter heen vormen zodat er in collision detection rekening mee gehouden kan worden. Maak een plane of box in het level, zodat de speler niet eeuwig zal vallen. Je kunt het karakter nu laten lopen (met WSAD) en de camera gaat mee. Je kunt echter nog niet sturen.
Doordat het karakter loopt in de richting waarin het kijkt, hoeven we alleen toe te voegen dat je de kijkrichting van het karakter kunt beïnvloeden — het script zorgt ervoor dat de juiste richting wordt gevolgd. In Unity3d zit gelukkig standaard een mouse-look script ingebouwd.
Selecteer je karakter en voeg uit Components, Camera-control het Mouse Look gedrag toe. Kies bij de optie Axes voor MouseX om te voorkomen dat je schuin omhoog of omlaag loopt. Het karakter is nu volledig bestuurbaar.
De laatste stap is het meedraaien van de camera. Hiervoor gebruiken we ook een Mouse Look component. Pas deze eerst toe op de camera en bekijk het effect: de camera en speler draaien beiden om hun eigen as, waardoor het karakter uit beeld kan verdwijnen. De camera moet om het centrum van het karakter roteren.
Verwijder het Mouse Look component weer en maak een nieuw game object aan. Noem het camera group, plaats het binnen de player group en plaats de camera er in zodat je deze hierarchie krijgt:
player
camera group
camera
character
biped
character
De camera group zorgt ervoor dat de transformatie van de camera t.o.v. de speler bewaard blijft. Pas Mouse Look nu toe op de camera group. Waarschijlijk wil je de opties voor de Y-as inperken, zodat je camera niet heel hoog of laag kan komen te staan. De third-person controller is nu af.

Rondlopen in Unity3d.
Tot slot is het het mooist als de loop-animatie alleen speelt wanneer we lopen. Dit is eenvoudig, want we kunnen de animatie met de commando’s Stop() en Play() aansturen. Als we nu Play() zeggen wanneer we lopen en Stop() wanneer dat niet zo is zijn we klaar. We kunnen hiervoor bijvoorbeeld kijken naar de lente van de richtingsvector (moveDirection.magnitude). Als die groter dan nul is, lopen we.
if ( moveDirection.magnitude > 0.01 )
dude.animation.Play();
else
dude.animation.Stop();
Het eindresultaat kun je eenvoudigweg hier bekijken in Unity3d. Het Unity-project en de modellen kun je hier downloaden (maar zonder de standard assets van Unity).



Reacties (één)
ProNoob op 02-02-2011 om 11:55:
Sweet! De goedkoopste workaround die ik tot nu toe heb gevonden. Bedankt!