Пример #1
0
    protected GameObject CreateByData(MayaObject data)
    {
        GameObject reference = GetReference(data.name);
        GameObject result    = GameObject.Instantiate(reference, data.position, Quaternion.Euler(data.rotation));

        result.name = data.name;
        return(result);
    }
Пример #2
0
    protected GameObject CreateInnerObject(List <MayaObject> path, MayaObject obj)
    {
        path.Add(obj);
        GameObject reference = GetObjectInnerFBX(path);

        if (reference != null)
        {
            reference      = GameObject.Instantiate(reference, obj.position, Quaternion.Euler(obj.rotation));
            reference.name = obj.name;
        }
        path.RemoveAt(path.Count - 1);
        return(reference);
    }
Пример #3
0
    private void OnGUI()
    {
        EditorGUI.BeginChangeCheck();
        textasset = (TextAsset)EditorGUILayout.ObjectField(textasset, typeof(TextAsset), false);

        if (textasset != null && GUILayout.Button("Apply"))
        {
            mayaObject = JsonUtility.FromJson <MayaObject>(textasset.text);
            string filepath = AssetDatabase.GetAssetPath(textasset);
            directory = System.IO.Directory.GetParent(filepath).FullName;

            path.Clear();
            ApplyObject(mayaObject, path);
            OnCreatedEvent(objCreated);
            objCreated.Clear();
        }

        GUIPrefix();
    }
    public static string SkinnedMeshToMel(MayaObject MayaObj)
    {
        string data = "";

        return(data);
    }
    // --------------------------------------------------
    // Process Mesh
    // --------------------------------------------------
    // Given a Mesh, this will query all the mesh data,
    // format it to Maya conventions, and write it to the file.
    //
    // Note - We must supply the ShapeName here, instead of using
    // the MayaObject.MayaName. We need this sort of setup because
    // we have to make 2 copies of the mesh data when creating
    // skinned meshes, the meshShape and meshShapeOrig.
    //
    // Note - For skinned meshes, the MeshShapeOrig needs
    // intermediate object set to TRUE.
    //public static void ProcessMesh(MayaObject MayaObj, bool ExportNormals, bool ExportUVs, bool ExportLightmapUVs, bool ExportVertexColors, bool ExportMaterials, bool ExportTextures, float ExportScale){
    public static void ProcessMesh(MayaObject MayaObj, string ParentName, string ShapeName, bool IntermediateObj)
    {
        string data = "";

        // Get a reference to the mesh of the MayaObject depending on
        // if the MayaObj is a Mesh or SkinnedMesh
        Mesh m = new Mesh();

        if (MayaObj.Type == ObjType.Mesh)
        {
            m = MayaObj.UnityObject.gameObject.GetComponent <MeshFilter>().sharedMesh;
        }
        if (MayaObj.Type == ObjType.SkinnedMesh)
        {
            m = MayaObj.UnityObject.gameObject.GetComponent <SkinnedMeshRenderer>().sharedMesh;
        }

        // Update progress bar
        Export2Maya.ProgressBarMessage(ShapeName, "Getting Mesh Data");

        // --------------------------------------------------
        // Gather mesh data
        // --------------------------------------------------
        Vector3[] verts   = m.vertices;
        Vector2[] uvs     = m.uv;
        Vector2[] uvs2    = m.uv2;
        Color[]   colors  = m.colors;
        Vector3[] normals = m.normals;
        int[]     tris    = m.triangles;

        // --------------------------------------------------
        // Get the Lightmap tiling and offset if Lightmap UVs exist
        // --------------------------------------------------
        Vector4 tilingOffset = new Vector4();

//!!!		if(uvs2.Length > 0) tilingOffset = MayaObj.UnityObject.gameObject.renderer.lightmapTilingOffset;
        if (uvs2.Length > 0)
        {
            tilingOffset = MayaObj.UnityObject.gameObject.GetComponent <Renderer>().lightmapScaleOffset;
        }

        // --------------------------------------------------
        // Perform UV and UV2 Zero Value checks here. With the
        // Tree Creator, it makes lightmap UVs all with Zero values
        // which can mess up our calculations when applying
        // the tiling and offset
        //
        // So check and see if all the UVs have zero values, if so
        // then disable UV or UV2 export
        // --------------------------------------------------
        bool ZeroUV  = true;
        bool ZeroUV2 = true;

        for (int i = 0; i < uvs.Length; i++)
        {
            if (uvs[i].x != 0)
            {
                ZeroUV = false;
                break;
            }
            if (uvs[i].y != 0)
            {
                ZeroUV = false;
                break;
            }
        }
        for (int i = 0; i < uvs2.Length; i++)
        {
            if (uvs2[i].x != 0)
            {
                ZeroUV2 = false;
                break;
            }
            if (uvs2[i].y != 0)
            {
                ZeroUV2 = false;
                break;
            }
        }

        // --------------------------------------------------
        // Write shape attributes
        // --------------------------------------------------
        data += "createNode mesh -n \"" + ShapeName + "\" -p \"" + ParentName + "\";\n";
        data += "\tsetAttr -k off \".v\";\n";
        if (IntermediateObj)
        {
            data += "\tsetAttr \".io\" yes;\n";                         // Set intermediate object flag to true (for skinned meshes)
        }
        data += "\tsetAttr \".vir\" yes;\n";
        data += "\tsetAttr \".vif\" yes;\n";

        // Write data to file
        Export2Maya.AppendToFile(data);
        data = "";

        // --------------------------------------------------
        // If the user has chosen to export materials
        // --------------------------------------------------
        if (Export2Maya.ExportMaterials)
        {
            // --------------------------------------------------
            // Sub Mesh - Per face material assignment
            // --------------------------------------------------
            // If the sub mesh count is greater than 1, we have
            // per face material assignment. If this is the case, write
            // out the per face assignments
            int SubMeshCount = m.subMeshCount;
            if (SubMeshCount > 1)
            {
                // Set the instObjGroup size to the number of sub meshes
                data += "\tsetAttr -s " + SubMeshCount + " \".iog[0].og\";\n";

                // Go through each sub mesh and add its face assignments
                int TotalSubMeshTris = 0;
                for (int i = 0; i < SubMeshCount; i++)
                {
                    // Get the sub mesh triangle count
                    int[] SubTriangles = m.GetTriangles(i);
                    data += "\tsetAttr \".iog[0].og[" + i + "].gcl\" -type \"componentList\" 1 \"f[" + ((SubTriangles.Length / 3) > 1 ? (TotalSubMeshTris.ToString() + ":") : "") + (((SubTriangles.Length / 3) - 1) + TotalSubMeshTris) + "]\";\n";

                    // Increment TotalSubMeshTris
                    TotalSubMeshTris += SubTriangles.Length / 3;
                }
            }

            // --------------------------------------------------
            // Material Assignment
            // --------------------------------------------------
            // Get material(s) list for the mesh
            Material[] mats = MayaObj.UnityObject.gameObject.GetComponent <Renderer>().sharedMaterials;

            // If the sub mesh count is greater than 1, then we need to handle
            // per-face assignment
            if (SubMeshCount > 1)
            {
                // Go through sub meshes
                for (int i = 0; i < SubMeshCount; i++)
                {
                    // Find the material in our MayaMaterials list
                    for (int j = 0; j < Export2Maya.MayaMaterials.Count; j++)
                    {
                        // Note - User Error Check !!
                        // If you import the mesh and manually alter the array count in inspector, this could result
                        // in the submesh count being greater than the materials count. Which is bad. In this case we
                        // create a new index that is based on Submesh count (i) and check if its greater than materials count.
                        // if it is, we clamp it to the materials count.
                        int ind = i;
                        if (ind >= mats.Length)
                        {
                            ind = mats.Length - 1;
                        }

                        // If we found the material
                        if (Export2Maya.MayaMaterials[j].UnityMaterial == mats[ind])
                        {
                            // Increment GroupID counter
                            Export2Maya.GroupIDCounter++;

                            // Create GroupID node
                            Export2Maya.MayaConnections += "createNode groupId -n \"groupId" + Export2Maya.GroupIDCounter + "\";\n";
                            Export2Maya.MayaConnections += "\tsetAttr \".ihi\" 0;\n";                                                   // Is historically interesting

                            // Connect groupID.id > mesh.instObjGroups
                            Export2Maya.MayaConnections += "connectAttr \"groupId" + Export2Maya.GroupIDCounter + ".id\" \"" + ShapeName + ".iog.og[" + i + "].gid\";\n";

                            // Connect groupID.message > SG.groupNodes
                            Export2Maya.MayaConnections += "connectAttr \"groupId" + Export2Maya.GroupIDCounter + ".msg\" \"" + Export2Maya.MayaMaterials[j].MayaName + "SG.gn\" -na;\n";

                            // Connect SG.memberWireframeColor > mesh.instObjGroups
                            Export2Maya.MayaConnections += "connectAttr \"" + Export2Maya.MayaMaterials[j].MayaName + "SG.mwc\" \"" + ShapeName + ".iog.og[" + i + "].gco\";\n";

                            // Connect mesh.instObjGroups > SG.dagSetMembers
                            Export2Maya.MayaConnections += "connectAttr \"" + ShapeName + ".iog.og[" + i + "]\" \"" + Export2Maya.MayaMaterials[j].MayaName + "SG.dsm\" -na;\n";

                            // Since we found the material, break out of the loop
                            break;
                        }
                    }
                }
            }
            // If the sub mesh count is 1, then we handle
            // per-object assignment
            else
            {
                // Find the material in our MayaMaterials list
                for (int mat = 0; mat < Export2Maya.MayaMaterials.Count; mat++)
                {
                    // If we found the material
                    if (Export2Maya.MayaMaterials[mat].UnityMaterial == mats[0])
                    {
                        Export2Maya.MayaConnections += "connectAttr \"" + ShapeName + ".iog\" \"" + Export2Maya.MayaMaterials[mat].MayaName + "SG.dsm\" -na;\n";
                        break;
                    }
                }
            }
        }
        // --------------------------------------------------
        // If the user has chosen to not export materials
        // --------------------------------------------------
        else
        {
            // Just assign the default lambert1 material to the object
            Export2Maya.MayaConnections += "connectAttr \"" + ShapeName + ".iog\" \":initialShadingGroup.dsm\" -na;\n";
        }

        // --------------------------------------------------
        // Build UV, UV2, Color and Vertex lists
        // --------------------------------------------------
        // Note - From what I've seen, the vertex list, the UV list, the UV2 list and the colors list are
        // always the same size. So as an optimization lets just pick the vertex list as our iterator and
        // fill out all the data in 1 go to save time
        //
        // The only exception is the normals since Maya stores normals per-vertex per-face, where as the
        // other lists get referenced by the face definitions
        string uvData    = "";
        string uv2Data   = "";
        string colorData = "";
        string vertData  = "";

        // Update progress bar
        Export2Maya.ProgressBarMessage(ShapeName, "UVs, Colors, Vertices");

        // Column counter used for nicely formatting the data in the Maya file
        // NOTE - We also use it below for the edge list as well
        int ColumnCounter = 0;

        for (int i = 0; i < verts.Length; i++)
        {
            // Format UV data
            if (uvs.Length > 0)
            {
                if (ColumnCounter == 0)
                {
                    uvData += "\t\t";
                }
                uvData += uvs[i].x + " " + uvs[i].y + " ";
                if (ColumnCounter == Export2Maya.ColumnDataWidth)
                {
                    uvData += "\n";
                }
            }

            // Format UV2 data
            if (uvs2.Length > 0)
            {
                if (ColumnCounter == 0)
                {
                    uv2Data += "\t\t";
                }
                uv2Data += ((uvs2[i].x * tilingOffset.x) + tilingOffset.z) + " " + ((uvs2[i].y * tilingOffset.y) + tilingOffset.w) + " ";
                if (ColumnCounter == Export2Maya.ColumnDataWidth)
                {
                    uv2Data += "\n";
                }
            }

            // Format color data
            if (colors.Length > 0)
            {
                if (ColumnCounter == 0)
                {
                    colorData += "\t\t";
                }
                colorData += colors[i].r + " " + colors[i].g + " " + colors[i].b + " " + colors[i].a + " ";
                if (ColumnCounter == Export2Maya.ColumnDataWidth)
                {
                    colorData += "\n";
                }
            }

            // Format vertex data
            if (ColumnCounter == 0)
            {
                vertData += "\t\t";
            }
            Vector3 MayaVert = MayaUtilities.MayaTranslation(verts[i]) * Export2Maya.MayaExportScale;             // Multiply by export scale
            vertData += (MayaVert.x + " " + MayaVert.y + " " + MayaVert.z + " ");
            if (ColumnCounter == Export2Maya.ColumnDataWidth)
            {
                vertData += "\n";
            }

            // Increment column counter
            ColumnCounter++;
            if (ColumnCounter > Export2Maya.ColumnDataWidth)
            {
                ColumnCounter = 0;
            }
        }

        // --------------------------------------------------
        // Write UV data
        // --------------------------------------------------
        if (Export2Maya.ExportUVs && !ZeroUV)
        {
            if (uvs.Length > 0)
            {
                data += "\tsetAttr \".uvst[0].uvsn\" -type \"string\" \"map1\";\n";
                data += "\tsetAttr -s " + verts.Length + " \".uvst[0].uvsp[" + (verts.Length > 1 ? "0:" : "") + (verts.Length - 1) + "]\" -type \"float2\" \n" + uvData + ";\n";
                data += "\tsetAttr  \".cuvs\" -type \"string\" \"map1\";\n";                    // Set the current uv set to the main uv set

                // Write data to file
                Export2Maya.AppendToFile(data);
                data = "";
            }
        }

        // --------------------------------------------------
        // Write UV2 data
        // --------------------------------------------------
        if (Export2Maya.ExportLightmapUVs && !ZeroUV2)
        {
            if (uvs2.Length > 0)
            {
                data += "\tsetAttr \".uvst[1].uvsn\" -type \"string\" \"lightmap\";\n";
                data += "\tsetAttr -s " + verts.Length + " \".uvst[1].uvsp[" + (verts.Length > 1 ? "0:" : "") + (verts.Length - 1) + "]\" -type \"float2\" \n" + uv2Data + ";\n";

                // Write data to file
                Export2Maya.AppendToFile(data);
                data = "";
            }
        }

        // --------------------------------------------------
        // Write Color data ( RGBA )
        // --------------------------------------------------
        if (Export2Maya.ExportVertexColors)
        {
            if (colors.Length > 0)
            {
                // Display vertex colors on file load? ON
                data += "\tsetAttr \".dcol\" yes;\n";
                // Set which color channel to display (Ambient + Diffuse)
                data += "\tsetAttr \".dcc\" -type \"string\" \"Ambient+Diffuse\";\n";
                // Set the current color set
                data += "\tsetAttr \".ccls\" -type \"string\" \"colorSet1\";\n";
                data += "\tsetAttr \".clst[0].clsn\" -type \"string\" \"colorSet1\";\n";

                data += "\tsetAttr -s " + verts.Length + " \".clst[0].clsp[" + (verts.Length > 1 ? "0:" : "") + (verts.Length - 1) + "]\" " + colorData + ";\n";

                // Write data to file
                Export2Maya.AppendToFile(data);
                data = "";
            }
        }

        // Write data to file
        data += "\tsetAttr -s " + verts.Length + " \".vt[" + (verts.Length > 1 ? "0:" : "") + (verts.Length - 1) + "]\" \n" + vertData + ";\n";
        Export2Maya.AppendToFile(data);
        data = "";

        // --------------------------------------------------
        // Edge Connections
        // --------------------------------------------------
        // Since Unity stores all polygons as triangles, this will be easy.
        // We will have 3 possible edge connections per face:
        // edgeA:(vert0->vert1) edgeB:(vert1->vert2) edgeC:(vert2->vert0)
        // Note - We have to check that the edge doesn't already exist in our
        // local list before storing the edge. No duplicates allowed!
        List <MayaEdge> EdgeList   = new List <MayaEdge>();             // Local edge list
        bool            EdgeExists = false;

        // Edge Index list:
        // We will fill this guy out as we go so its ready when writing the
        // polygon face data. This will be a list of indices that point to our
        // local edge list which describe the edges of a face
        List <int> EdgeIndexList = new List <int>();

        // Update progress bar
        Export2Maya.ProgressBarMessage(ShapeName, "Edge List");

        // Go through every triangle (3 verts)
        for (int v = 0; v < tris.Length; v += 3)
        {
            // Edge A
            EdgeExists = false;                 // Reset exists value
            for (int i = 0; i < EdgeList.Count; i++)
            {
                if (EdgeList[i].Match(tris[v], tris[v + 1]) != 0)
                {
                    EdgeExists = true;
                    EdgeIndexList.Add(i);
                    break;
                }
            }
            if (!EdgeExists)
            {
                EdgeList.Add(new MayaEdge(tris[v], tris[v + 1]));
                EdgeIndexList.Add(EdgeList.Count - 1);
            }

            // Edge B
            EdgeExists = false;                 // Reset exists value
            for (int i = 0; i < EdgeList.Count; i++)
            {
                if (EdgeList[i].Match(tris[v + 1], tris[v + 2]) != 0)
                {
                    EdgeExists = true;
                    EdgeIndexList.Add(i);
                    break;
                }
            }
            if (!EdgeExists)
            {
                EdgeList.Add(new MayaEdge(tris[v + 1], tris[v + 2]));
                EdgeIndexList.Add(EdgeList.Count - 1);
            }

            // Edge C
            EdgeExists = false;                 // Reset exists value
            for (int i = 0; i < EdgeList.Count; i++)
            {
                if (EdgeList[i].Match(tris[v + 2], tris[v]) != 0)
                {
                    EdgeExists = true;
                    EdgeIndexList.Add(i);
                    break;
                }
            }
            if (!EdgeExists)
            {
                EdgeList.Add(new MayaEdge(tris[v + 2], tris[v]));
                EdgeIndexList.Add(EdgeList.Count - 1);
            }
        }

        // --------------------------------------------------
        // Combine edges into single string
        // --------------------------------------------------
        string EdgesStr = "\n";

        ColumnCounter = 0;
        for (int i = 0; i < EdgeList.Count; i++)
        {
            if (ColumnCounter == 0)
            {
                EdgesStr += "\t\t";
            }
            EdgesStr += (EdgeList[i].StartEdge + " " + EdgeList[i].EndEdge + " 0 ");
            if (ColumnCounter == Export2Maya.ColumnDataWidth)
            {
                EdgesStr += "\n";
            }

            // Increment column counter
            ColumnCounter++;
            if (ColumnCounter > Export2Maya.ColumnDataWidth)
            {
                ColumnCounter = 0;
            }
        }

        // Write data to file
        data += "\tsetAttr -s " + EdgeList.Count + " \".ed[" + (EdgeList.Count > 1 ? "0:" : "") + (EdgeList.Count - 1) + "]\" " + EdgesStr + ";\n";
        Export2Maya.AppendToFile(data);
        data = "";

        // --------------------------------------------------
        // Normals
        // --------------------------------------------------
        // The way Unity specifies the normals list is 1 normal per vertex
        // entry. But we need normals per-vertex per-face. So we go through the
        // triangles list and find what vertices make up the face. We then use
        // that to index into the normals array to find the normals per face
        if (Export2Maya.ExportNormals)
        {
            // Update progress bar
            Export2Maya.ProgressBarMessage(ShapeName, "Normals");

            string NormalsStr = "";
            for (int v = 0; v < tris.Length; v += 3)
            {
                // Get the normals and convert them into Maya translation
                Vector3 normalA = MayaUtilities.MayaTranslation(normals[tris[v]]);
                Vector3 normalB = MayaUtilities.MayaTranslation(normals[tris[v + 1]]);
                Vector3 normalC = MayaUtilities.MayaTranslation(normals[tris[v + 2]]);

                // Not sure why this works, but we have to flip normal C and normal B for them to match
                // correctly in Maya. Weird
                NormalsStr += ("\t\t" + normalA.x + " " + normalA.y + " " + normalA.z + " ");
                NormalsStr += (normalC.x + " " + normalC.y + " " + normalC.z + " ");
                NormalsStr += (normalB.x + " " + normalB.y + " " + normalB.z);

                // Add a return character if not the last entry into the normals list,
                // this way the last one has the semicolon next to the number instead of the next line
                if (v + 3 < tris.Length - 1)
                {
                    NormalsStr += "\n";
                }
            }

            // Write data to file
            data += "\tsetAttr -s " + tris.Length + " \".n[0:" + (tris.Length - 1) + "]\" -type \"float3\"\n" + NormalsStr + ";\n";
            Export2Maya.AppendToFile(data);
            data = "";
        }

        // --------------------------------------------------
        // Faces
        // --------------------------------------------------
        // Now we need to tell Maya which edges make up each face. In Unity you can
        // specify the faces simply by giving 3 indexes into the vertex array, and it will build the
        // face from that, but Maya is different. Maya needs edges specified in order to define a face.
        // So for each triangle go through the edges list and find the corresponding edges that
        // match the triangle vertices
        Export2Maya.ProgressBarMessage(ShapeName, "Faces");

        // --------------------------------------------------
        // 1 or more faces check!
        // --------------------------------------------------
        // For an object that has more than 1 face, Maya will list the range
        // of faces like so: [0:N]
        // BUT! if there are objects with just 1 face, Maya will list the range
        // like so: [0]
        // So do a check here and make sure the correct format is used
        string faceFormat = ""; if ((tris.Length / 3) > 1)

        {
            faceFormat = "0:";
        }

        data += "\tsetAttr -s " + (tris.Length / 3) + " \".fc[" + faceFormat + ((tris.Length / 3) - 1) + "]\" -type \"polyFaces\"\n";
        for (int i = 0; i < tris.Length; i += 3)
        {
            // --------------------------------------------------
            // Record the polygon face-edge data
            // --------------------------------------------------
            // NOTE! We reverse the order of the edge indices, from ABC to CBA
            // because Maya uses a counter-clockwise winding order for faces and Unity
            // gives us the data in clockwise winding order
            data += "\t\tf 3 " + EdgeIndexList[i + 2] + " " + EdgeIndexList[i + 1] + " " + EdgeIndexList[i];

            // Record the main UV data per face, if it exists and is requested.
            // Note - We don't completely reverse the order, but swap the second and
            // last values so it displays correctly in Maya
            if (Export2Maya.ExportUVs)
            {
                if (uvs.Length > 0)
                {
                    data += " mu 0 3 " + tris[i] + " " + tris[i + 2] + " " + tris[i + 1];
                }
            }

            // Record the lightmap UV data per face, if it exists and is requested.
            // Same swapping mechanism as the main UV data
            if (Export2Maya.ExportLightmapUVs)
            {
                if (uvs2.Length > 0)
                {
                    data += " mu 1 3 " + tris[i] + " " + tris[i + 2] + " " + tris[i + 1];
                }
            }

            // Record vertex color per face, if it exists and is requested
            if (Export2Maya.ExportVertexColors)
            {
                if (colors.Length > 0)
                {
                    data += " mc 0 3 " + tris[i] + " " + tris[i + 2] + " " + tris[i + 1];
                }
            }

            data += "\n";
        }
        // Add trailing semicolon after face setup
        data += ";\n";

        // Write data to file
        Export2Maya.AppendToFile(data);
        data = "";
    }
    // --------------------------------------------------
    // Pre-Processor
    // --------------------------------------------------
    //
    // This is a convenience method. Given a MayaObject it will determine if it should
    // process it as a mesh, or a skinned mesh. Since skinned meshes are identical to
    // regular meshes, just with added skinned mesh "stuff", we reuse the mesh code because
    // its long and involved. No sense in duplicating code.
    //public static void BeginExport(MayaObject MayaObj){
    //	// If it is a mesh
    //	if(MayaObj.Type == ObjType.Mesh) ProcessMesh(MayaObj, MayaObj.MayaName, MayaObj.MayaName + "Shape", false);
    //
    //	// If it is a skinned mesh
    //	if(MayaObj.Type == ObjType.SkinnedMesh) ProcessSkinnedMesh(MayaObj);
    //}

    // --------------------------------------------------
    // Process Skinned Mesh
    // --------------------------------------------------
    //
    //public static void ProcessSkinnedMesh(MayaObject MayaObj, bool ExportNormals, bool ExportUVs, bool ExportLightmapUVs, bool ExportVertexColors, bool ExportMaterials, bool ExportTextures, float ExportScale){
    public static void ProcessSkinnedMesh(MayaObject MayaObj)
    {
        ProcessMesh(MayaObj, MayaObj.MayaName, (MayaObj.MayaName + "Shape"), false);
        ProcessMesh(MayaObj, MayaObj.MayaName, (MayaObj.MayaName + "ShapeOrig"), true);
    }
Пример #7
0
    protected void ApplyObject(MayaObject mayaObject, List <MayaObject> path, GameObject parentReference = null)
    {
        GameObject obj = null;

        if (!string.IsNullOrEmpty(mayaObject.name))
        {
            // Recuperar objeto existente
            if (parentReference != null)
            {
                Transform tr = parentReference.transform.FindChild(mayaObject.name);
                if (tr != null)
                {
                    obj = tr.gameObject;
                }
            }
            else
            {
                obj = GameObject.Find(mayaObject.name);
            }



            // Caso o objeto nao for encontrado na cena, recriar objeto
            if (obj == null)
            {
                if (mayaObject.name.Contains("_GO"))
                {
                    obj = CreateByData(mayaObject);
                }
                else
                {
                    obj = CreateInnerObject(path, mayaObject);
                }

                if (obj == null)
                {
                    obj = new GameObject(mayaObject.name);
                }

                obj.isStatic = true;

                Undo.RegisterCreatedObjectUndo(obj, "Created Obj By Maya");
            }

            // configurar posicao e rotacao do objeto
            Undo.RecordObject(obj.transform, "Transform Position");
            obj.transform.rotation = MayaRotationToUnity(mayaObject.rotation);
            obj.transform.position = mayaObject.position;
            Undo.SetTransformParent(obj.transform, parentReference != null ? parentReference.transform : null, "Organize Hierarchy");
            //obj.transform.parent = parentReference != null ? parentReference.transform : null;

            //adiciona mesh collider para o pai ou para si mesmo
            if (mayaObject.name.Contains("_COL"))
            {
                if (mayaObject.name.Contains("_GO"))
                {
                    MeshCollider col = obj.GetComponent <MeshCollider>();
                    if (col == null)
                    {
                        col = parentReference.AddComponent <MeshCollider>();
                    }
                    col.sharedMesh = obj.GetComponent <MeshFilter>().sharedMesh;
                }
                else
                {
                    MeshCollider col = parentReference.GetComponent <MeshCollider>();
                    if (col == null)
                    {
                        col = parentReference.AddComponent <MeshCollider>();
                    }
                    col.sharedMesh = obj.GetComponent <MeshFilter>().sharedMesh;
                    DestroyImmediate(obj);
                    return;
                }
            }

            //add components by prefix
            foreach (PrefixToBehaviour pr in prefixGrp.prefix)
            {
                if (!string.IsNullOrEmpty(pr.prefix) && mayaObject.name.Contains(pr.prefix))
                {
                    System.Type tp = GetType(pr.className);
                    if (tp != null)
                    {
                        if (obj.GetComponent(tp) == null)
                        {
                            obj.AddComponent(tp);
                        }
                    }
                    else
                    {
                        Debug.Log("NAO ENCONTREI: " + pr.className);
                    }
                }
            }

            //remove renderer
            if (mayaObject.name.Contains("_RR"))
            {
                obj.GetComponent <Renderer>().enabled = false;
            }

            if (mayaObject.name.Contains("_PREF"))
            {
                System.IO.Directory.CreateDirectory("Assets/Prefabs/Maya");
                string     prefabPath    = "Assets/Prefabs/Maya/" + obj.name + ".prefab";
                GameObject currentPrefab = AssetDatabase.LoadAssetAtPath <GameObject>(prefabPath);
                GameObject prefab        = (currentPrefab != null) ?
                                           PrefabUtility.ReplacePrefab(obj, currentPrefab, ReplacePrefabOptions.Default) :
                                           PrefabUtility.CreatePrefab(prefabPath, obj);
                DestroyImmediate(obj);
                obj = prefab;
            }

            //add to object created
            objCreated.Add(obj);
        }



        // continua recursividade para os filhos

        if (mayaObject.children == null)
        {
            return;
        }

        path.Add(mayaObject);
        foreach (MayaObject mo in mayaObject.children)
        {
            ApplyObject(mo, path, obj);
        }
        path.RemoveAt(path.Count - 1);
    }