🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

Force skinned mesh to use another skeleton

Started by
3 comments, last by rogerdv 9 years, 2 months ago

Im trying to find a solution for the issue of assemblying a character from several pieces in Unity, and my current approach is to export body parts from Blender to different fbx files, including the armature. Then I exported only the armature to another fbx file. In unity editor I create a hierarchy of GameObjects:

Player (parent)

Skeleton

Head

Torso

Legs

Hands

Feet

The problem is that I cant find a way in Unity to tell each body part to use the skeleton avatar and animation controller, instead of its own, or find another solution that allows me to animate the assembled body and switch some of its parts with items like armors. Can somebody suggest me what to do?

Advertisement

Here's one solution someone used, seems several people have had success with it according to the comments.

Hazard Pay :: FPS/RTS in SharpDX (gathering dust, retained for... historical purposes)
DeviantArt :: Because right-brain needs love too (also pretty neglected these days)

I think I read that post, but didnt got any useful conclusio, Ill have to re-read it. After long hours of trial and error, I produced a solution: I set the parent GameObject's animation controller to use head's avatar, same for all the body parts (I think). It worked in the editor, now Im trying to reproduce the same via c# scripts. So far I managed to create the character with all the parts in place, even managed to replace torso with an armor and keep the idle anim running without deformations, but cant switch to other animations.

What I've done in the past, was to combine the all the meshes to the single mesh and then use Animator on this mesh.

I've exported all the parts as a solo files. Each of them has the whole skeleton BUT with particular mesh only (head, torso, ...). Then in unity I've written a script that combines all the meshes to the single mesh and used it normally.

Here is the testing script (a bit long) to build the whole character:


public class assemble : MonoBehaviour {
	Transform me;
	Animator anim;
	private Vector3 position;
	NavMeshAgent agent;

	GameObject head;
	GameObject torso;
	GameObject hands;
	GameObject legs;
	GameObject feet;
	RuntimeAnimatorController contr;

	// Use this for initialization
	void Start () {
		me = transform;
		anim = GetComponent<Animator>();
		agent = GetComponent<NavMeshAgent> ();
		Object test = Resources.Load("vmale-anim");
		contr = (RuntimeAnimatorController)RuntimeAnimatorController.Instantiate(test);
		anim.runtimeAnimatorController = contr;
		GameObject prefab = Resources.Load("vmale-head") as GameObject;
		head = Instantiate(prefab) as GameObject; 
		head.transform.SetParent(me);
		head.transform.localPosition = Vector3.zero;
		head.transform.localRotation = Quaternion.Euler(Vector3.zero);
		head.GetComponent<Animator> ().runtimeAnimatorController = contr;
		//build torso
		prefab = Resources.Load("vmale-torso") as GameObject;
		//prefab = Resources.Load("items/armors/iron_armor") as GameObject;
		torso = Instantiate(prefab) as GameObject; 
		torso.transform.SetParent(me);
		torso.transform.localPosition = Vector3.zero;
		torso.transform.localRotation = Quaternion.Euler(Vector3.zero);
		torso.GetComponent<Animator> ().runtimeAnimatorController = contr;
		//build hands
		prefab = Resources.Load("vmale-hands") as GameObject;
		hands = Instantiate(prefab) as GameObject; 
		hands.transform.SetParent(me);
		hands.transform.localPosition = Vector3.zero;
		hands.transform.localRotation = Quaternion.Euler(Vector3.zero);
		hands.GetComponent<Animator> ().runtimeAnimatorController = contr;
		//build legs
		prefab = Resources.Load("vmale-legs") as GameObject;
		//prefab = Resources.Load("items/armors/iron_leggins") as GameObject;
		legs = Instantiate(prefab) as GameObject; 
		legs.transform.SetParent(me);
		legs.transform.localPosition = Vector3.zero;
		legs.transform.localRotation = Quaternion.Euler(Vector3.zero);
		legs.GetComponent<Animator> ().runtimeAnimatorController = contr;
		//build feet
		prefab = Resources.Load("vmale-feet") as GameObject;
		feet = Instantiate(prefab) as GameObject; 
		feet.transform.SetParent(me);
		feet.transform.localPosition = Vector3.zero;
		feet.transform.localRotation = Quaternion.Euler(Vector3.zero);
		feet.GetComponent<Animator> ().runtimeAnimatorController = contr;
	}
	
	// Update is called once per frame
	void Update () {
		if (agent.pathStatus == NavMeshPathStatus.PathComplete) {
			anim.SetInteger("CharacterState", 1);
		}
		if (Input.GetKey (KeyCode.Mouse0)) {
			//basic character movement for testing
                        RaycastHit hit;
			Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);
			if (Physics.Raycast (ray, out hit, 1000)) 
			{
				position = new Vector3(hit.point.x,hit.point.y,hit.point.z);
				agent.SetDestination(position);
				anim.SetInteger("CharacterState", 2);
			}
		}
	
	}
}

The only problem is that it fails to change animations, stays forever in Idle.

This topic is closed to new replies.

Advertisement