Unskinned Joint Performance / Character Customization

Hi guys,

i posted this question already in the “support” forum, but since i’m not getting any answers there, i thought i might try my luck here:

do unskinned joints (“joints” that aktually dont affect vetecies of a mesh) in a scene actually have impact on the performance of a game?

i’m running into problems with the “character customization” part of the project i’m working on - i want to avoid having all the possible clothes/armor/ etc already skinned but inactive(hidden) on the character, since this would eat a lot of ram for nothing.
so what i’m doing now is: i create an instance of the gameobject in the moment the character is equipping some armor, and assign the same animation controller to this object.
the downside of this approach is, that i cant “reskin” the mesh to the already existing bones, so i need to instance the whole rig again, and make the new gameobject be driven by animations separatly.

the thing now is, that the new instanciated gameobject (armor/clothing) comes with a lot of joints which are actually not skinned/have no influence on any vertecies. but as far as i know, i need them to transfer/control the animation of the object correctly.

is there any better approach than this to achieve the same result? best would be if i was able to “attach” the instanced object to the already existing skeleton, but i’ve read on several posts that this is quite “impossible” becouse of the “random bone order” in the SkinnedMeshRenderer.

any ideas/insights would be awesome! thanks alot!

cheers and thanks!

I have some experience with this, but my case is rather specific so I’m not sure how it scales to other people’s usage…

This is exactly what I do… it isn’t “impossible” :smile: It just isn’t very clear from Unity examples or other forum posts on how to do this. As you’ll see below, once the objects are setup and imported into unity I don’t need to mess with the skinned mesh renderer at all, just the bone transforms.

What I’ve done on my projects is to first setup the master character object in max w/ a skeleton and skinned modifier etc. I also setup any accessory objects (hair, armor etc.) as their own objects/files in max with the SAME skeleton hierarchy, and also with it’s own skinned modifier etc.

In Unity these are imported as separate objects. When I start the scene I only instantiate the character object. When I want to add armor to the character, I instantiate the armor object as a child of the character object, and then run a custom script which gathers all the BIP(skeleton) transforms (by name) from the armor object and then automatically searches and parents these to the BIP transforms of the target character object. This will activate the animations on the armor just as if it were a part of the character object… there is no need to apply a second animation component to the armor, it simply starts acting with the animations that are driving the character skeleton :slight_smile:

When I want to remove the armor, I do this process in reverse… remove all the child BIP transforms from the character skeleton and parent them back to the armor object, then delete the armor object.

This is my bone gather and transfer script… you’ll probably need to modify it for your own project but it’s pretty straight forward and I hope it’s useful…

var AttachToRoot : boolean = true;

private var isOn : boolean = false;
private var InstanceObjects;
private var checkObject : GameObject;
private var targetObject : GameObject;
private var localChildren : Transform[];
private var targetChildren : Transform[];


function Start(){
	checkObject = this.transform.Find("Bip01").gameObject;
	targetObject = this.transform.parent.transform.Find("Bip01").gameObject;
}


function LateUpdate(){

if (!isOn){
	InstanceObjects = new Array(0);
	if (AttachToRoot){
		//ATTACH ALL BONES TO PLAYER BONES
		var namePath = "Bip01";

		if (checkObject != null){
		var localChildren = checkObject.GetComponentsInChildren(Transform);
		var targetChildren = targetObject.GetComponentsInChildren(Transform);
		var ob = 0;

		for (var child : Transform in localChildren) {
			ob +=1;
		}
		InstanceObjects = new Array(ob);
		
		ob=0;
		for (var child : Transform in localChildren) {
			if (child.name !="Bip01"  child.name !="Bip01 Footsteps"  child.name !="Bip01 Chin"  child.name !="Bip01 ChinNub"){
				namePath = namePath+"/"+child.name;
				if (child.gameObject != null){
					for (var targ : Transform in targetChildren) {
						if (targ.name == child.name){
							child.parent = targ.transform;
							child.position = targ.position;
							child.rotation = targ.rotation;
							child.name = targ.name+"("+this.transform.name+")";
							InstanceObjects[ob] = child.name;
							ob+=1;
						}
					}
				} else {
					Debug.Log("ERROR: This sucker won't load : "+namePath);
				}
				if (child.childCount <= 0) namePath = "Bip01";
			}
		}
	}
	}
isOn=true;
}
}



function RemoveAll(){
	if (InstanceObjects){
		if (InstanceObjects.length > 0){
		for (lp = 0; lp < InstanceObjects.length; lp++) {
			if (InstanceObjects[lp] !=null){
				this.transform.parent.gameObject.Find(InstanceObjects[lp]).transform.parent = this.transform;
				//Destroy(GameObject.Find(InstanceObjects.lp));
				//InstanceObjects.RemoveAt(lp);
			}
		}
		}
	}
}

This code would be saved and attached as a component to any “accessory” object. Once that object is instantiated and made a direct child of the character object, the script runs and automatically and should attach the bones to your character. When you want to “detach” you need to call the RemoveAll() function on this component.

NOTE: This was made with 3dsMax “BIP” skeletons in mind, and has not been tested on anything else. Results may vary :smile:

so if i understood you correctly, you’re keeping the unskinned bones in your scene, but constrain the bones of the armor/pants/… to the character bones to transfer the animation, right? i agree - seems like thats a lot cleaner and smarter than adding another animation controller to the armor object!

although, what i actually meant with “impossible” was to import the armor object WITHOUT any additional bones. since i skinned them on the same rig as the character in max/maya/etc already, the mesh should somehow have all the necessary information stored somewhere?

basically i’d love to instance the object without bones, and “attach” the mesh to the existing character rig to avoid having extra (unused) bones in my scene to save performance.

but anyways - thanks a lot for your quick reply, explanation and even sample code!! :smile: i’ll have a close look at it!

Yes exactly. for the armor object I only have to skin the bone(s) that I actually need (so torso and shoulder bones maybe). Bone transforms don’t really have much overhead, they are just math/point computations so having the extra bones in your scene, unskinned, and not being used, really isn’t an issue as long as they don’t mess up your hierarchy organization :slight_smile:

I’m sure I tried this when first building this script (a couple years ago now)… I don’t think this is possible… the animation component animates the bone objects, and the skinned mesh renderer animates the mesh based on the bones and skinning setup. Deleting any part of this system will keep your animation from running. So the armor or accessory object will also need it’s own set of bones to reference.

Have you looked into UMA? If you’re looking for efficiency in character customization, it’s fairly efficient.

Even if it isn’t a solution for you, it might give you useful things to think about.