/// <summary> /// /// </summary> /// <param name="element"></param> public void Clone(XAvatarElement element) { Name = element.Name; Prefab = element.Prefab; SmrLocalToWorldMatrix = element.SmrLocalToWorldMatrix; if (element.BoneNames != null) { BoneNames = new List <string>(element.BoneNames); } if (element.SharedMaterials != null) { SharedMaterials = new List <Material>(element.SharedMaterials); } if (element.BindPoses != null) { BindPoses = new List <Matrix4x4>(element.BindPoses); } if (element.BoneWeights != null) { BoneWeights = new List <XBoneWeightRecord>(element.BoneWeights); } }
/// <summary> /// /// </summary> /// <returns></returns> static IEnumerator OnLoadAsync(string name, string[] elementList, System.Action <Object> callabck) { XAvatarCacheInfo cacheInfo = GetCacheAvatar(name, elementList); if (cacheInfo != null && cacheInfo.prefab != null) { if (callabck != null) { GameObject prefab = cacheInfo.prefab; prefab.transform.position = Vector3.one * 1000; prefab.transform.localScale = Vector3.one; prefab.transform.rotation = Quaternion.identity; callabck(prefab); } yield break; } List <Object> elements = new List <Object>(); // load all elements yield return(XRes.LoadMultiAsync(elementList, delegate(Object[] objs) { for (int i = 0; i < objs.Length; i++) { elements.Add(objs[i]); } })); yield return(XRes.LoadAsync <GameObject>(name, delegate(Object obj) { GameObject skeleton = GameObject.Instantiate(obj) as GameObject; if (skeleton && elements.Count > 0) { List <CombineInstance> combineInstances = new List <CombineInstance>(); Transform[] trans = skeleton.GetComponentsInChildren <Transform>(); List <Matrix4x4> bindPoses = new List <Matrix4x4>(); List <Transform> boneTrans = new List <Transform>(); List <Material> shardMatList = new List <Material>(); for (int i = 0; i < elements.Count; i++) { XAvatarElement element = elements[i] as XAvatarElement; if (element && element.Prefab) { GameObject prefab = GameObject.Instantiate(element.Prefab) as GameObject; if (prefab) { SkinnedMeshRenderer skin = prefab.GetComponent <SkinnedMeshRenderer>(); CombineInstance ci = new CombineInstance(); ci.mesh = skin.sharedMesh; ci.transform = element.SmrLocalToWorldMatrix; combineInstances.Add(ci); List <Transform> curBones = new List <Transform>(); foreach (string transName in element.BoneNames) { for (int transIndex = 0; transIndex < trans.Length; transIndex++) { if (transName == trans[transIndex].name) { curBones.Add(trans[transIndex]); bindPoses.Add(trans[transIndex].worldToLocalMatrix * skeleton.transform.localToWorldMatrix); break; } } } boneTrans.AddRange(curBones); Dictionary <string, int> boneWeightDic = element.GenBoneWeightsDic(); foreach (BoneWeight boneWeight in skin.sharedMesh.boneWeights) { BoneWeight bw = boneWeight; bw.boneIndex0 = boneWeightDic[curBones[boneWeight.boneIndex0].name]; bw.boneIndex1 = boneWeightDic[curBones[boneWeight.boneIndex1].name]; bw.boneIndex2 = boneWeightDic[curBones[boneWeight.boneIndex2].name]; bw.boneIndex3 = boneWeightDic[curBones[boneWeight.boneIndex3].name]; } shardMatList.AddRange(element.SharedMaterials); GameObject.DestroyImmediate(prefab); } } } skeleton.transform.position = Vector3.one * 1000; skeleton.name = obj.name; Transform model = skeleton.transform.Find(XActorElementName.shape.ToString()); if (!model) { model = skeleton.transform; } GameObject render = new GameObject(typeof(Renderer).Name); render.transform.parent = model; render.transform.localScale = Vector3.one; render.transform.localPosition = Vector3.zero; render.transform.localRotation = Quaternion.identity; SkinnedMeshRenderer smr = render.AddComponent <SkinnedMeshRenderer>(); smr.sharedMesh = new Mesh(); smr.sharedMesh.CombineMeshes(combineInstances.ToArray(), false, false); smr.bones = boneTrans.ToArray(); smr.sharedMaterials = shardMatList.ToArray(); Animator animator = skeleton.GetComponent <Animator>(); if (animator) { smr.rootBone = animator.GetBoneTransform(HumanBodyBones.Hips); } smr.sharedMesh.RecalculateBounds(); // add avatar cache AddCacheAvatar(name, elementList, skeleton); if (callabck != null) { callabck(skeleton); } } })); }