unity .obj文件的导出
生活随笔
收集整理的這篇文章主要介紹了
unity .obj文件的导出
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
.obj文件后綴,是一種3D模型文件格式,一種文本文件。支持多邊形模型(三個點以上的面),紀錄法線和貼圖坐標。并不記錄動畫、材質特性、貼圖路徑、動力學及粒子等信息。
主要的用途在于將場景的Mesh信息導出給服務器做碰撞檢測(服務器拿到.obj文件后具體如何實現的就暫時不是很懂啦),unity也可以識別出.obj文件,我們將導出的.obj文件放入unity中,效果如下
首先來看一下一個簡單的.obj文件的內容
#type mesh #Cube #------- g Cube v -53.00000 -2.00000 -62.00000 v 66.00000 -2.00000 -62.00000 v -53.00000 1.00000 -62.00000 v 66.00000 1.00000 -62.00000 v 66.00000 -2.00000 -62.00000 v 66.00000 -2.00000 49.50000 v 66.00000 1.00000 -62.00000 v 66.00000 1.00000 50.50000 v 66.00000 -2.00000 49.50000 v -53.00000 -2.00000 49.50000 v 66.00000 1.00000 50.50000 v -53.00000 1.00000 50.50000 v -53.00000 -2.00000 49.50000 v -53.00000 -2.00000 -62.00000 v -53.00000 1.00000 50.50000 v -53.00000 1.00000 -62.00000 v -53.00000 1.00000 -62.00000 v 66.00000 1.00000 -62.00000 v -53.00000 1.00000 50.50000 v 66.00000 1.00000 50.50000 v -53.00000 -2.00000 49.50000 v 66.00000 -2.00000 49.50000 v -53.00000 -2.00000 -62.00000 v 66.00000 -2.00000 -62.00000vn 0 0 1 vn 0 0 1 vn 0 0 1 vn 0 0 1 vn -1 0 0 vn -1 0 0 vn -1 0 0 vn -1 0 0 vn 0 0.3162278 -0.9486833 vn 0 0.3162278 -0.9486833 vn 0 0.3162278 -0.9486833 vn 0 0.3162278 -0.9486833 vn 1 0 0 vn 1 0 0 vn 1 0 0 vn 1 0 0 vn 0 -1 0 vn 0 -1 0 vn 0 -1 0 vn 0 -1 0 vn 0 1 0 vn 0 1 0 vn 0 1 0 vn 0 1 0vt 53 -2 vt -66 -2 vt 53 1 vt -66 1 vt 62 -2 vt -49.5 -2 vt 62 1 vt -50.5 1 vt 66 13.75591 vt -53 13.75591 vt 66 16.91819 vt -53 16.91819 vt 49.5 -2 vt -62 -2 vt 50.5 1 vt -62 1 vt -53 62 vt 66 62 vt -53 -50.5 vt 66 -50.5 vt 53 -49.5 vt -66 -49.5 vt 53 62 vt -66 62usemtl ProBuilderDefault usemap ProBuilderDefault f 1/1/1 2/2/2 3/3/3 f 2/2/2 4/4/4 3/3/3 f 5/5/5 6/6/6 7/7/7 f 6/6/6 8/8/8 7/7/7 f 9/9/9 10/10/10 11/11/11 f 10/10/10 12/12/12 11/11/11 f 13/13/13 14/14/14 15/15/15 f 14/14/14 16/16/16 15/15/15 f 17/17/17 18/18/18 19/19/19 f 18/18/18 20/20/20 19/19/19 f 21/21/21 22/22/22 23/23/23 f 22/22/22 24/24/24 23/23/23其中幾個關鍵字的含義為
| # | 開頭表示注釋 |
| v | 表示頂點 |
| vn | 表示法線,可以共用法線 |
| vt | 表示uv坐標 |
| f | 表示一個面,比如參數1/4/1,表示頂點索引/UV索引/法線索引 |
| usemtl | 材質名稱?(Material name)? |
通過這些位置信息就可以構建出模型的框架了。
?
至于如何導出.obj文件,可以參考文檔:http://wiki.unity3d.com/index.php/ExportOBJ?,可以根據自己項目的一些需求進行一些小的修改,例如我們的只導出static物體,一個多gameobject的場景要合并導出與拆分導出等等。
using UnityEngine; using UnityEditor; using System.Collections; using System.IO; using System.Text; using Base.Framework.Tools;public class ObjExporter : ScriptableObject {[MenuItem("Tools/Export/Export OBJ")]static void DoExportWSubmeshes(){Export(true);}[MenuItem("Tools/Export/Export OBJ (No Submeshes)")]static void DoExportWOSubmeshes(){Export(false);}static void Export(bool isSubmeshes){if (Selection.gameObjects == null){Debug.Log("Didn't Export Any Meshes; Nothing was selected!");return;}string fileName = EditorUtility.SaveFilePanel("Export .obj file", "", Selection.gameObjects[0].name, "obj");PrefabExportToObj.DoExport(Selection.gameObjects[0], fileName, isSubmeshes);}[MenuItem("Tools/Export/Split Export OBJ")]static void SplitExport(){if (Selection.gameObjects == null){Debug.Log("Didn't Export Any Meshes; Nothing was selected!");return;}string filePath = EditorUtility.SaveFolderPanel("Export .obj file", "", Selection.gameObjects[0].name);PrefabExportToObj.SplitExport(Selection.gameObjects[0], filePath, true);}[MenuItem("Tools/Export/Export All OBJ")]static void AllExport(){if (Selection.gameObjects == null){Debug.Log("Didn't Export Any Meshes; Nothing was selected!");return;}string filePath = EditorUtility.SaveFolderPanel("Export .obj file", "", Selection.gameObjects[0].name);PrefabExportToObj.SplitExport(Selection.gameObjects[0], filePath, true);PrefabExportToObj.DoExport(Selection.gameObjects[0], filePath + "/" + Selection.gameObjects[0].name + ".obj", true);} } using System; using System.IO; using System.Text; using UnityEngine;namespace Base.Framework.Tools {public class PrefabExportToObj{static StringBuilder filesString;static int fileCount;public static void StartRecordFiles(string msg){filesString = new StringBuilder();filesString.Append("#");filesString.Append(msg);filesString.Append("\n");fileCount = 0;}public static void ExportRecordFiles(string path){if(filesString!=null&& filesString.Length > 0){WriteToFile(filesString.ToString(), path);}filesString.Length = 0;filesString = null;}public static void SplitExport(GameObject target, string path, bool makeSubmeshes){ PrefabExportToObj.StartRecordFiles("GameObject:" + target.name);Split(target, path);PrefabExportToObj.ExportRecordFiles(path + "/dependencies.txt");}static void Split(GameObject go, string path){if (go.isStatic && go.activeSelf && go.activeInHierarchy && go.GetComponent<MeshFilter>() != null){DoExport(go, path + "/" + fileCount + ".obj", true);fileCount++;}for (int i = 0; i < go.transform.childCount; i++){//Split(go.transform.GetChild(i).gameObject, path + "/" + go.transform.GetChild(i).gameObject.name);Split(go.transform.GetChild(i).gameObject, path);}}/// <param name="target"></param>/// <param name="path">x/y/z.obj</param>/// <param name="makeSubmeshes"></param>public static void DoExport(GameObject target, string path, bool makeSubmeshes){if (target == null){Debug.Log("Didn't Export Any Meshes; Nothing was selected!");return;}string meshName = target.name;ObjExporterScript.Start();StringBuilder meshString = new StringBuilder();Transform t = target.transform;meshString.Append($"#type mesh\n");//Vector3 originalPosition = t.position;//t.position = Vector3.zero;if (!makeSubmeshes){meshString.Append("g ").Append(t.name).Append("\n");}meshString.Append(processTransform(t, makeSubmeshes));if (filesString != null){filesString.Append(Path.GetFileName(path));filesString.Append("\n");}WriteToFile(meshString.ToString(), path);//t.position = originalPosition;ObjExporterScript.End();Debug.Log("Exported Mesh: " + path);}static string processTransform(Transform t, bool makeSubmeshes){StringBuilder meshString = new StringBuilder();meshString.Append("#" + t.name+ "\n#-------"+ "\n");if (t.gameObject.isStatic){if (makeSubmeshes){meshString.Append("g ").Append(t.name).Append("\n");}MeshFilter mf = t.GetComponent<MeshFilter>();if (mf){meshString.Append(ObjExporterScript.MeshToString(mf, t));}}for (int i = 0; i < t.childCount; i++){Transform tc = t.GetChild(i);if (tc.gameObject.isStatic && tc.gameObject.activeSelf && tc.gameObject.activeInHierarchy){meshString.Append(processTransform(tc, makeSubmeshes));}}return meshString.ToString();}static void WriteToFile(string s, string filename){string path = Path.GetDirectoryName(filename);if (!Directory.Exists(path)){Directory.CreateDirectory(path);}using (StreamWriter sw = new StreamWriter(filename)){sw.Write(s);}}}public class ObjExporterScript{private static int StartIndex = 0;public static void Start(){StartIndex = 0;}public static void End(){StartIndex = 0;}public static string MeshToString(MeshFilter mf, Transform t){Vector3 s = t.localScale;Vector3 p = t.localPosition;Quaternion r = t.localRotation;int numVertices = 0;Mesh m = mf.sharedMesh;if (!m || mf.GetComponent<Renderer>() == null){return "####Error####";}Material[] mats = mf.GetComponent<Renderer>().sharedMaterials;StringBuilder sb = new StringBuilder();foreach (Vector3 vv in m.vertices){Vector3 v = t.TransformPoint(vv);numVertices++;sb.Append(string.Format("v {0:f5} {1:f5} {2:f5}\n", v.x, v.y, -v.z));}sb.Append("\n");foreach (Vector3 nn in m.normals){Vector3 v = r * nn;sb.Append(string.Format("vn {0} {1} {2}\n", v.x, v.y, v.z));}sb.Append("\n");foreach (Vector3 v in m.uv){sb.Append(string.Format("vt {0} {1}\n", v.x, v.y));}for (int material = 0; material < m.subMeshCount; material++){sb.Append("\n");sb.Append("usemtl ").Append(mats[material].name).Append("\n");sb.Append("usemap ").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 {2}/{2}/{2} {1}/{1}/{1} {0}/{0}/{0}\n",triangles[i] + 1 + StartIndex, triangles[i + 1] + 1 + StartIndex, triangles[i + 2] + 1 + StartIndex));}}StartIndex += numVertices;return sb.ToString();}} }最后,選擇我們需要導出的gameobject,選擇Tool -> Export即可
?
總結
以上是生活随笔為你收集整理的unity .obj文件的导出的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 51单片机 DHT11温湿度传感器LCD
- 下一篇: 绝知此事要躬行|fatal: not i