日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

unity .obj文件的导出

發(fā)布時(shí)間:2023/12/20 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 unity .obj文件的导出 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

.obj文件后綴,是一種3D模型文件格式,一種文本文件。支持多邊形模型(三個(gè)點(diǎn)以上的面),紀(jì)錄法線和貼圖坐標(biāo)。并不記錄動(dòng)畫、材質(zhì)特性、貼圖路徑、動(dòng)力學(xué)及粒子等信息。

主要的用途在于將場(chǎng)景的Mesh信息導(dǎo)出給服務(wù)器做碰撞檢測(cè)(服務(wù)器拿到.obj文件后具體如何實(shí)現(xiàn)的就暫時(shí)不是很懂啦),unity也可以識(shí)別出.obj文件,我們將導(dǎo)出的.obj文件放入unity中,效果如下

首先來(lái)看一下一個(gè)簡(jiǎn)單的.obj文件的內(nèi)容

#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

其中幾個(gè)關(guān)鍵字的含義為

#

開(kāi)頭表示注釋
v表示頂點(diǎn)
vn表示法線,可以共用法線
vt表示uv坐標(biāo)
f表示一個(gè)面,比如參數(shù)1/4/1,表示頂點(diǎn)索引/UV索引/法線索引
usemtl材質(zhì)名稱?(Material name)?

通過(guò)這些位置信息就可以構(gòu)建出模型的框架了。

?

至于如何導(dǎo)出.obj文件,可以參考文檔:http://wiki.unity3d.com/index.php/ExportOBJ?,可以根據(jù)自己項(xiàng)目的一些需求進(jìn)行一些小的修改,例如我們的只導(dǎo)出static物體,一個(gè)多gameobject的場(chǎng)景要合并導(dǎo)出與拆分導(dǎo)出等等。

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();}} }

最后,選擇我們需要導(dǎo)出的gameobject,選擇Tool -> Export即可

?

總結(jié)

以上是生活随笔為你收集整理的unity .obj文件的导出的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。