同步操作将从 jzt/UnityFun 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
using UnityEngine;using System.Collections.Generic;public class CombineMesh : MonoBehaviour{public GameObject skeleton;public GameObject face;public GameObject hands;public GameObject lower;public GameObject upper;public GameObject weapon;void EquipWeapon(int hand, GameObject avatar, GameObject weapon){Transform handTransform = null;if (hand == 1){handTransform = avatar.transform.FindChild("Bip01/dummy_right_weapon_at");}else{handTransform = avatar.transform.FindChild("Bip01/dummy_left_weapon_at");}var weaponTransform = weapon.transform;weaponTransform.SetParent(handTransform);weaponTransform.localPosition = Vector3.zero;weaponTransform.localRotation = Quaternion.identity;weaponTransform.localScale = Vector3.one;}void ReplaceElement(int elementType, GameObject avatar, GameObject dummy){if (elementType == 1) //头{var dummyElement = dummy.transform.FindChild("face").gameObject;var avatarElement = avatar.transform.FindChild("face").gameObject;dummyElement.transform.SetParent(avatar.transform);GameObject.Destroy(dummy);GameObject.Destroy(avatarElement);var skinnedMeshRenderer = dummyElement.GetComponent<SkinnedMeshRenderer>();var avatarBones = avatar.GetComponentsInChildren<Transform>();List<Transform> newBones = new List<Transform>();foreach (Transform bone in skinnedMeshRenderer.bones){foreach (Transform avatarBone in avatarBones){//找对应骨骼进行替换if (avatarBone.name.Equals(bone.name)){newBones.Add(avatarBone);break;}}}skinnedMeshRenderer.bones = newBones.ToArray();}}void OnGUI(){if (GUI.Button(new Rect(50, 400, 100, 50), "替换骨骼")){ReplaceElement(1, skeleton, face);EquipWeapon(2, skeleton, weapon);return;var faceSMR = face.GetComponentInChildren<SkinnedMeshRenderer>();faceSMR.transform.SetParent(skeleton.transform);GameObject.DestroyImmediate(skeleton.transform.FindChild("face").gameObject);var avatarBones = gameObject.GetComponentsInChildren<Transform>();List<Transform> newBones = new List<Transform>();foreach (Transform bone in faceSMR.bones){foreach (Transform avatarBone in avatarBones){if (avatarBone.name.Equals(bone.name)){avatarBone.localPosition = bone.localPosition;avatarBone.localScale = bone.localScale;avatarBone.localRotation = bone.localRotation;newBones.Add(avatarBone);break;}}}faceSMR.bones = newBones.ToArray();}if (GUI.Button(new Rect(50, 300, 100, 50), "换头2")){SkinnedMeshRenderer[] meshes = new SkinnedMeshRenderer[4];GameObject[] objects = new GameObject[4];meshes[0] = face.GetComponentInChildren<SkinnedMeshRenderer>();meshes[1] = hands.GetComponentInChildren<SkinnedMeshRenderer>();meshes[2] = lower.GetComponentInChildren<SkinnedMeshRenderer>();meshes[3] = upper.GetComponentInChildren<SkinnedMeshRenderer>();CombineObject(skeleton, meshes, false);}if (GUI.Button(new Rect(50, 100, 100, 50), "换头1")){MergeChild(skeleton);return;//目标部件//var targetSMRs = face.GetComponentsInChildren<SkinnedMeshRenderer>();//SkinnedMeshRenderer targetSMR = null;//for (int i = 0; i < targetSMRs.Length; i++)//{// if (targetSMRs[i].gameObject.name.Equals("face"))// {// targetSMR = targetSMRs[i];// break;// }//}//裸体原型List<Material> materials = new List<Material>();List<CombineInstance> combineInstances = new List<CombineInstance>();List<Transform> bones = new List<Transform>();//bones.AddRange(skeleton.transform.FindChild("Bip01").GetComponentsInChildren<Transform>(true));Matrix4x4 myTransform = skeleton.transform.worldToLocalMatrix;var nudeSMRs = skeleton.GetComponentsInChildren<SkinnedMeshRenderer>();for (int i = 0; i < nudeSMRs.Length; i++){SkinnedMeshRenderer skinnedMeshRenderer = nudeSMRs[i];foreach (Transform bone in skinnedMeshRenderer.bones){bones.Add(bone);}//材质materials.AddRange(skinnedMeshRenderer.materials);//网格CombineInstance combine = new CombineInstance();combine.mesh = skinnedMeshRenderer.sharedMesh;combine.transform = myTransform * skinnedMeshRenderer.transform.localToWorldMatrix;combineInstances.Add(combine);for (int sub = 0; sub < skinnedMeshRenderer.sharedMesh.subMeshCount; sub++){combine.subMeshIndex = sub;//combineInstances.Add(combine);}skinnedMeshRenderer.gameObject.SetActive(false);//if (nudeSMRs[i].gameObject.name.Equals("face"))//{// nudeSMRs[i].gameObject.SetActive(false);//}}List<Matrix4x4> bindposes = new List<Matrix4x4>();for (int i = 0; i < bones.Count; i++){bindposes.Add(bones[i].worldToLocalMatrix * skeleton.transform.worldToLocalMatrix);}//合并SkinnedMeshRenderer smr = skeleton.AddComponent<SkinnedMeshRenderer>();smr.materials = materials.ToArray();smr.sharedMesh = new Mesh();smr.sharedMesh.name = skeleton.name;smr.sharedMesh.CombineMeshes(combineInstances.ToArray(), false);//smr.sharedMesh.bindposes = bindposes.ToArray();smr.sharedMesh.RecalculateBounds();smr.bones = bones.ToArray();}}public static void MergeChild(GameObject gameObject){if (gameObject.GetComponent<SkinnedMeshRenderer>() != null){//LogTool.Error("合并结果对象不能有SkinnedMeshRenderer");return;}var meshRenderers = gameObject.GetComponentsInChildren<SkinnedMeshRenderer>();List<BoneWeight> boneWeights = new List<BoneWeight>();List<Transform> bones = new List<Transform>();List<CombineInstance> combines = new List<CombineInstance>();List<Material> materials = new List<Material>();int boneOffset = 0;for (int i = 0; i < meshRenderers.Length; i++){SkinnedMeshRenderer skinnedMeshRenderer = meshRenderers[i];if (skinnedMeshRenderer.sharedMesh.triangles.Length == 0){Debug.LogError(skinnedMeshRenderer.gameObject.name + "模型网格顶点数据为空!检查导入模型Read/Write Enabled");return;}BoneWeight[] meshBoneweight = skinnedMeshRenderer.sharedMesh.boneWeights;foreach (BoneWeight bw in meshBoneweight){BoneWeight bWeight = bw;bWeight.boneIndex0 += boneOffset;bWeight.boneIndex1 += boneOffset;bWeight.boneIndex2 += boneOffset;bWeight.boneIndex3 += boneOffset;boneWeights.Add(bWeight);}boneOffset += skinnedMeshRenderer.bones.Length;foreach (Transform bone in skinnedMeshRenderer.bones){bool contain = false;foreach (Transform bone2 in bones){if (bone2.name.Equals(bone.name)){contain = true;}}if (!contain){bones.Add(bone);}}//combines[i].mesh = skinnedMeshRenderer.sharedMesh;//combines[i].transform = skinnedMeshRenderer.transform.localToWorldMatrix;//materials[i] = skinnedMeshRenderer.sharedMaterial;//材质materials.AddRange(skinnedMeshRenderer.materials);//网格CombineInstance combine = new CombineInstance();combine.mesh = skinnedMeshRenderer.sharedMesh;combine.transform = skinnedMeshRenderer.transform.localToWorldMatrix;for (int sub = 0; sub < skinnedMeshRenderer.sharedMesh.subMeshCount; sub++){combine.subMeshIndex = sub;combines.Add(combine);}GameObject.Destroy(skinnedMeshRenderer.gameObject);}List<Matrix4x4> bindposes = new List<Matrix4x4>();for (int i = 0; i < bones.Count; i++){bindposes.Add(bones[i].worldToLocalMatrix * gameObject.transform.worldToLocalMatrix);}SkinnedMeshRenderer meshRenderer = gameObject.GetComponent<SkinnedMeshRenderer>();if (meshRenderer == null){meshRenderer = gameObject.AddComponent<SkinnedMeshRenderer>();}meshRenderer.sharedMesh = new Mesh();meshRenderer.sharedMesh.name = gameObject.name;meshRenderer.sharedMesh.CombineMeshes(combines.ToArray(), false);meshRenderer.bones = bones.ToArray();//meshRenderer.sharedMesh.boneWeights = boneWeights.ToArray();meshRenderer.sharedMesh.bindposes = bindposes.ToArray();meshRenderer.sharedMesh.RecalculateBounds();meshRenderer.sharedMaterials = materials.ToArray();}/// <summary>/// Combine SkinnedMeshRenderers together and share one skeleton./// Merge materials will reduce the drawcalls, but it will increase the size of memory./// </summary>/// <param name="skeleton">combine meshes to this skeleton(a gameobject)</param>/// <param name="meshes">meshes need to be merged</param>/// <param name="combine">merge materials or not</param>public void CombineObject(GameObject skeleton, SkinnedMeshRenderer[] meshes, bool combine = false){// Fetch all bones of the skeletonList<Transform> transforms = new List<Transform>();transforms.AddRange(skeleton.GetComponentsInChildren<Transform>(true));List<Material> materials = new List<Material>();//the list of materialsList<CombineInstance> combineInstances = new List<CombineInstance>();//the list of meshesList<Transform> bones = new List<Transform>();//the list of bones// Collect information from meshesfor (int i = 0; i < meshes.Length; i++){SkinnedMeshRenderer smr = meshes[i];materials.AddRange(smr.materials); // Collect materials// Collect meshesfor (int sub = 0; sub < smr.sharedMesh.subMeshCount; sub++){CombineInstance ci = new CombineInstance();ci.mesh = smr.sharedMesh;ci.subMeshIndex = sub;combineInstances.Add(ci);}// Collect bonesfor (int j = 0; j < smr.bones.Length; j++){int tBase = 0;for (tBase = 0; tBase < transforms.Count; tBase++){if (smr.bones[j].name.Equals(transforms[tBase].name)){bones.Add(transforms[tBase]);break;}}}}// Create a new SkinnedMeshRendererSkinnedMeshRenderer oldSKinned = skeleton.GetComponent<SkinnedMeshRenderer>();if (oldSKinned != null){GameObject.DestroyImmediate(oldSKinned);}SkinnedMeshRenderer r = skeleton.AddComponent<SkinnedMeshRenderer>();r.sharedMesh = new Mesh();r.sharedMesh.CombineMeshes(combineInstances.ToArray(), combine, false);// Combine meshesr.bones = bones.ToArray();// Use new bonesr.materials = materials.ToArray();}}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。