Unity中为导出的OBJ文件生成MTL材质文件的技术咨询
Hey there! Let's get your OBJ exports linked to MTL material files instead of exporting standalone textures. Here's a step-by-step breakdown of modifying your existing code to achieve this:
1. Quick Background
The MTL file defines material properties (like texture references) that your OBJ will point to. Instead of exporting separate texture files, we'll configure the MTL to reference your existing texture assets directly—this keeps your export clean and aligned with standard OBJ/MTL workflows.
2. Updated ObjExporter Class
We'll add a method to generate MTL content, update the OBJ to reference the MTL, and adjust the export logic to save both files together. Here's the full modified code:
using System.IO; using System.Text; using UnityEngine; public class ObjExporter { // Generate OBJ content with MTL reference public static string MeshToString(MeshFilter mf, string mtlFileName) { Mesh m = mf.mesh; Material[] mats = mf.GetComponent<Renderer>().sharedMaterials; StringBuilder sb = new StringBuilder(); // Link OBJ to the corresponding MTL file sb.Append(string.Format("mtllib {0}\n", Path.GetFileName(mtlFileName))); sb.Append("g ").Append(mf.name).Append("\n"); // Write vertex data foreach (Vector3 v in m.vertices) { sb.Append(string.Format("v {0} {1} {2}\n", v.x, v.y, v.z)); } sb.Append("\n"); // Write normal data foreach (Vector3 v in m.normals) { sb.Append(string.Format("vn {0} {1} {2}\n", v.x, v.y, v.z)); } sb.Append("\n"); // Write UV data (fixed to Vector2 since Unity UVs are 2D) foreach (Vector2 v in m.uv) { sb.Append(string.Format("vt {0} {1}\n", v.x, v.y)); } // Write submesh and material references for (int material = 0; material < m.subMeshCount; material++) { sb.Append("\n"); sb.Append("usemtl ").Append(mats[material].name).Append("\n"); int[] triangles = m.GetTriangles(material); for (int i = 0; i < triangles.Length; i += 3) { sb.Append(string.Format("f {0}/{0}/{0} {1}/{1}/{1} {2}/{2}/{2}\n", triangles[i] + 1, triangles[i + 1] + 1, triangles[i + 2] + 1)); } } return sb.ToString(); } // Generate MTL content for each material public static string MaterialToString(Material[] mats, string textureBasePath) { StringBuilder sb = new StringBuilder(); foreach (Material mat in mats) { sb.Append(string.Format("\nnewmtl {0}\n", mat.name)); // Default material properties (adjust these to match your in-game materials if needed) sb.Append("Ka 1.000 1.000 1.000\n"); // Ambient color sb.Append("Kd 1.000 1.000 1.000\n"); // Diffuse color sb.Append("Ks 0.000 0.000 0.000\n"); // Specular color sb.Append("Ns 0.000\n"); // Specular exponent sb.Append("d 1.000\n"); // Transparency (1 = opaque) // Link the material's main texture Texture mainTex = mat.mainTexture; if (mainTex != null) { // Use the texture's filename (ensure textures are in the same folder as OBJ/MTL, or adjust the path here) string textureFileName = mainTex.name + Path.GetExtension(mainTex.name); sb.Append(string.Format("map_Kd {0}\n", textureFileName)); } } return sb.ToString(); } // Export both OBJ and MTL files public static void MeshToFile(MeshFilter mf, string objFilename) { // MTL file will be saved in the same directory as the OBJ string mtlFilename = Path.ChangeExtension(objFilename, ".mtl"); string textureBasePath = Path.GetDirectoryName(objFilename); // Write OBJ file using (StreamWriter sw = new StreamWriter(objFilename)) { sw.Write(MeshToString(mf, mtlFilename)); } // Write MTL file Material[] mats = mf.GetComponent<Renderer>().sharedMaterials; using (StreamWriter sw = new StreamWriter(mtlFilename)) { sw.Write(MaterialToString(mats, textureBasePath)); } Debug.Log($"Export complete! OBJ: {objFilename}, MTL: {mtlFilename}"); } }
3. Key Changes Explained
- OBJ-MTL Link: Added
mtllib {0}at the top of the OBJ to connect it to the generated MTL file. - MTL Texture References: The
MaterialToStringmethod creates material entries withmap_Kd, which points directly to your existing texture files. - UV Fix: Updated UV handling to use
Vector2(Unity meshes store UVs as 2D values, your original code had a minor mismatch here). - Path Alignment: The MTL is saved in the same directory as the OBJ, and texture references use filenames—just make sure your texture files are placed in the same folder as the exported OBJ/MTL, or adjust the path logic to match your project structure.
4. How to Use
Call the updated MeshToFile method like you did before—now it will generate both files automatically:
ObjExporter.MeshToFile(GetComponent<MeshFilter>(), Application.dataPath + "/MyExportedModel.obj");
内容的提问来源于stack exchange,提问作者skgames




