Dev Blog
Home                Games                Archive
 
 
 
 
MÅRD Tech Talk, Part 1 - UMA
Feb 15, 2016
    
 
 

Let's start off this dev blog with some tech rant about my latest game "MÅRD".

 

Unity Multipurpose Avatar

The characters in MÅRD are all generated with the help of UMA 2 - a framework for Unity3D, which allows you to create and generate characters on the fly with unique DNA settings.

With UMA you get a wide range of DNA settings that helps you making each avatar unique and lifelike. An UMA consists of slots and overlays, which basically are model body parts and textures. Each body part is a slot: head, hair, eyes, inner mouth, torso, legs and feet. On top of the fundamental slots you can add more slots to create clothes for your avatar. Every slot contains overlays and each overlay can be layered on top of each other to create special features. You could e.g layer 3 overlays on the head slot to create the skin, beard and tattoos.

Slots and Overlays

Generating a UMA by code is quite simple

 

GameObject GO = new GameObject(UMAName);
umaDynamicAvatar = GO.AddComponent<UMADynamicAvatar>();
umaDynamicAvatar.Initialize();
umaData = umaDynamicAvatar.umaData;
umaData.OnCharacterCreated += CharacterCreatedCallbak;
umaData.OnCharacterUpdated += CharacterUpdatedCallback;
umaDynamicAvatar.umaGenerator = generator;
umaData.umaGenerator = generator;
umaData.umaRecipe.slotDataList = new SlotData[numberOfSlots];
// Setup morph references
umaDna = new UMADnaHumanoid();
umaTutorialDNA = new UMADnaTutorial();
umaData.umaRecipe.AddDna(umaDna);
umaData.umaRecipe.AddDna(umaTutorialDNA);
CreateMale();
// Setup animation controller
umaDynamicAvatar.animationController = animController;
// Generate UMA
umaDynamicAvatar.UpdateNewRace();

 

After that you can add animator controllers to animate your character. Also, don't forget to add your slots and overlays


var umaRecipe = umaDynamicAvatar.umaData.umaRecipe;
umaRecipe.SetRace(raceLibrary.GetRace("HumanMale"));
umaData.umaRecipe.slotDataList[0] = slotLibrary.InstantiateSlot("MaleFace");
umaData.umaRecipe.slotDataList[0].AddOverlay(overlayLibrary.InstantiateOverlay("MaleHead02"));



Expressions

Not only can you create you own set of unique characters, UMA also comes with a expression player that enables you to animate your avatar's facial expressions without the need of writing a single line of code. Blinking, gaze mode and saccades are just some of the cool features that you can enable in the expression player to make your avatar look more alive and lifelike. All this can of course be extended with the help of some coding to animate the mouth to talk or make a frowny face.

 

expressionPlayer = umaData.gameObject.AddComponent<ExpressionPlayer>();

expressionPlayer.expressionSet = expressionSet;
expressionPlayer.midBrowUp_Down = 1.0f;
expressionPlayer.leftMouthSmile_Frown = 1.0f;
expressionPlayer.rightMouthSmile_Frown = 1.0f;



 
Hello
 
 
 

Update character

Once you have generated your avatar there will be moments where you need to check for updates in the geometry and textures. Here's where UMA's callbacks comes into play, else your avatar might end up looking like in the picture above

 

umaData = umaDynamicAvatar.umaData;
umaData.OnCharacterCreated += CharacterCreatedCallbak;
umaData.OnCharacterUpdated += CharacterUpdatedCallback;

 

 The callback methods are useful if you are changing your character's appearance during runtime, e.g changing clothes or equiping weapons. For this you could use a callback method like this to update the textures

 

void CharacterUpdatedCallback(UMAData umaData)
{
umaData.isTextureDirty = true;
umaData.Dirty ();
}

 

Equiping stuff

Do you need to equip weapons or other items to your character? No problem, this can easily be achieved by parenting your gameobjects to the avatar rig and position it

 

GameObject weapon = GameObject.Find("Weapon");
Transform hand = umaData.skeleton.GetBoneGameObject(UMASkeleton.StringToHash("RightHand")).transform;
weapon.transform.SetParent(hand);
weapon.transform.localPosition = new Vector3(-0.158f, 0.372f, -0.02f);
weapon.transform.localRotation = Quaternion.Euler(new Vector3(-0.02f, 356f, 8.12f));

 

In closing...

This has been a quick dive into what you can do with UMA and how it can help you bring more life to the characters in your game. In the next updates I will talk about more cool stuff that MÅRD has to offer.



More updates

If you want even more updates then don't forget to subscribe to the Black Curtain Studio newsletter below.

Newsletter subscription

Home                Archive