Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Export obj while Runtime?

Discussion in 'Scripting' started by pcace, Jun 17, 2014.

  1. pcace

    pcace

    Joined:
    May 6, 2014
    Posts:
    20
    Hi,

    i need to export my gamegeometry (everything) while the game is running as an obj. Because i am really bad in Programming ( im just beginning) i tried to google my Problem and found that script (below) it does exactly what i want, but it does this in the editor. How on earth can i run this in realtime for example when pressing a button?

    i think the Problem is, that in this script i have things like:
    Transform[] selection = Selection.GetTransforms(SelectionMode.Editable | SelectionMode.ExcludePrefab);

    while running the "game" there is nothing like selection right?


    Any help for someone like me would be nice!!!!!


    Code (csharp):
    1.  
    2. usingUnityEngine;
    3. usingUnityEditor;
    4. usingSystem.Collections;
    5. usingSystem.Collections.Generic;
    6. usingSystem.IO;
    7. usingSystem.Text;
    8. usingSystem;
    9.  
    10. structObjMaterial
    11. {
    12. publicstringname;
    13. publicstringtextureName;
    14. }
    15.  
    16. publicclassEditorObjExporter : ScriptableObject
    17. {
    18. privatestaticintvertexOffset = 0;
    19. privatestaticintnormalOffset = 0;
    20. privatestaticintuvOffset = 0;
    21.  
    22.  
    23. //AUSGABEORDNER
    24. privatestaticstringtargetFolder = "ExportedObj";
    25.  
    26.  
    27. privatestaticstringMeshToString(MeshFiltermf, Dictionary<string, ObjMaterial> materialList)
    28.  {
    29. Meshm = mf.sharedMesh;
    30. Material[] mats = mf.renderer.sharedMaterials;
    31.  
    32. StringBuildersb = newStringBuilder();
    33.  
    34. sb.Append("g ").Append(mf.name).Append("\n");
    35. foreach(Vector3lvinm.vertices)
    36.  {
    37. Vector3wv = mf.transform.TransformPoint(lv);
    38.  
    39. //Thisissortofugly - invertingx-componentsincewe'rein
    40. //adifferentcoordinatesystemthan "everyone" is "usedto".
    41. sb.Append(string.Format("v {0} {1} {2}\n",-wv.x,wv.y,wv.z));
    42.  }
    43. sb.Append("\n");
    44.  
    45. foreach(Vector3lvinm.normals)
    46.  {
    47. Vector3wv = mf.transform.TransformDirection(lv);
    48.  
    49. sb.Append(string.Format("vn {0} {1} {2}\n",-wv.x,wv.y,wv.z));
    50.  }
    51. sb.Append("\n");
    52.  
    53. foreach(Vector3vinm.uv)
    54.  {
    55. sb.Append(string.Format("vt {0} {1}\n",v.x,v.y));
    56.  }
    57.  
    58. for (intmaterial=0; material < m.subMeshCount; material ++) {
    59. sb.Append("\n");
    60. sb.Append("usemtl ").Append(mats[material].name).Append("\n");
    61. sb.Append("usemap ").Append(mats[material].name).Append("\n");
    62.  
    63. //Seeifthismaterialisalreadyinthemateriallist.
    64. try
    65.  {
    66. ObjMaterialobjMaterial = newObjMaterial();
    67.  
    68. objMaterial.name = mats[material].name;
    69.  
    70. if (mats[material].mainTexture)
    71. objMaterial.textureName = EditorUtility.GetAssetPath(mats[material].mainTexture);
    72. else
    73. objMaterial.textureName = null;
    74.  
    75. materialList.Add(objMaterial.name, objMaterial);
    76.  }
    77. catch (ArgumentException)
    78.  {
    79. //Alreadyinthedictionary
    80.  }
    81.  
    82.  
    83. int[] triangles = m.GetTriangles(material);
    84. for (inti=0;i<triangles.Length;i+=3)
    85.  {
    86. //Becauseweinvertedthex-component, wealsoneededtoalterthetrianglewinding.
    87. sb.Append(string.Format("f {1}/{1}/{1} {0}/{0}/{0} {2}/{2}/{2}\n",
    88. triangles[i]+1 + vertexOffset, triangles[i+1]+1 + normalOffset, triangles[i+2]+1 + uvOffset));
    89.  }
    90.  }
    91.  
    92. vertexOffset += m.vertices.Length;
    93. normalOffset += m.normals.Length;
    94. uvOffset += m.uv.Length;
    95.  
    96. returnsb.ToString();
    97.  }
    98.  
    99. privatestaticvoidClear()
    100.  {
    101. vertexOffset = 0;
    102. normalOffset = 0;
    103. uvOffset = 0;
    104.  }
    105.  
    106. privatestaticDictionary<string, ObjMaterial> PrepareFileWrite()
    107.  {
    108. Clear();
    109.  
    110. returnnewDictionary<string, ObjMaterial>();
    111.  }
    112.  
    113.  
    114.  
    115. privatestaticvoidMeshToFile(MeshFiltermf, stringfolder, stringfilename)
    116.  {
    117. Dictionary<string, ObjMaterial> materialList = PrepareFileWrite();
    118.  
    119. using (StreamWritersw = newStreamWriter(folder +"/" + filename + ".obj"))
    120.  {
    121. sw.Write("mtllib ./" + filename + ".mtl\n");
    122.  
    123. sw.Write(MeshToString(mf, materialList));
    124.  }
    125.  
    126.  }
    127.  
    128. privatestaticvoidMeshesToFile(MeshFilter[] mf, stringfolder, stringfilename)
    129.  {
    130. Dictionary<string, ObjMaterial> materialList = PrepareFileWrite();
    131.  
    132. using (StreamWritersw = newStreamWriter(folder +"/" + filename + ".obj"))
    133.  {
    134. sw.Write("mtllib ./" + filename + ".mtl\n");
    135.  
    136. for (inti = 0; i < mf.Length; i++)
    137.  {
    138. sw.Write(MeshToString(mf[i], materialList));
    139.  }
    140.  }
    141.  
    142.  }
    143.  
    144. privatestaticboolCreateTargetFolder()
    145.  {
    146. try
    147.  {
    148. System.IO.Directory.CreateDirectory(targetFolder);
    149.  }
    150. catch
    151.  {
    152. EditorUtility.DisplayDialog("Error!", "Failed to create target folder!", "");
    153. returnfalse;
    154.  }
    155.  
    156. returntrue;
    157.  }
    158.  
    159.  
    160. //MENUITEM + EXPORT
    161.  
    162.  [MenuItem ("OBJ/Komplette Selektion in OBJ")]
    163. staticvoidExportWholeSelectionToSingle()
    164.  {
    165. if (!CreateTargetFolder())
    166. return;
    167.  
    168.  
    169. Transform[] selection = Selection.GetTransforms(SelectionMode.Editable | SelectionMode.ExcludePrefab);
    170.  
    171. if (selection.Length == 0)
    172.  {
    173. EditorUtility.DisplayDialog("No source object selected!", "Please select one or more target objects", "");
    174. return;
    175.  }
    176.  
    177. intexportedObjects = 0;
    178.  
    179. ArrayListmfList = newArrayList();
    180.  
    181. for (inti = 0; i < selection.Length; i++)
    182.  {
    183. Component[] meshfilter = selection[i].GetComponentsInChildren(typeof(MeshFilter));
    184.  
    185. for (intm = 0; m < meshfilter.Length; m++)
    186.  {
    187. exportedObjects++;
    188. mfList.Add(meshfilter[m]);
    189.  }
    190.  }
    191.  
    192. if (exportedObjects > 0)
    193.  {
    194. MeshFilter[] mf = newMeshFilter[mfList.Count];
    195.  
    196. for (inti = 0; i < mfList.Count; i++)
    197.  {
    198. mf[i] = (MeshFilter)mfList[i];
    199.  }
    200.  
    201. stringfilename = EditorApplication.currentScene + "_" + exportedObjects;
    202.  
    203. intstripIndex = filename.LastIndexOf('/');//FIXME: ShouldbePath.PathSeparator
    204.  
    205. if (stripIndex >= 0)
    206. filename = filename.Substring(stripIndex + 1).Trim();
    207.  
    208. MeshesToFile(mf, targetFolder, filename);
    209.  
    210.  
    211. EditorUtility.DisplayDialog("Objects exported", "Exported " + exportedObjects + " objects to " + filename, "");
    212.  }
    213. else
    214. EditorUtility.DisplayDialog("Objects not exported", "Make sure at least some of your selected objects have mesh filters!", "");
    215.  }
    216.  
    217. }    
    218.  
     
  2. bigmisterb

    bigmisterb

    Joined:
    Nov 6, 2010
    Posts:
    4,221
    Unfortunately, if you want anyone to help you with this, your code is going to have to be tabbed and spaced correctly.

    I don't think anyone is going to touch this, when they have to pretty much rebuild everything.

    Code (csharp):
    1.  
    2.  
    3. usingUnityEngine;
    4. usingUnityEditor;
    5. usingSystem.Collections;
    6. usingSystem.Collections.Generic;
    7. usingSystem.IO;
    8. usingSystem.Text;
    9. usingSystem;
    10.  
    11. // should be....
    12.  
    13.  
    14. using UnityEngine;
    15. using UnityEditor;
    16. using System.Collections;
    17. using System.Collections.Generic;
    18. using System.IO;
    19. using System.Text;
    20. using System;
    21.  
    All of your code is littered with this.
     
  3. pcace

    pcace

    Joined:
    May 6, 2014
    Posts:
    20
    omg, i am sorry!! this happened while copying! Here is another one:

    Code (csharp):
    1.  
    2. /*
    3.  
    4.   */
    5.  
    6. using UnityEngine;
    7. using UnityEditor;
    8. using System.Collections;
    9. using System.Collections.Generic;
    10. using System.IO;
    11. using System.Text;
    12. using System;
    13.  
    14. struct ObjMaterial
    15. {
    16.     public string name;
    17.     public string textureName;
    18. }
    19.  
    20. public class EditorObjExporter : ScriptableObject
    21. {
    22.     private static int vertexOffset = 0;
    23.     private static int normalOffset = 0;
    24.     private static int uvOffset = 0;
    25.  
    26.  
    27.     //AUSGABE ORDNER
    28.     private static string targetFolder = "ExportedObj";
    29.  
    30.  
    31.     private static string MeshToString(MeshFilter mf, Dictionary<string, ObjMaterial> materialList)
    32.     {
    33.         Mesh m = mf.sharedMesh;
    34.         Material[] mats = mf.renderer.sharedMaterials;
    35.      
    36.         StringBuilder sb = new StringBuilder();
    37.      
    38.         sb.Append("g ").Append(mf.name).Append("\n");
    39.         foreach(Vector3 lv in m.vertices)
    40.         {
    41.             Vector3 wv = mf.transform.TransformPoint(lv);
    42.      
    43.             //This is sort of ugly - inverting x-component since we're in
    44.             //a different coordinate system than "everyone" is "used to".
    45.             sb.Append(string.Format("v {0} {1} {2}\n",-wv.x,wv.y,wv.z));
    46.         }
    47.         sb.Append("\n");
    48.      
    49.         foreach(Vector3 lv in m.normals)
    50.         {
    51.             Vector3 wv = mf.transform.TransformDirection(lv);
    52.      
    53.             sb.Append(string.Format("vn {0} {1} {2}\n",-wv.x,wv.y,wv.z));
    54.         }
    55.         sb.Append("\n");
    56.      
    57.         foreach(Vector3 v in m.uv)
    58.         {
    59.             sb.Append(string.Format("vt {0} {1}\n",v.x,v.y));
    60.         }
    61.      
    62.         for (int material=0; material < m.subMeshCount; material ++) {
    63.             sb.Append("\n");
    64.             sb.Append("usemtl ").Append(mats[material].name).Append("\n");
    65.             sb.Append("usemap ").Append(mats[material].name).Append("\n");
    66.              
    67.             //See if this material is already in the materiallist.
    68.             try
    69.             {
    70.                 ObjMaterial objMaterial = new ObjMaterial();
    71.              
    72.                 objMaterial.name = mats[material].name;
    73.              
    74.                 if (mats[material].mainTexture)
    75.                     objMaterial.textureName = EditorUtility.GetAssetPath(mats[material].mainTexture);
    76.                 else
    77.                     objMaterial.textureName = null;
    78.              
    79.                 materialList.Add(objMaterial.name, objMaterial);
    80.             }
    81.             catch (ArgumentException)
    82.             {
    83.                 //Already in the dictionary
    84.             }
    85.  
    86.              
    87.             int[] triangles = m.GetTriangles(material);
    88.             for (int i=0;i<triangles.Length;i+=3)
    89.             {
    90.                 //Because we inverted the x-component, we also needed to alter the triangle winding.
    91.                 sb.Append(string.Format("f {1}/{1}/{1} {0}/{0}/{0} {2}/{2}/{2}\n",
    92.                     triangles[i]+1 + vertexOffset, triangles[i+1]+1 + normalOffset, triangles[i+2]+1 + uvOffset));
    93.             }
    94.         }
    95.      
    96.         vertexOffset += m.vertices.Length;
    97.         normalOffset += m.normals.Length;
    98.         uvOffset += m.uv.Length;
    99.      
    100.         return sb.ToString();
    101.     }
    102.  
    103.     private static void Clear()
    104.     {
    105.         vertexOffset = 0;
    106.         normalOffset = 0;
    107.         uvOffset = 0;
    108.     }
    109.  
    110.     private static Dictionary<string, ObjMaterial> PrepareFileWrite()
    111.     {
    112.         Clear();
    113.      
    114.         return new Dictionary<string, ObjMaterial>();
    115.     }
    116.  
    117.  
    118.     private static void MeshToFile(MeshFilter mf, string folder, string filename)
    119.     {
    120.         Dictionary<string, ObjMaterial> materialList = PrepareFileWrite();
    121.  
    122.         using (StreamWriter sw = new StreamWriter(folder +"/" + filename + ".obj"))
    123.         {
    124.             sw.Write("mtllib ./" + filename + ".mtl\n");
    125.      
    126.             sw.Write(MeshToString(mf, materialList));
    127.         }
    128.      
    129.     }
    130.  
    131.     private static void MeshesToFile(MeshFilter[] mf, string folder, string filename)
    132.     {
    133.         Dictionary<string, ObjMaterial> materialList = PrepareFileWrite();
    134.  
    135.         using (StreamWriter sw = new StreamWriter(folder +"/" + filename + ".obj"))
    136.         {
    137.             sw.Write("mtllib ./" + filename + ".mtl\n");
    138.      
    139.             for (int i = 0; i < mf.Length; i++)
    140.             {
    141.                 sw.Write(MeshToString(mf[i], materialList));
    142.             }
    143.         }
    144.      
    145.     }
    146.  
    147.     private static bool CreateTargetFolder()
    148.     {
    149.         try
    150.         {
    151.             System.IO.Directory.CreateDirectory(targetFolder);
    152.         }
    153.         catch
    154.         {
    155.             EditorUtility.DisplayDialog("Error!", "Failed to create target folder!", "");
    156.             return false;
    157.         }
    158.      
    159.         return true;
    160.     }
    161.  
    162.  
    163.     //MENUITEM + EXPORT
    164.  
    165.     [MenuItem ("OBJ/Komplette Selektion in OBJ")]
    166.     static void ExportWholeSelectionToSingle()
    167.     {
    168.         if (!CreateTargetFolder())
    169.             return;
    170.          
    171.          
    172.         Transform[] selection = Selection.GetTransforms(SelectionMode.Editable | SelectionMode.ExcludePrefab);
    173.      
    174.         if (selection.Length == 0)
    175.         {
    176.             EditorUtility.DisplayDialog("No source object selected!", "Please select one or more target objects", "");
    177.             return;
    178.         }
    179.      
    180.         int exportedObjects = 0;
    181.      
    182.         ArrayList mfList = new ArrayList();
    183.      
    184.         for (int i = 0; i < selection.Length; i++)
    185.         {
    186.             Component[] meshfilter = selection[i].GetComponentsInChildren(typeof(MeshFilter));
    187.          
    188.             for (int m = 0; m < meshfilter.Length; m++)
    189.             {
    190.                 exportedObjects++;
    191.                 mfList.Add(meshfilter[m]);
    192.             }
    193.         }
    194.      
    195.         if (exportedObjects > 0)
    196.         {
    197.             MeshFilter[] mf = new MeshFilter[mfList.Count];
    198.      
    199.             for (int i = 0; i < mfList.Count; i++)
    200.             {
    201.                 mf[i] = (MeshFilter)mfList[i];
    202.             }
    203.          
    204.             string filename = EditorApplication.currentScene + "_" + exportedObjects;
    205.      
    206.             int stripIndex = filename.LastIndexOf('/');//FIXME: Should be Path.PathSeparator
    207.          
    208.             if (stripIndex >= 0)
    209.                 filename = filename.Substring(stripIndex + 1).Trim();
    210.      
    211.             MeshesToFile(mf, targetFolder, filename);
    212.      
    213.      
    214.             EditorUtility.DisplayDialog("Objects exported", "Exported " + exportedObjects + " objects to " + filename, "");
    215.         }
    216.         else
    217.             EditorUtility.DisplayDialog("Objects not exported", "Make sure at least some of your selected objects have mesh filters!", "");
    218.     }
    219.  
    220.  
    221. }
    222.  
    223.  
    Sorry again!!

    Maybe one more thing:

    i tried something like this too:
    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4. using System.IO;
    5. using System.Text;
    6.  
    7. public class ObjExporter {
    8.    
    9.     public static string MeshToString(MeshFilter mf) {
    10.         Mesh m = mf.sharedMesh;
    11.         Material[] mats = mf.renderer.sharedMaterials;
    12.        
    13.         StringBuilder sb = new StringBuilder();
    14.        
    15.         sb.Append("g ").Append(mf.name).Append("\n");
    16.    
    17.  
    18.         foreach(Vector3 v in m.vertices) {
    19.             sb.Append(string.Format("v {0} {1} {2}\n",v.x,v.y,v.z));
    20.         }
    21.         sb.Append("\n");
    22.  
    23.    
    24.         foreach(Vector3 v in m.normals) {
    25.             sb.Append(string.Format("vn {0} {1} {2}\n",v.x,v.y,v.z));
    26.         }
    27.         sb.Append("\n");
    28.  
    29.  
    30.         foreach(Vector3 v in m.uv) {
    31.             sb.Append(string.Format("vt {0} {1}\n",v.x,v.y));
    32.         }
    33.         for (int material=0; material < m.subMeshCount; material ++) {
    34.             sb.Append("\n");
    35.  
    36.  
    37.    
    38.     //        sb.Append("usemtl ").Append(mats[material].name).Append("\n");
    39.     //        sb.Append("usemap ").Append(mats[material].name).Append("\n");
    40.    
    41.             int[] triangles = m.GetTriangles(material);
    42.             for (int i=0;i<triangles.Length;i+=3) {
    43.                 sb.Append(string.Format("f {0}/{0}/{0} {1}/{1}/{1} {2}/{2}/{2}\n",
    44.                                        triangles[i]+1, triangles[i+1]+1, triangles[i+2]+1));
    45.             }
    46.         }
    47.         return sb.ToString();
    48.     }
    49.    
    50.     public static void MeshToFile(MeshFilter mf, string filename) {
    51.         using (StreamWriter sw = new StreamWriter(filename))
    52.         {
    53.             sw.Write(MeshToString(mf));
    54.         }
    55.     }
    56. }
    57.  
    which exports one single obj file from one single object while runtime. But the Problem is, that i only exports the Object without the transformation (scaling) i do in the game! So it exports the geometry in scale 1,1,1. What i need is a way to export all the game objects as an obj with the actual scaling and position.

    Thank you guys so much for help!!

    Thanks!

    Pcace
     
  4. bigmisterb

    bigmisterb

    Joined:
    Nov 6, 2010
    Posts:
    4,221
    a good piece of reading....

    http://en.wikipedia.org/wiki/Wavefront_.obj_file

     
  5. pcace

    pcace

    Joined:
    May 6, 2014
    Posts:
    20
    Hi,

    i already read that, but my real Problem is, that i do not know how to implement this in unity!
    So now i tried to "convert" the script from my first post wich ran from the editor into a script wich runs at runtime.
    The Problem right now is, that i do not know what to do with that line:

    Code (csharp):
    1.  
    2.         Transform[] selection = Selection.GetTransforms(SelectionMode.Editable | SelectionMode.ExcludePrefab);
    3.  
    so with my really really small programming knowledge, i do not know how to tell unity that it should not ask for a selection (since i am not in the editor anymore) but instead using all my meshobjects in the scene!

    Any help with this would be amazin!

    Thanks a lot,

    pcace

    PS.: Here is how far i got with the script:
    Code (csharp):
    1.  
    2.  
    3. using UnityEngine;
    4. using UnityEditor;
    5. using System.Collections;
    6. using System.Collections.Generic;
    7. using System.IO;
    8. using System.Text;
    9. using System;
    10.  
    11.  
    12.  
    13.  
    14. public class objexporter2 : MonoBehaviour {
    15.  
    16.  
    17.    
    18.     struct ObjMaterial
    19.     {
    20.         public string name;
    21.         public string textureName;
    22.     }
    23.    
    24.     public  int vertexOffset = 0;
    25.     public  int normalOffset = 0;
    26.     public  int uvOffset = 0;
    27.     public  string targetFolder = "ExportedObj";
    28.  
    29.     string MeshToString(MeshFilter mf, Dictionary<string, ObjMaterial> materialList)
    30.     {
    31.         Mesh m = mf.sharedMesh;
    32.         Material[] mats = mf.renderer.sharedMaterials;
    33.        
    34.         StringBuilder sb = new StringBuilder();
    35.        
    36.         sb.Append("g ").Append(mf.name).Append("\n");
    37.         foreach(Vector3 lv in m.vertices)
    38.         {
    39.             Vector3 wv = mf.transform.TransformPoint(lv);
    40.            
    41.             //This is sort of ugly - inverting x-component since we're in
    42.             //a different coordinate system than "everyone" is "used to".
    43.             sb.Append(string.Format("v {0} {1} {2}\n",-wv.x,wv.y,wv.z));
    44.         }
    45.         sb.Append("\n");
    46.        
    47.         foreach(Vector3 lv in m.normals)
    48.         {
    49.             Vector3 wv = mf.transform.TransformDirection(lv);
    50.            
    51.             sb.Append(string.Format("vn {0} {1} {2}\n",-wv.x,wv.y,wv.z));
    52.         }
    53.         sb.Append("\n");
    54.        
    55.         foreach(Vector3 v in m.uv)
    56.         {
    57.             sb.Append(string.Format("vt {0} {1}\n",v.x,v.y));
    58.         }
    59.        
    60.         for (int material=0; material < m.subMeshCount; material ++) {
    61.             sb.Append("\n");
    62.             sb.Append("usemtl ").Append(mats[material].name).Append("\n");
    63.             sb.Append("usemap ").Append(mats[material].name).Append("\n");
    64.            
    65.             //See if this material is already in the materiallist.
    66.             try
    67.             {
    68.                 ObjMaterial objMaterial = new ObjMaterial();
    69.                
    70.                 objMaterial.name = mats[material].name;
    71.                
    72.                 if (mats[material].mainTexture)
    73.                     objMaterial.textureName = EditorUtility.GetAssetPath(mats[material].mainTexture);
    74.                 else
    75.                     objMaterial.textureName = null;
    76.                
    77.                 materialList.Add(objMaterial.name, objMaterial);
    78.             }
    79.             catch (ArgumentException)
    80.             {
    81.                 //Already in the dictionary
    82.             }
    83.            
    84.            
    85.             int[] triangles = m.GetTriangles(material);
    86.             for (int i=0;i<triangles.Length;i+=3)
    87.             {
    88.                 //Because we inverted the x-component, we also needed to alter the triangle winding.
    89.                 sb.Append(string.Format("f {1}/{1}/{1} {0}/{0}/{0} {2}/{2}/{2}\n",
    90.                                        triangles[i]+1 + vertexOffset, triangles[i+1]+1 + normalOffset, triangles[i+2]+1 + uvOffset));
    91.             }
    92.         }
    93.        
    94.         vertexOffset += m.vertices.Length;
    95.         normalOffset += m.normals.Length;
    96.         uvOffset += m.uv.Length;
    97.        
    98.         return sb.ToString();
    99.     }
    100.     void Clear()
    101.     {
    102.         vertexOffset = 0;
    103.         normalOffset = 0;
    104.         uvOffset = 0;
    105.     }
    106.  
    107.     Dictionary<string, ObjMaterial> PrepareFileWrite()
    108.     {
    109.         Clear();
    110.        
    111.         return new Dictionary<string, ObjMaterial>();
    112.     }
    113.  
    114.     void MeshToFile(MeshFilter mf, string folder, string filename)
    115.     {
    116.         Dictionary<string, ObjMaterial> materialList = PrepareFileWrite();
    117.        
    118.         using (StreamWriter sw = new StreamWriter(folder +"/" + filename + ".obj"))
    119.         {
    120.             sw.Write("mtllib ./" + filename + ".mtl\n");
    121.            
    122.             sw.Write(MeshToString(mf, materialList));
    123.         }
    124.        
    125.     }
    126.    
    127.     void MeshesToFile(MeshFilter[] mf, string folder, string filename)
    128.     {
    129.         Dictionary<string, ObjMaterial> materialList = PrepareFileWrite();
    130.        
    131.         using (StreamWriter sw = new StreamWriter(folder +"/" + filename + ".obj"))
    132.         {
    133.             sw.Write("mtllib ./" + filename + ".mtl\n");
    134.            
    135.             for (int i = 0; i < mf.Length; i++)
    136.             {
    137.                 sw.Write(MeshToString(mf[i], materialList));
    138.             }
    139.         }
    140.        
    141.     }
    142.  
    143.     bool CreateTargetFolder()
    144.     {
    145.         try
    146.         {
    147.             System.IO.Directory.CreateDirectory(targetFolder);
    148.         }
    149.         catch
    150.         {
    151.             EditorUtility.DisplayDialog("Error!", "Failed to create target folder!", "");
    152.             return false;
    153.         }
    154.        
    155.         return true;
    156.     }
    157.  
    158.  
    159.  
    160.     // Use this for initialization
    161.     void Start () {
    162.    
    163.     }
    164.    
    165.     // Update is called once per frame
    166.     void Update () {
    167.  
    168.  
    169.         if (Input.GetButtonDown ("Fire3") )
    170.         {
    171.  
    172.         if (!CreateTargetFolder())
    173.             return;
    174.        
    175.        
    176.         Transform[] selection = Selection.GetTransforms(SelectionMode.Editable | SelectionMode.ExcludePrefab);
    177.        
    178.         if (selection.Length == 0)
    179.         {
    180.             EditorUtility.DisplayDialog("No source object selected!", "Please select one or more target objects", "");
    181.             return;
    182.         }
    183.        
    184.         int exportedObjects = 0;
    185.        
    186.         ArrayList mfList = new ArrayList();
    187.        
    188.         for (int i = 0; i < selection.Length; i++)
    189.         {
    190.             Component[] meshfilter = selection[i].GetComponentsInChildren(typeof(MeshFilter));
    191.            
    192.             for (int m = 0; m < meshfilter.Length; m++)
    193.             {
    194.                 exportedObjects++;
    195.                 mfList.Add(meshfilter[m]);
    196.             }
    197.         }
    198.        
    199.         if (exportedObjects > 0)
    200.         {
    201.             MeshFilter[] mf = new MeshFilter[mfList.Count];
    202.            
    203.             for (int i = 0; i < mfList.Count; i++)
    204.             {
    205.                 mf[i] = (MeshFilter)mfList[i];
    206.             }
    207.            
    208.             string filename = EditorApplication.currentScene + "_" + exportedObjects;
    209.            
    210.             int stripIndex = filename.LastIndexOf('/');//FIXME: Should be Path.PathSeparator
    211.            
    212.             if (stripIndex >= 0)
    213.                 filename = filename.Substring(stripIndex + 1).Trim();
    214.            
    215.             MeshesToFile(mf, targetFolder, filename);
    216.            
    217.            
    218.             EditorUtility.DisplayDialog("Objects exported", "Exported " + exportedObjects + " objects to " + filename, "");
    219.         }
    220.         else
    221.             EditorUtility.DisplayDialog("Objects not exported", "Make sure at least some of your selected objects have mesh filters!", "");
    222.     }
    223.     }
    224.     }
    225.  
    226.  
     
  6. bigmisterb

    bigmisterb

    Joined:
    Nov 6, 2010
    Posts:
    4,221
    Well, to be honest, all you have to do is replicate the whole Update method.... Lets just call it SaveModels


    instead of the selection, you will need to feed it a group of transforms with at least one meshfilter.

    Code (csharp):
    1.  
    2.     public void SaveModels(Transform[] models){
    3.         if(models.Length == 0) return;
    4.        
    5.         int exportedObjects = 0;
    6.        
    7.         ArrayList mfList = new ArrayList();
    8.        
    9.         for (int i = 0; i < models.Length; i++)
    10.         {
    11.             Component[] meshfilter = models[i].GetComponentsInChildren(typeof(MeshFilter));
    12.            
    13.             for (int m = 0; m < meshfilter.Length; m++)
    14.             {
    15.                 exportedObjects++;
    16.                 mfList.Add(meshfilter[m]);
    17.             }
    18.         }
    19.        
    20.         if (exportedObjects > 0){
    21.             MeshFilter[] mf = new MeshFilter[mfList.Count];
    22.            
    23.             for (int i = 0; i < mfList.Count; i++)
    24.             {
    25.                 mf[i] = (MeshFilter)mfList[i];
    26.             }
    27.            
    28.             string filename = "Exported_Objects.obj";
    29.            
    30.             MeshesToFile(mf, Application.dataPath, filename);
    31.            
    32.            
    33.             Debug.Log("Objects exported", "Exported " + exportedObjects + " objects to " + filename, "");
    34.         }
    35.         else
    36.            Debug.Log("Objects not exported", "Make sure at least some of your selected objects have mesh filters!", "");
    37.     }
    38.  
     
    Last edited: Jun 18, 2014
  7. pcace

    pcace

    Joined:
    May 6, 2014
    Posts:
    20
    Hi, thank you so much for your help!
    just not to do something wrong:
    this line
    for(int i =0; i < selection.Length; i++)
    should be
    for(int i =0; i < models.Length; i++)
    right?
    and this line:
    Component[] meshfilter = selection.GetComponentsInChildren(typeof(MeshFilter));
    should probably
    Component[] meshfilter = models .GetComponentsInChildren (typeof(MeshFilter));

    so what i did now is:
    Code (csharp):
    1.  
    2.    public GameObject[] savegeo;
    3.  
    Code (csharp):
    1.  
    2. world = GameObject.Find ("Strasse");
    3. savegeo[1] = world;
    4.  
    5. if  (Input.GetButtonDown ("Fire3")) {
    6.  
    7. Debug.Log("Button DOWN");
    8. SaveModels(world);
    9. }
    10.  
    11.  
    but i get this error:

    Assets/C Scripts/objexporter2.cs(208,33): error CS1502: The best overloaded method match for `objexporter2.SaveModels(UnityEngine.Transform[])' has some invalid arguments

    what means "some invalid arguments"?! this really does not sound precise ;)?!

    Thank you again for your help!!

    Pcace
     
  8. Sharp-Development

    Sharp-Development

    Joined:
    Nov 14, 2013
    Posts:
    353
    It sounds precise as long as you know what an Argument is.

    You are passing a variable to SaveModels which is not of type Transform[]. In your case the world variable, which I guess is either a Transform or a Gameobject, but neither of both is a Transform[]. (array of Transforms)

    /E: Just saw the line above. You are passing an array of GameObjects but not an array of Transforms which the SaveModel method takes.
    GameObject[] != Transform[] !
     
  9. pcace

    pcace

    Joined:
    May 6, 2014
    Posts:
    20
    Ok,

    i got a step further! what i did now is:

    Code (csharp):
    1.  
    2.     // Use this for initialization
    3.     void Start () {
    4.  
    5.         exportgeo = new Transform[1];
    6.         world = GameObject.Find ("Strasse");
    7.     }
    8.  
    9.     // Update is called once per frame
    10.     void Update () {
    11.         world = GameObject.Find ("Strasse");
    12.         exportgeo[0] = world.transform;
    13.  
    14.         if (Input.GetButtonDown ("Fire3")) {
    15.                  
    16.                 SaveModels(exportgeo);
    17.  
    18.                 }
    19.     }
    20. }
    21.  
    22.  
    The Problem now is, that i have no idea how to automaticly search for gameobjects and put all of them in this array.
    The question here is more like 2 questions: what happens if i do not know how many gameobjects there are in the scene (for example because i cloned some) how does the array knows how long it should be? or should i somehow firs count the gameobjects, then create the array and then put everything into the array? and second how to find all gameobjects?


    Thanks a lot! (really - thank you soo much)

    pcace
     
  10. Sharp-Development

    Sharp-Development

    Joined:
    Nov 14, 2013
    Posts:
    353
    Well, answers are simple. Tho, you should really consider to first read/watch a bunch of C# aswell as Unity tutorials since you wont go very far with this. Considering you will never be able to publish a real game as long as your c#-fu stays in that condition.

    As of finding every gameobject in the scene:
    Code (csharp):
    1. GameObject[] objects = FindObjectsOfType<GameObject>();
    This will return an array of gameobjects.

    As of your first question. That one is hard to answer, well, acctually it not. Theres multiple ways in doing so, keeping track of the stuff you create, for example.
    Knowing how long the array should be? Well, in case of FindObjectsOfType, you dont since it already returns the array.


    Your above posted SaveModel method does essentially shrink down to this:
    Code (csharp):
    1.  
    2. public void SaveModels( string fileName ) {
    3.     MeshFilter[] filters = FindObjectsOfType<MeshFilter>();
    4.  
    5.     if( filters.Length == 0 ) return;
    6.  
    7.     MeshesToFile( filters, Application.dataPath, fileName + ".obj" );
    8. }
    9.  
     
    Last edited: Jun 18, 2014
  11. pcace

    pcace

    Joined:
    May 6, 2014
    Posts:
    20
    Hi,

    i really know i need to learn c#. The project here is a part of a project here at my university. our focus is really not to make the best code ever, but more that it just runs ;)
    but still: you are right. i need to learn the basics of c#. Anyway, i am more than thankfull, that you guys here help me that much!

    I tried to use your codeline, but i get an error wich sais "Cannot implicitly convert type `UnityEngine.Object[]' to `UnityEngine.GameObject[]'."

    so i tried to do that:
    GameObject[] allObjects = GameObject.FindGameObjectsWithTag ("Untagged");
    but that array has a length of 0. So something is still wrong.

    in the end i want to do something like that:

    Code (csharp):
    1.  
    2. void Update () {
    3.  
    4.     wholescene = GameObject.FindGameObjectsWithTag("Untagged");
    5.     Debug.Log ("wholescene.length: " + wholescene.Length);
    6.     for (var i=0; i < wholescene.Length - 1; i++)
    7.     {
    8.         exportgeo[i] = wholescene[i].transform;
    9.  
    10.     }
    11.     if (Input.GetButtonDown ("Fire3")) {
    12.                
    13.             SaveModels(exportgeo);
    14.  
    15.             }
    16. }
    17.  
    but wholescene.length is simply 0. Why? Do i have to initiate the array somehow? i mean tell it how long it is? (i tried toing something like this:
    Code (csharp):
    1.  
    2.      wholescene = new GameObject[GameObject.FindGameObjectsWithTag ("Untagged").Length];
    3.  
    but that also does not help...

    Thanks again for Help,

    Pcace
     
  12. pcace

    pcace

    Joined:
    May 6, 2014
    Posts:
    20
    OMG, i did not see your edit:
    This is amazing!!!!
    If i could i would imidiately buy you a beer!!

    Thank you so much!!!!!
     
  13. Sharp-Development

    Sharp-Development

    Joined:
    Nov 14, 2013
    Posts:
    353
    No problem. But I'll quote you on that beer. :p
     
    Zimbres likes this.
  14. pcace

    pcace

    Joined:
    May 6, 2014
    Posts:
    20
    Seriously? are you from europe?
    Maybe i'll come over and buy you a beer in summer ;)
     
  15. alcamedes

    alcamedes

    Joined:
    Mar 26, 2014
    Posts:
    5
    Pcace did you get this to work? is there a complete script somewhere? Just asking before I try my own...
     
  16. bigmisterb

    bigmisterb

    Joined:
    Nov 6, 2010
    Posts:
    4,221
    All he code is in the thread, you just have to read it and sift a bit.