unity编辑器拓展五——将场景中物体以Obj格式导入max

来源:互联网 发布:星之海洋 知乎 编辑:程序博客网 时间:2024/05/21 20:24

描述:

  1.在unity中建立一个场景,做完后,有很多需求是将一个完整的场景导入到max里面,这样可以准确的去做行走网格 水面 等各种需要与场景配合的模型

下面这段代码就可以实现unity与max互导

代码如下:

using UnityEngine;using UnityEditor;using System.IO;using System.Text;using System.Collections;using System.Collections.Generic;using UnityEditor.SceneManagement;public class SceneExport : EditorWindow{    struct Model    {        public Mesh mesh;        public Material[] materials;        public Transform transform;    }    struct ModelMaterial    {        public string name;        public float cutoff;        public string texture;    }    class MaterialCompare : EqualityComparer<ModelMaterial>    {        public override bool Equals(ModelMaterial mtlx, ModelMaterial mtly)        {            return string.Compare(mtlx.name, mtly.name) == 0;        }        public override int GetHashCode(ModelMaterial mtl)        {            return mtl.name.GetHashCode();        }    }    static SceneExport window;    [MenuItem("Game-X/Scene Exporter", false, 101)]    public static void Open()    {        if (window == null)        {            window =                EditorWindow.GetWindow<SceneExport>(false, "SceneExport", true);            int initWidth = 300;            int initHeight = 150;            int x = (Screen.currentResolution.width - initWidth) / 2;            int y = (Screen.currentResolution.height - initHeight) / 2;            window.position = new Rect(x, y, initWidth, initHeight);        }    }    static float unitsScale;    static bool exportMaterial;    SceneExport()    {        unitsScale = 100f;        exportMaterial = true;    }    Texture icon;    void Awake()    {        if (EditorPrefs.HasKey("SceneExportMaterial"))            exportMaterial = EditorPrefs.GetBool("SceneExportMaterial");        else            exportMaterial = true;        if (EditorPrefs.HasKey("SceneExportUnitsScale"))            unitsScale = EditorPrefs.GetFloat("SceneExportUnitsScale");        else            unitsScale = 100f;        icon =             AssetDatabase.LoadAssetAtPath(                "assets/editor/images/sceneExporter.png", typeof(Texture)) as Texture;    }    void OnDestroy()    {        icon = null;        window = null;        EditorPrefs.SetBool("SceneExportMaterial", exportMaterial);        EditorPrefs.SetFloat("SceneExportUnitsScale", unitsScale);    }    void OnGUI()    {        EditorGUILayout.BeginVertical();        GUILayout.Space(10f);        EditorGUILayout.BeginHorizontal();        exportMaterial =            EditorGUILayout.Toggle("Material", exportMaterial);        GUILayout.FlexibleSpace();        EditorGUILayout.EndHorizontal();        unitsScale =             EditorGUILayout.FloatField("Units Scale", unitsScale);        if (icon)        {            Rect rc =                 GUILayoutUtility.GetRect(icon.width, icon.height);            rc.x += 6f;            rc.y += 6f;            rc.width = icon.width;            rc.height = icon.height;            GUI.DrawTexture(rc, icon);        }        GUILayout.FlexibleSpace();        EditorGUILayout.BeginHorizontal();        GUILayout.FlexibleSpace();        if (GUILayout.Button("Export", GUILayout.Width(90f)))            Export();        EditorGUILayout.EndHorizontal();        EditorGUILayout.EndVertical();    }    static void Export()    {        Transform[] objectList =            Selection.GetTransforms(SelectionMode.Editable | SelectionMode.ExcludePrefab);        if (objectList.Length <= 0)        {            EditorUtility.DisplayDialog("Alert", "No Object Selected", "OK");            return;        }                List<Model> modelList = new List<Model>();        for (int i = 0; i < objectList.Length; ++i)        {            MeshFilter[] meshList =                objectList[i].GetComponentsInChildren<MeshFilter>();            for (int j = 0; j < meshList.Length; ++j)            {                Model model = new Model();                MeshFilter _meshFilter = meshList[j];                model.mesh = _meshFilter.sharedMesh;                Renderer meshrenderer = _meshFilter.GetComponent<Renderer>();                if (meshrenderer)                    model.materials = meshrenderer.sharedMaterials;                model.transform = _meshFilter.transform;                modelList.Add(model);            }            SkinnedMeshRenderer[] skinList =                objectList[i].GetComponentsInChildren<SkinnedMeshRenderer>();            for (int j = 0; j < skinList.Length; ++j)            {                Model model = new Model();                SkinnedMeshRenderer _skinRender = skinList[j];                model.mesh = _skinRender.sharedMesh;                model.materials = _skinRender.sharedMaterials;                model.transform = _skinRender.transform;                modelList.Add(model);            }        }        if (modelList.Count <= 0)        {            EditorUtility.DisplayDialog("Alert", "No Mesh To Export", "OK");            return;        }        string modelPath =            EditorUtility.SaveFilePanel(                "Scene Export Name", EditorPrefs.GetString("sceneExportPath"),                 Path.GetFileNameWithoutExtension(SceneManager.GetActiveScene().name), "obj");        if (string.IsNullOrEmpty(modelPath))        {            EditorUtility.DisplayDialog("Error", "Invalid Export Name", "OK");            return;        }        string path =            Path.GetDirectoryName(modelPath);        string name =            Path.GetFileNameWithoutExtension(modelPath);        EditorPrefs.SetString("sceneExportPath", path);        string materialPath = string.Format("{0}/{1}.material", path, name);        if (!Directory.Exists(materialPath))            Directory.CreateDirectory(materialPath);        float modelPret =             exportMaterial ? 0.9f : 1f;        float materialPret = 1f - modelPret;        HashSet<ModelMaterial> materialSet =            new HashSet<ModelMaterial>(new MaterialCompare());        using (StreamWriter writer = new StreamWriter(modelPath))        {            writer.WriteLine(                string.Format("mtllib ./{0}.material/material.mtl", name));            writer.WriteLine();            int offset = 0;            for (int i = 0; i < modelList.Count; ++i)            {                ExportMesh(writer, modelList[i], materialSet, ref offset);                EditorUtility.DisplayProgressBar(                    "SceneExport",                     string.Format(                        "Export Model : {0}", modelList[i].transform.name),                     modelPret * (float)i / (float)modelList.Count);            }            writer.Close();        }        if (exportMaterial)            using (StreamWriter writer =                new StreamWriter(string.Format("{0}/material.mtl", materialPath)))            {                int p = 0;                int count = materialSet.Count;                foreach (ModelMaterial material in materialSet)                {                    ExportMaterial(writer, material, materialPath);                    EditorUtility.DisplayProgressBar(                        "SceneExport",                        string.Format(                            "Export Material : {0}", material.name),                        materialPret * (float)p / (float)count);                    ++p;                }                writer.Close();            }        EditorUtility.ClearProgressBar();        EditorUtility.RevealInFinder(modelPath);    }    static void ExportMesh(        TextWriter writer, Model model, HashSet<ModelMaterial> materalSet, ref int offset)    {        int vertexCount = model.mesh.vertexCount;        writer.WriteLine(            string.Format("g {0}", model.transform.name));        for (int i = 0; i < vertexCount; ++i)        {            Vector3 v =                model.transform.TransformPoint(model.mesh.vertices[i]);            v *= unitsScale;            writer.WriteLine(                string.Format("v {0} {1} {2}", -v.x, v.y, v.z));        }        writer.WriteLine();        for (int i = 0; i < vertexCount; ++i)        {            Vector3 n =                model.transform.TransformDirection(model.mesh.normals[i]);            writer.WriteLine(                string.Format("vn {0} {1} {2}", -n.x, n.y, n.z));        }        writer.WriteLine();        for (int i = 0; i < vertexCount; ++i)        {            Vector2 t = model.mesh.uv[i];            writer.WriteLine(                string.Format("vt {0} {1}", t.x, t.y));        }        writer.WriteLine();        for (int i = 0; i < model.mesh.subMeshCount; ++i)        {            Material mtl = model.materials[i];            int[] triangles = model.mesh.GetTriangles(i);            if (exportMaterial)            {                ModelMaterial modelMtl = new ModelMaterial();                modelMtl.name = mtl.name;                modelMtl.cutoff = 1f;                for (int t = 0; t < 100; ++t)                {                    if (!materalSet.Contains(modelMtl))                        break;                    modelMtl.name =                        string.Format("{0}_{1:d2}", mtl.name, t);                }                writer.WriteLine(                        string.Format("usemtl {0}", modelMtl.name));                writer.WriteLine(                    string.Format("usemap {0}", modelMtl.name));                if (mtl.mainTexture)                    modelMtl.texture = AssetDatabase.GetAssetPath(mtl.mainTexture);                else                    modelMtl.texture = null;                if (mtl.HasProperty("_Cutoff"))                    modelMtl.cutoff = mtl.GetFloat("_Cutoff");                materalSet.Add(modelMtl);            }            for (int j = 0; j < triangles.Length / 3; ++j)                writer.WriteLine(                    string.Format(                        "f {1}/{1}/{1} {0}/{0}/{0} {2}/{2}/{2}",                        triangles[j * 3 + 0] + 1 + offset,                        triangles[j * 3 + 1] + 1 + offset,                        triangles[j * 3 + 2] + 1 + offset));        }        writer.WriteLine();        offset += vertexCount;    }    static void ExportMaterial(TextWriter writer, ModelMaterial material, string path)    {        writer.WriteLine("newmtl {0}", material.name);        writer.WriteLine("Ka  1.0 1.0 1.0");        writer.WriteLine("Kd  1.0 1.0 1.0");        writer.WriteLine("Ks  0.0 0.0 0.0");        writer.WriteLine("d  1.0");        writer.WriteLine("illum 1");        if (!string.IsNullOrEmpty(material.texture))        {            string texture =                Path.GetFileName(material.texture);            try            {                File.Copy(material.texture, path + "/" + texture);            }            catch (System.Exception)            {            }            writer.WriteLine("map_Kd {0}", texture);            if (material.cutoff < 1f)                writer.WriteLine("map_d {0}", texture);        }        writer.WriteLine();    }}


阅读全文
0 0
原创粉丝点击