Exemplo n.º 1
0
        /** 結合処理。GameObject全体に対して処理を行う。dstは初期化される */
        static public bool combine(
            GameObject targetGO,
            MeshObject dst,
            string dstMeshObjName,                      //!< 結合後に生成されるプレファブ内の、メッシュ表示用のGameObjectの名前
            string[] ignoreList = null                  //!< 結合対象外とするオブジェクト名のリスト
            )
        {
            // 結合元となるMesh情報を収集する。最も子供のTransformのものから順に格納する。
            var srcMeshes  = MeshComponentWrapper.getMeshComponentsInChildren(targetGO);
            var srcDataLst = srcMeshes
                             .Where(i => i.mesh.blendShapeCount == 0)                                   // BlendShapeがあるものは結合対象外
                             .Where(i => ignoreList == null || !ignoreList.Contains(i.gameObject.name)) // 無視リストに指定されているオブジェクトは結合対象外
                             .Select(i => (data: MeshObject.generate(i), trans: i.transform)).ToArray();

            // 結合したメッシュを生成
            dst.reset();
            var isSuccess = true;

            foreach (var i in srcDataLst)
            {
                isSuccess &= addTo(i.data, dst);
            }

            // ログに追加
            Log.instance.endCombineMesh(isSuccess, srcDataLst.Select(i => i.data.mesh).ToArray(), dst.mesh);
            if (!isSuccess)
            {
                return(false);
            }

            // 結合したメッシュを表示するオブジェクトを追加
            var combinedMeshObj = new GameObject(dstMeshObjName);

            combinedMeshObj.transform.SetParent(targetGO.transform, false);
            if (dst.bones.Length == 0)
            {
                var mr = combinedMeshObj.AddComponent <MeshRenderer>();
                var mf = combinedMeshObj.AddComponent <MeshFilter>();
                mf.sharedMesh      = dst.mesh;
                mr.sharedMaterials = dst.matLst;
            }
            else
            {
                var smr = combinedMeshObj.AddComponent <SkinnedMeshRenderer>();
                smr.sharedMesh      = dst.mesh;
                smr.sharedMaterials = dst.matLst;
                smr.bones           = dst.bones;
            }

            // 結合前のオブジェクトを削除
            foreach (var i in srcDataLst)
            {
                // 子供がない場合はそのまま削除。
                // 子供の方から順番にイテレートするので、殆どのものはそのまま削除できるはず
                if (i.trans.childCount == 0)
                {
                    UnityEngine.Object.DestroyImmediate(i.trans.gameObject);
                }
                else
                {
                    var mf  = i.trans.GetComponent <MeshFilter>();
                    var mr  = i.trans.GetComponent <MeshRenderer>();
                    var smr = i.trans.GetComponent <SkinnedMeshRenderer>();
                    if (mf != null)
                    {
                        UnityEngine.Object.DestroyImmediate(mf);
                    }
                    if (mr != null)
                    {
                        UnityEngine.Object.DestroyImmediate(mr);
                    }
                    if (smr != null)
                    {
                        UnityEngine.Object.DestroyImmediate(smr);
                    }
                }
            }

            return(true);
        }