Unity3D - 不能附加多个身体肢体/网格 [英] Unity3D - Cant attach more then one body limb/mesh

查看:26
本文介绍了Unity3D - 不能附加多个身体肢体/网格的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将所有四肢都分开的 3D 模型中的人类组装在一起.像头、躯干、手臂、腿等.在运行时,我想构建一个完整的人,将所有这些四肢组装在一起.这是我所做的:

I am trying to assemble together human from 3D model that have all limbs split. Like Head,Torso,Arms,Legs etc. And in runtime I would like to build a whole human with all those limbs assembled together. Here is what I do:

private void Start()
{
    Debug.Log("Trying to build a Race!");
    RaceModelSO firstRace = _races[0];
    GameObject stiches = Instantiate(firstRace.GetRaceBodySlots()[0].mesh, new Vector3(773,0.83F,778), Quaternion.identity) as GameObject;
    stiches.name = "HumanMale";
    for (int i = 0; i < firstRace.GetRaceBodySlots().Length; i++)
    {
        if (i != 0)
        {
            GameObject bodyPart = Instantiate(firstRace.GetRaceBodySlots()[i].mesh) as GameObject;
            _stitcher.Stitch(bodyPart, stiches);
        }
    }
}

这是将四肢组装在一起的实际 Stitcher 类.

Here is the actual Stitcher class that is assembling the limbs together.

 public class Stitcher
    {

        public GameObject Stitch(GameObject sourceClothing, GameObject targetAvatar)
        {
            var boneCatalog = new TransformCatalog(targetAvatar.transform);
            var skinnedMeshRenderers = sourceClothing.GetComponentsInChildren<SkinnedMeshRenderer>();
            var targetClothing = AddChild(sourceClothing, targetAvatar.transform);
 
 
            foreach (var sourceRenderer in skinnedMeshRenderers)
            {
                var targetRenderer = AddSkinnedMeshRenderer(sourceRenderer, targetClothing);
                targetRenderer.bones = TranslateTransforms(sourceRenderer.bones, boneCatalog);
            }
            return targetClothing;
        }
 
        private GameObject AddChild(GameObject source, Transform parent)
        {
            source.transform.parent = parent;
 
            foreach (Transform child in source.transform)
            {
                Object.Destroy(child.gameObject);
            }
 
            return source;
        }
 
        private SkinnedMeshRenderer AddSkinnedMeshRenderer(SkinnedMeshRenderer source, GameObject parent)
        {
            GameObject meshObject = new GameObject(source.name);
            meshObject.transform.parent = parent.transform;
 
            var target = meshObject.AddComponent<SkinnedMeshRenderer>();
            target.sharedMesh = source.sharedMesh;
            target.materials = source.materials;
            return target;
        }
 
        private Transform[] TranslateTransforms(Transform[] sources, TransformCatalog transformCatalog)
        {
            var targets = new Transform[sources.Length];
            for (var index = 0; index < sources.Length; index++)
                targets[index] = DictionaryExtensions.Find(transformCatalog, sources[index].name);
            return targets;
        }
 
        #region TransformCatalog
        private class TransformCatalog : Dictionary<string, Transform>
        {
            #region Constructors
            public TransformCatalog(Transform transform)
            {
                Catalog(transform);
            }
            #endregion
 
            #region Catalog
            private void Catalog(Transform transform)
            {
                if (ContainsKey(transform.name))
                {
                    Remove(transform.name);
                    Add(transform.name, transform);
                }
                else
                    Add(transform.name, transform);
                foreach (Transform child in transform)
                    Catalog(child);
            }
            #endregion
        }
        #endregion
 
 
        #region DictionaryExtensions
        private class DictionaryExtensions
        {
            public static TValue Find<TKey, TValue>(Dictionary<TKey, TValue> source, TKey key)
            {
                TValue value;
                source.TryGetValue(key, out value);
                return value;
            }
        }
        #endregion
 
    }

让我解释一下这个问题.在 firstRace.GetRaceBodySlots() 中,我拥有所有肢体的预制件.我得到了所有这些,并为每个调用了 _stitcher.Stitch().

So let me explain the issue. In firstRace.GetRaceBodySlots() I have all the prefabs with all limbs of the body. I get all of them and I call _stitcher.Stitch() for each of them.

问题是第一个肢体是在 :

The problem is that the first limb is the one created before the :

for (int i = 0; i < firstRace.GetRaceBodySlots().Length; i++)
{
    if (i != 0)
    {
        GameObject bodyPart = Instantiate(firstRace.GetRaceBodySlots()[i].mesh) as GameObject;
        _stitcher.Stitch(bodyPart, stiches);
    }
}

而且只有第二个肢体正确连接,所有其他肢体都在那里但不可见.看一看:

And that only the second limb gets attached properly all the others are there but not visible. Take a look:

所以 SOH_HM_1_Head 是在 foreach 之前创建的第一个肢体,而第二个 SOH_HM_1_Body 是循环中的第一个肢体并且只有那个是从 foreach 循环内部可见的.所有其他的都是创造出来的,但不可见.看一看:

So SOH_HM_1_Head is the first limb that was created before the foreach than is the second one SOH_HM_1_Body which is the first one inside the loop and only that one was created visible from all inside the foreach loop. All others are created but invisible. Take a look:

你知道为什么只有 foreach 循环内部的第一个分支被创建为可见吗?知道我该如何解决这个问题.

Do you have any idea why only the first limb from inside the foreach loop gets created visible? Any idea how can I solve this issue.

附言

看起来这里描述了完全相同的问题:这里

Looks like the exact same issue was described here: Here

你能建议任何其他方法而不是协程吗?

Can you suggest any other method rather than coroutine ?

推荐答案

对于所有正在寻找一种使用相同装备将多个网格拼接成一个的方法的人,我想出了一些小脚本:Unity-3D-MeshStitcher

For all people searching for a way to stitch many meshes into one all using same rig, I've come up with some small script: Unity-3D-MeshStitcher

这篇关于Unity3D - 不能附加多个身体肢体/网格的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆