I’m trying to set things up so that if our animator put a model in Character folders, the model automatically gets imported as a Humanoid, rather than as a Generic model. I’m pretty stumped.
The problem is defining the avatar in the model. When I manually switch the model from Generic to Humanoid in the Rig tab, it generates an avatar that maps all bones correctly. When I try to supply the same bones through code (through setting the modelImporter’s humanDescription), I get errors.
Here’s the hierarchy we’re trying to import:

(I cut stuff under chest so the image wouldn’t be one million pixels high :p).
There’s two different rigs defined. We’re going to try for a LOD thing with the animation details.
The stuff under unity_humanoid_rig is what we’ll use for the humanoid avatar (with hips_0 as the humanoid hips bone and so on). That works when we manually change from generic to humanoid in the import settings - the correct bones are selected, and animations play correctly.
When we try to do the same thing through asset post processing, it fails. Here’s the model importer code:
public class ModelImportSettings : AssetPostprocessor {
private const string processedTag = "Model_preprocessed";
private const string humanoidCharacterBaseFolder = "Assets/3D Models/Characters";
private void OnPreprocessModel() {
if (!assetPath.StartsWith(humanoidCharacterBaseFolder))
return;
var importer = (ModelImporter) assetImporter;
if (importer.userData.Contains(processedTag))
return;
importer.optimizeGameObjects = true;
importer.importAnimation = false;
importer.animationType = ModelImporterAnimationType.Human;
Func<string, string, HumanBone> Bone = (humanName, boneName) => new HumanBone() {humanName = humanName, boneName = boneName};
var humanDesc = new HumanDescription {
human = new[] {
Bone("Chest", "chest"),
Bone("Head", "head_0"),
Bone("Hips", "hips_0"),
Bone("Left Index Distal", "f_index_03_L"),
Bone("Left Index Intermediate", "f_index_02_L"),
Bone("Left Index Proximal", "f_index_01_L"),
Bone("Left Middle Distal", "f_middle_03_L"),
Bone("Left Middle Intermediate", "f_middle_02_L"),
Bone("Left Middle Proximal", "f_middle_01_L"),
Bone("Left Ring Distal", "f_ring_03_L"),
Bone("Left Ring Intermediate", "f_ring_02_L"),
Bone("Left Ring Proximal", "f_ring_01_L"),
Bone("Left Thumb Distal", "thumb_03_L"),
Bone("Left Thumb Intermediate", "thumb_02_L"),
Bone("Left Thumb Proximal", "thumb_01_L"),
Bone("LeftFoot", "foot_L"),
Bone("LeftHand", "hand_L"),
Bone("LeftLowerArm", "forearm_L_0"),
Bone("LeftLowerLeg", "shin_L_0"),
Bone("LeftShoulder", "shoulder_L"),
Bone("LeftToes", "toe_L"),
Bone("LeftUpperArm", "upper_arm_L"),
Bone("LeftUpperLeg", "thigh_L"),
Bone("Neck", "neck"),
Bone("Right Index Distal", "f_index_03_R"),
Bone("Right Index Intermediate", "f_index_02_R"),
Bone("Right Index Proximal", "f_index_01_R"),
Bone("Right Middle Distal", "f_middle_03_R"),
Bone("Right Middle Intermediate", "f_middle_02_R"),
Bone("Right Middle Proximal", "f_middle_01_R"),
Bone("Right Ring Distal", "f_ring_03_R"),
Bone("Right Ring Intermediate", "f_ring_02_R"),
Bone("Right Ring Proximal", "f_ring_01_R"),
Bone("Right Thumb Distal", "thumb_03_R"),
Bone("Right Thumb Intermediate", "thumb_02_R"),
Bone("Right Thumb Proximal", "thumb_01_R"),
Bone("RightFoot", "foot_R"),
Bone("RightHand", "hand_R"),
Bone("RightLowerArm", "forearm_R_0"),
Bone("RightLowerLeg", "shin_R_0"),
Bone("RightShoulder", "shoulder_R"),
Bone("RightToes", "toe_R"),
Bone("RightUpperArm", "upper_arm_R"),
Bone("RightUpperLeg", "thigh_R"),
Bone("Spine", "spine"),
}
};
importer.humanDescription = humanDesc;
}
void OnPostprocessModel(GameObject model) {
if (!assetPath.StartsWith(humanoidCharacterBaseFolder))
return;
var importer = (ModelImporter) assetImporter;
if (importer.userData.Contains(processedTag))
return;
importer.userData = importer.userData + processedTag;
var animator = model.EnsureComponent<Animator>();
animator.applyRootMotion = true;
animator.avatar = importer.sourceAvatar;
}
}
When I put a .blend file in the given folder, it errors with
“File ‘NPC’ avatar creation failed:
Transform ‘unity_humanoid_rig’ not found in HumanDescription.”
And I get this result in the importer:

Now it seems pretty clear - it expects the unity_humanoid_rig bone to be a part of the human description. The problem is that when we switch from generic to Humanoid, Unity doesn’t generate any mapping for that bone, and that works fine. Here’s the HumanTemplate file Unity generates for the same model:
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1105 &110500000
HumanTemplate:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_Name: New Human Template
m_BoneTemplate:
Chest: chest
Head: head_0
Hips: hips_0
Left Index Distal: f_index_03_L
Left Index Intermediate: f_index_02_L
Left Index Proximal: f_index_01_L
Left Middle Distal: f_middle_03_L
Left Middle Intermediate: f_middle_02_L
Left Middle Proximal: f_middle_01_L
Left Ring Distal: f_ring_03_L
Left Ring Intermediate: f_ring_02_L
Left Ring Proximal: f_ring_01_L
Left Thumb Distal: thumb_03_L
Left Thumb Intermediate: thumb_02_L
Left Thumb Proximal: thumb_01_L
LeftFoot: foot_L
LeftHand: hand_L
LeftLowerArm: forearm_L_0
LeftLowerLeg: shin_L_0
LeftShoulder: shoulder_L
LeftToes: toe_L
LeftUpperArm: upper_arm_L
LeftUpperLeg: thigh_L
Neck: neck
Right Index Distal: f_index_03_R
Right Index Intermediate: f_index_02_R
Right Index Proximal: f_index_01_R
Right Middle Distal: f_middle_03_R
Right Middle Intermediate: f_middle_02_R
Right Middle Proximal: f_middle_01_R
Right Ring Distal: f_ring_03_R
Right Ring Intermediate: f_ring_02_R
Right Ring Proximal: f_ring_01_R
Right Thumb Distal: thumb_03_R
Right Thumb Intermediate: thumb_02_R
Right Thumb Proximal: thumb_01_R
RightFoot: foot_R
RightHand: hand_R
RightLowerArm: forearm_R_0
RightLowerLeg: shin_R_0
RightShoulder: shoulder_R
RightToes: toe_R
RightUpperArm: upper_arm_R
RightUpperLeg: thigh_R
Spine: spine
It’s exactly the same thing as I’m providing in the importer code.
What am I doing wrong? Essentially, I want the same result as if I had clicked the “Automap” button in the avatar configuration menu (Mapping dropdown → automap). Is there any way for me to access that?
