using Sirenix.OdinInspector; using System; using System.Collections; using System.Collections.Generic; using UnityEngine; public class MeshCenterSelect : MonoBehaviour { public GameObject modelA; public GameObject modelB; // 模型A的层级树对象 public objTree ObjATree; public objTree ObjBTree; [DictionaryDrawerSettings] public Dictionary objADic; [DictionaryDrawerSettings] public Dictionary objBDic; [Button("测试")] void CreateTree() { ObjATree = new objTree(modelA); ObjBTree = new objTree(modelB); objADic = new Dictionary(); objBDic = new Dictionary(); FindChild(ObjATree, objADic); FindChild(ObjBTree, objBDic); GameObject newFenzumubiao = new GameObject("分组目标"); HierarchicalMatching(ObjATree, newFenzumubiao); modelB.transform.SetParent(newFenzumubiao.transform, newFenzumubiao); modelB.name = "没配对上的"; } void FindChild(objTree child, Dictionary pairs) //收集未分组的mesh { if(child.meshRenderer != null) { if (!pairs.ContainsKey(child.CenterV3)) pairs.Add(child.CenterV3, child); else Debug.LogError(child.nodeObj.name); } // 递归遍历所有子物体 for (int i = 0; i < child.children.Count; i++) FindChild(child.children[i], pairs); } void HierarchicalMatching(objTree tree, GameObject NowPoint) //按层级匹配 { GameObject matchTmpObj; if (tree.meshRenderer != null && objBDic.TryGetValue(tree.CenterV3, out objTree tmpObj)) matchTmpObj = tmpObj.nodeObj; else { matchTmpObj = new GameObject(); matchTmpObj.name = tree.nodeObj.name; } matchTmpObj.transform.SetParent(NowPoint.transform); foreach (objTree tmp in tree.children) HierarchicalMatching(tmp, matchTmpObj); } [Serializable] public class objTree { public MeshRenderer meshRenderer; public GameObject nodeObj; public List children = new List(); public Vector3 CenterV3; public objTree(GameObject gameObj) { nodeObj = gameObj;//节点 if(nodeObj.GetComponent()!= null) { meshRenderer = nodeObj.GetComponent(); Vector3 tmpV3 = meshRenderer.bounds.center; CenterV3 = new Vector3(float.Parse(tmpV3.x.ToString("F2")), float.Parse(tmpV3.y.ToString("F2")), float.Parse(tmpV3.z.ToString("F2"))); } addObjNode(); } public void addObjNode() { for (int i = 0; i < nodeObj.transform.childCount; i++) { children.Add(new objTree(nodeObj.transform.GetChild(i).gameObject)); } } } public struct Vector3Double { public double x, y, z; public Vector3Double(double x, double y, double z) { this.x = x; this.y = y; this.z = z; } // 转换为 Unity 的 Vector3(会损失精度) public Vector3 ToVector3() { return new Vector3((float)x, (float)y, (float)z); } // 从 Vector3 转换 public static Vector3Double FromVector3(Vector3 v) { return new Vector3Double(v.x, v.y, v.z); } } }