29using System.Collections;
31using System.Collections.Generic;
51 ref StringBuilder objects,
52 ref StringBuilder connections,
53 GameObject parentObject =
null,
54 long parentModelId = 0)
56 StringBuilder tempObjectSb =
new StringBuilder();
57 StringBuilder tempConnectionsSb =
new StringBuilder();
63 MeshFilter filter = gameObj.GetComponent<MeshFilter>();
64 SkinnedMeshRenderer skinnedMesh = gameObj.GetComponent<SkinnedMeshRenderer>();
67 Mesh meshToExport =
new Mesh();
69 meshToExport = filter.sharedMesh;
70 else if(skinnedMesh !=
null)
72 meshToExport =
new Mesh();
73 skinnedMesh.BakeMesh(meshToExport);
76 if(meshToExport ==
null)
77 Debug.LogError(
"Couldn't find a mesh to export");
79 string meshName = gameObj.name;
82 string isMesh =
"Null";
84 if(meshToExport !=
null)
86 meshName = meshToExport.name;
92 if(filter.sharedMesh ==
null)
99 meshName = filter.sharedMesh.name;
105 if(meshName ==
"" && skinnedMesh !=
null)
106 meshName =
"Skinned Mesh " +
Random.Range(0, 1000000);
108 if(parentModelId == 0)
109 tempConnectionsSb.AppendLine(
"\t;Model::" + meshName +
", Model::RootNode");
111 tempConnectionsSb.AppendLine(
"\t;Model::" + meshName +
", Model::USING PARENT");
112 tempConnectionsSb.AppendLine(
"\tC: \"OO\"," + modelId +
"," + parentModelId);
113 tempConnectionsSb.AppendLine();
114 tempObjectSb.AppendLine(
"\tModel: " + modelId +
", \"Model::" + gameObj.name +
"\", \"" + isMesh +
"\" {");
115 tempObjectSb.AppendLine(
"\t\tVersion: 232");
116 tempObjectSb.AppendLine(
"\t\tProperties70: {");
117 tempObjectSb.AppendLine(
"\t\t\tP: \"RotationOrder\", \"enum\", \"\", \"\",4");
118 tempObjectSb.AppendLine(
"\t\t\tP: \"RotationActive\", \"bool\", \"\", \"\",1");
119 tempObjectSb.AppendLine(
"\t\t\tP: \"InheritType\", \"enum\", \"\", \"\",1");
120 tempObjectSb.AppendLine(
"\t\t\tP: \"ScalingMax\", \"Vector3D\", \"Vector\", \"\",0,0,0");
121 tempObjectSb.AppendLine(
"\t\t\tP: \"DefaultAttributeIndex\", \"int\", \"Integer\", \"\",0");
123 Vector3 position = gameObj.transform.localPosition;
125 tempObjectSb.Append(
"\t\t\tP: \"Lcl Translation\", \"Lcl Translation\", \"\", \"A+\",");
128 tempObjectSb.AppendFormat(
"{0},{1},{2}",
FE.FBXFormat(position.x * -1),
FE.FBXFormat(position.y),
FE.FBXFormat(position.z));
129 tempObjectSb.AppendLine();
132 Vector3 localRotation = gameObj.transform.localEulerAngles;
133 tempObjectSb.AppendFormat(
"\t\t\tP: \"Lcl Rotation\", \"Lcl Rotation\", \"\", \"A+\",{0},{1},{2}",
FE.FBXFormat(localRotation.x),
FE.FBXFormat(localRotation.y * -1),
FE.FBXFormat(-1 * localRotation.z));
134 tempObjectSb.AppendLine();
137 Vector3 localScale = gameObj.transform.localScale;
138 tempObjectSb.AppendFormat(
"\t\t\tP: \"Lcl Scaling\", \"Lcl Scaling\", \"\", \"A\",{0},{1},{2}",
FE.FBXFormat(localScale.x),
FE.FBXFormat(localScale.y),
FE.FBXFormat(localScale.z));
139 tempObjectSb.AppendLine();
141 tempObjectSb.AppendLine(
"\t\t\tP: \"currentUVSet\", \"KString\", \"\", \"U\", \"map1\"");
142 tempObjectSb.AppendLine(
"\t\t}");
143 tempObjectSb.AppendLine(
"\t\tShading: T");
144 tempObjectSb.AppendLine(
"\t\tCulling: \"CullingOff\"");
145 tempObjectSb.AppendLine(
"\t}");
148 if(meshToExport !=
null)
150 Mesh mesh = meshToExport;
157 tempObjectSb.AppendLine(
"\tGeometry: " + geometryId +
", \"Geometry::\", \"Mesh\" {");
160 Vector3[] verticies = mesh.vertices;
161 int vertCount = mesh.vertexCount * 3;
163 tempObjectSb.AppendLine(
"\t\tVertices: *" + vertCount +
" {");
164 tempObjectSb.Append(
"\t\t\ta: ");
165 for(
int i = 0; i < verticies.Length; i++)
168 tempObjectSb.Append(
",");
171 tempObjectSb.AppendFormat(
"{0},{1},{2}",
FE.FBXFormat(verticies[i].x * -1),
FE.FBXFormat(verticies[i].y),
FE.FBXFormat(verticies[i].z));
174 tempObjectSb.AppendLine();
175 tempObjectSb.AppendLine(
"\t\t} ");
178 int triangleCount = mesh.triangles.Length;
179 int[] triangles = mesh.triangles;
181 tempObjectSb.AppendLine(
"\t\tPolygonVertexIndex: *" + triangleCount +
" {");
184 tempObjectSb.Append(
"\t\t\ta: ");
185 for(
int i = 0; i < triangleCount; i += 3)
188 tempObjectSb.Append(
",");
191 tempObjectSb.AppendFormat(
"{0},{1},{2}",
194 (triangles[i + 1] * -1) - 1);
198 tempObjectSb.AppendLine();
200 tempObjectSb.AppendLine(
"\t\t} ");
201 tempObjectSb.AppendLine(
"\t\tGeometryVersion: 124");
202 tempObjectSb.AppendLine(
"\t\tLayerElementNormal: 0 {");
203 tempObjectSb.AppendLine(
"\t\t\tVersion: 101");
204 tempObjectSb.AppendLine(
"\t\t\tName: \"\"");
205 tempObjectSb.AppendLine(
"\t\t\tMappingInformationType: \"ByPolygonVertex\"");
206 tempObjectSb.AppendLine(
"\t\t\tReferenceInformationType: \"Direct\"");
209 Vector3[] normals = mesh.normals;
211 tempObjectSb.AppendLine(
"\t\t\tNormals: *" + (triangleCount * 3) +
" {");
212 tempObjectSb.Append(
"\t\t\t\ta: ");
214 for(
int i = 0; i < triangleCount; i += 3)
217 tempObjectSb.Append(
",");
220 Vector3 newNormal = normals[triangles[i]];
222 tempObjectSb.AppendFormat(
"{0},{1},{2},",
223 FE.FBXFormat(newNormal.x * -1),
224 FE.FBXFormat(newNormal.y),
225 FE.FBXFormat(newNormal.z));
227 newNormal = normals[triangles[i + 2]];
229 tempObjectSb.AppendFormat(
"{0},{1},{2},",
230 FE.FBXFormat(newNormal.x * -1),
231 FE.FBXFormat(newNormal.y),
232 FE.FBXFormat(newNormal.z));
234 newNormal = normals[triangles[i + 1]];
236 tempObjectSb.AppendFormat(
"{0},{1},{2}",
237 FE.FBXFormat(newNormal.x * -1),
238 FE.FBXFormat(newNormal.y),
239 FE.FBXFormat(newNormal.z));
242 tempObjectSb.AppendLine();
243 tempObjectSb.AppendLine(
"\t\t\t}");
244 tempObjectSb.AppendLine(
"\t\t}");
247 bool containsColors = mesh.colors.Length == verticies.Length;
251 Color[] colors = mesh.colors;
253 Dictionary<Color, int> colorTable =
new Dictionary<Color, int>();
257 for (
int i = 0; i < colors.Length; i++)
259 if (!colorTable.ContainsKey(colors[i]))
261 colorTable[colors[i]] = idx;
266 tempObjectSb.AppendLine(
"\t\tLayerElementColor: 0 {");
267 tempObjectSb.AppendLine(
"\t\t\tVersion: 101");
268 tempObjectSb.AppendLine(
"\t\t\tName: \"Col\"");
269 tempObjectSb.AppendLine(
"\t\t\tMappingInformationType: \"ByPolygonVertex\"");
270 tempObjectSb.AppendLine(
"\t\t\tReferenceInformationType: \"IndexToDirect\"");
271 tempObjectSb.AppendLine(
"\t\t\tColors: *" + colorTable.Count * 4 +
" {");
272 tempObjectSb.Append(
"\t\t\t\ta: ");
275 foreach (KeyValuePair<Color, int> color
in colorTable)
278 tempObjectSb.Append(
",");
280 tempObjectSb.AppendFormat(
"{0},{1},{2},{3}",
FE.FBXFormat(color.Key.r),
FE.FBXFormat(color.Key.g),
FE.FBXFormat(color.Key.b),
FE.FBXFormat(color.Key.a));
283 tempObjectSb.AppendLine();
285 tempObjectSb.AppendLine(
"\t\t\t\t}");
288 tempObjectSb.AppendLine(
"\t\t\tColorIndex: *" + triangles.Length +
" {");
289 tempObjectSb.Append(
"\t\t\t\ta: ");
291 for (
int i = 0; i < triangles.Length; i += 3)
294 tempObjectSb.Append(
",");
297 int index1 = triangles[i];
298 int index2 = triangles[i + 2];
299 int index3 = triangles[i + 1];
302 index1 = colorTable[colors[index1]];
303 index2 = colorTable[colors[index2]];
304 index3 = colorTable[colors[index3]];
306 tempObjectSb.AppendFormat(
"{0},{1},{2}", index1, index2, index3);
309 tempObjectSb.AppendLine();
311 tempObjectSb.AppendLine(
"\t\t\t}");
312 tempObjectSb.AppendLine(
"\t\t}");
315 Debug.LogWarning(
"Mesh contains " + mesh.vertices.Length +
" vertices for " + mesh.colors.Length +
" colors. Skip color export");
374 tempObjectSb.AppendLine(
"\t\tLayerElementMaterial: 0 {");
375 tempObjectSb.AppendLine(
"\t\t\tVersion: 101");
376 tempObjectSb.AppendLine(
"\t\t\tName: \"\"");
377 tempObjectSb.AppendLine(
"\t\t\tMappingInformationType: \"ByPolygon\"");
378 tempObjectSb.AppendLine(
"\t\t\tReferenceInformationType: \"IndexToDirect\"");
380 int totalFaceCount = 0;
383 int numberOfSubmeshes = mesh.subMeshCount;
385 StringBuilder submeshesSb =
new StringBuilder();
388 if(numberOfSubmeshes == 1)
390 int numFaces = triangles.Length / 3;
392 for(
int i = 0; i < numFaces; i++)
394 submeshesSb.Append(
"0,");
400 List<int[]> allSubmeshes =
new List<int[]>();
403 for(
int i = 0; i < numberOfSubmeshes; i++)
404 allSubmeshes.Add(mesh.GetIndices(i));
407 for(
int i = 0; i < triangles.Length; i += 3)
409 for(
int subMeshIndex = 0; subMeshIndex < allSubmeshes.Count; subMeshIndex++)
411 bool breaker =
false;
413 for(
int n = 0; n < allSubmeshes[subMeshIndex].Length; n += 3)
415 if(triangles[i] == allSubmeshes[subMeshIndex][n]
416 && triangles[i + 1] == allSubmeshes[subMeshIndex][n + 1]
417 && triangles[i + 2] == allSubmeshes[subMeshIndex][n + 2])
419 submeshesSb.Append(subMeshIndex.ToString());
420 submeshesSb.Append(
",");
432 tempObjectSb.AppendLine(
"\t\t\tMaterials: *" + totalFaceCount +
" {");
433 tempObjectSb.Append(
"\t\t\t\ta: ");
434 tempObjectSb.AppendLine(submeshesSb.ToString());
435 tempObjectSb.AppendLine(
"\t\t\t} ");
436 tempObjectSb.AppendLine(
"\t\t}");
439 tempObjectSb.AppendLine(
"\t\tLayer: 0 {");
440 tempObjectSb.AppendLine(
"\t\t\tVersion: 100");
441 tempObjectSb.AppendLine(
"\t\t\tLayerElement: {");
442 tempObjectSb.AppendLine(
"\t\t\t\tType: \"LayerElementNormal\"");
443 tempObjectSb.AppendLine(
"\t\t\t\tTypedIndex: 0");
444 tempObjectSb.AppendLine(
"\t\t\t}");
445 tempObjectSb.AppendLine(
"\t\t\tLayerElement: {");
446 tempObjectSb.AppendLine(
"\t\t\t\tType: \"LayerElementMaterial\"");
447 tempObjectSb.AppendLine(
"\t\t\t\tTypedIndex: 0");
448 tempObjectSb.AppendLine(
"\t\t\t}");
449 tempObjectSb.AppendLine(
"\t\t\tLayerElement: {");
450 tempObjectSb.AppendLine(
"\t\t\t\tType: \"LayerElementTexture\"");
451 tempObjectSb.AppendLine(
"\t\t\t\tTypedIndex: 0");
452 tempObjectSb.AppendLine(
"\t\t\t}");
455 tempObjectSb.AppendLine(
"\t\t\tLayerElement: {");
456 tempObjectSb.AppendLine(
"\t\t\t\tType: \"LayerElementColor\"");
457 tempObjectSb.AppendLine(
"\t\t\t\tTypedIndex: 0");
458 tempObjectSb.AppendLine(
"\t\t\t}");
460 tempObjectSb.AppendLine(
"\t\t\tLayerElement: {");
461 tempObjectSb.AppendLine(
"\t\t\t\tType: \"LayerElementUV\"");
462 tempObjectSb.AppendLine(
"\t\t\t\tTypedIndex: 0");
463 tempObjectSb.AppendLine(
"\t\t\t}");
469 tempObjectSb.AppendLine(
"\t\t}");
470 tempObjectSb.AppendLine(
"\t}");
473 tempConnectionsSb.AppendLine(
"\t;Geometry::, Model::" + mesh.name);
474 tempConnectionsSb.AppendLine(
"\tC: \"OO\"," + geometryId +
"," + modelId);
475 tempConnectionsSb.AppendLine();
478 MeshRenderer meshRenderer = gameObj.GetComponent<MeshRenderer>();
479 if(meshRenderer !=
null)
481 Material[] allMaterialsInThisMesh = meshRenderer.sharedMaterials;
483 for(
int i = 0; i < allMaterialsInThisMesh.Length; i++)
485 Material mat = allMaterialsInThisMesh[i];
486 int referenceId = Mathf.Abs(mat.GetInstanceID());
490 Debug.LogError(
"ERROR: the game object " + gameObj.name +
" has an empty material on it. This will export problematic files. Please fix and reexport");
494 tempConnectionsSb.AppendLine(
"\t;Material::" + mat.name +
", Model::" + mesh.name);
495 tempConnectionsSb.AppendLine(
"\tC: \"OO\"," + referenceId +
"," + modelId);
496 tempConnectionsSb.AppendLine();
503 for(
int i = 0; i < gameObj.transform.childCount; i++)
505 GameObject childObject = gameObj.transform.GetChild(i).gameObject;
506 if (childObject.activeSelf)
513 objects.Append(tempObjectSb.ToString());
514 connections.Append(tempConnectionsSb.ToString());
UnityFBXExporter.FBXExporter FE
static long GetRandomFBXId()
static long GetMeshToString(GameObject gameObj, Material[] materials, ref StringBuilder objects, ref StringBuilder connections, GameObject parentObject=null, long parentModelId=0)
Gets all the meshes and outputs to a string (even grabbing the child of each gameObject)