Export options/settings, material export, prefab export.

Moved/changed replace OBJ to ReplaceMesh.
Optional model/texture/material export.
Added Material export option, set shader and shader properties to assign exported textures.
Added Prefab export option, exports mesh as an Unity .asset file and creates a prefab to link it to the mesh filter/renderer, added the option for auto assignment of the exported material (New default).
This commit is contained in:
max 2019-11-27 00:22:05 +01:00
parent 947eb6f18e
commit 406720d718
5 changed files with 273 additions and 108 deletions

View File

@ -1,6 +1,7 @@
using UnityEngine;
using System.Collections;
using MA_Texture;
using System.Collections.Generic;
namespace MA_TextureAtlasserPro
{
@ -10,8 +11,11 @@ namespace MA_TextureAtlasserPro
[HideInInspector]
public bool canModify = true;
public bool exportModels = true;
public ModelExportSettings modelExportSettings = new ModelExportSettings();
public bool exportTextures = true;
public TextureExportSettings textureExportSettings = new TextureExportSettings();
public bool exportMaterials = true;
public MaterialExportSettings materialExportSettings = new MaterialExportSettings();
}
@ -19,8 +23,7 @@ namespace MA_TextureAtlasserPro
public class ModelExportSettings
{
[Header("Model settings:")]
public ModelFormat modelFormat = ModelFormat.Obj;
public bool replaceModel = false;
public ModelFormat modelFormat = ModelFormat.UnityMeshPrefab;
public bool uvFlipY = true;
public int uvChannel = 0;
public bool uvWrap = true;
@ -35,17 +38,19 @@ namespace MA_TextureAtlasserPro
public MA_TextureUtils.TextureScaleMode textureScaleMode = MA_TextureUtils.TextureScaleMode.Bilinear;
}
public enum ExportPreset
[System.Serializable]
public class MaterialExportSettings
{
Custom,
Default,
Sprites,
ReplaceObjMeshes
[Header("Material settings:")]
public Shader shader = null;
public List<string> shaderPropertyNames = new List<string>() { "_MainTex", "_MetallicGlossMap", "_BumpMap" };
}
public enum ModelFormat
{
None,
UnityMeshPrefab,
ReplaceMesh,
Obj
}
@ -61,12 +66,4 @@ namespace MA_TextureAtlasserPro
Sprite,
SpriteSliced
}
[System.Serializable]
public class MaterialExportSettings
{
[Header("Material settings:")]
public string shader = "Standard";
public string[] shaderPropertyNames = { "_MainTex", "_MetallicGlossMap", "_BumpMap" };
}
}

View File

@ -60,6 +60,8 @@ namespace MA_TextureAtlasserPro
if (_settings != null)
{
_settings.materialExportSettings.shader = Shader.Find("Standard");
CreateFolder(EXPORT_ASSET_PATH);
AssetDatabase.CreateAsset(_settings, SETTINGS_ASSET_PATH + name + ".asset");
AssetDatabase.SaveAssets();
@ -387,100 +389,155 @@ namespace MA_TextureAtlasserPro
}
#region Export
public static void ExportAtlasModels(MA_TextureAtlasserProAtlas atlas, ModelExportSettings modelExportSettings, string savePath = EXPORT_ASSET_PATH)
public static string[] ExportAtlasModels(MA_TextureAtlasserProAtlas atlas, ModelExportSettings modelExportSettings, string material = null, string savePath = EXPORT_ASSET_PATH)
{
switch(modelExportSettings.modelFormat)
{
case ModelFormat.None:
break;
case ModelFormat.Obj:
ExportAtlasObj(atlas, modelExportSettings, savePath);
case ModelFormat.ReplaceMesh:
ReplaceAtlasMesh(atlas, modelExportSettings, savePath: savePath);
break;
case ModelFormat.UnityMeshPrefab:
return ExportAtlasUnityMeshPrefab(atlas, modelExportSettings, material: material, savePath: savePath);
case ModelFormat.Obj:
return ExportAtlasObj(atlas, modelExportSettings, savePath: savePath);
default:
break;
}
return null;
}
private static void ExportAtlasObj(MA_TextureAtlasserProAtlas atlas, ModelExportSettings modelExportSettings, string savePath = EXPORT_ASSET_PATH)
{
private static void ReplaceAtlasMesh(MA_TextureAtlasserProAtlas atlas, ModelExportSettings modelExportSettings, string savePath = EXPORT_ASSET_PATH)
{
if (atlas == null || atlas.textureQuads == null)
return;
if(modelExportSettings.replaceModel)
var quads = atlas.textureQuads;
for (var index = 0; index < quads.Count; index++)
{
var quads = atlas.textureQuads;
var quad = quads[index];
if (quad.meshes == null)
continue;
for (var index = 0; index < quads.Count; index++)
var meshes = quad.meshes;
for (var meshIndex = 0; meshIndex < quad.meshes.Count; meshIndex++)
{
var quad = quads[index];
if (quad.meshes == null)
if (meshes[meshIndex] == null)
continue;
var meshes = quad.meshes;
for (var meshIndex = 0; meshIndex < quad.meshes.Count; meshIndex++)
{
if (meshes[meshIndex] == null)
continue;
MA_MeshUtils.MA_UVReMap(meshes[meshIndex], atlas.textureAtlasSize, quad.guiRect, modelExportSettings.uvChannel, modelExportSettings.uvFlipY, modelExportSettings.uvWrap);
EditorUtility.SetDirty(meshes[meshIndex]);
}
MA_MeshUtils.MA_UVReMap(meshes[meshIndex], atlas.textureAtlasSize, quad.guiRect, modelExportSettings.uvChannel, modelExportSettings.uvFlipY, modelExportSettings.uvWrap);
EditorUtility.SetDirty(meshes[meshIndex]);
}
AssetDatabase.SaveAssets();
}
else
{
foreach (MA_TextureAtlasserProQuad quad in atlas.textureQuads)
{
//Export Mesh
if (quad.meshes != null)
{
for (int m = 0; m < quad.meshes.Count; m++)
{
if (quad.meshes[m] != null)
{
//Create new mesh
Mesh newMesh = new Mesh();
//Duplicate it from the current one
newMesh = MA_MeshUtils.MA_DuplicateMesh(quad.meshes[m]);
//Remap UV's
newMesh = MA_MeshUtils.MA_UVReMap(newMesh, atlas.textureAtlasSize, quad.guiRect, modelExportSettings.uvChannel, modelExportSettings.uvFlipY, modelExportSettings.uvWrap);
//Save it
string modelName = string.IsNullOrEmpty(quad.name) ? "" : quad.name + "-";
modelName += quad.meshes[m].name;
int n = m + 1;
modelName += "_" + n.ToString("#000");
MA_MeshUtils.MeshToFile(newMesh, modelName, savePath);
}
AssetDatabase.SaveAssets();
}
private static string[] ExportAtlasUnityMeshPrefab(MA_TextureAtlasserProAtlas atlas, ModelExportSettings modelExportSettings, string material = null, string savePath = EXPORT_ASSET_PATH)
{
if (atlas == null || atlas.textureQuads == null)
return null;
List<string> assetPaths = new List<string>();
foreach (MA_TextureAtlasserProQuad quad in atlas.textureQuads)
{
//Export Mesh
if (quad.meshes != null)
{
for (int m = 0; m < quad.meshes.Count; m++)
{
if (quad.meshes[m] != null)
{
//Create new mesh
Mesh newMesh = new Mesh();
//Duplicate it from the current one
newMesh = MA_MeshUtils.MA_DuplicateMesh(quad.meshes[m]);
//Remap UV's
newMesh = MA_MeshUtils.MA_UVReMap(newMesh, atlas.textureAtlasSize, quad.guiRect, modelExportSettings.uvChannel, modelExportSettings.uvFlipY, modelExportSettings.uvWrap);
//Save it
string meshName = string.IsNullOrEmpty(quad.name) ? "" : quad.name + "-";
meshName += quad.meshes[m].name;
int n = m + 1;
meshName += "_" + n.ToString("#000");
string asset = MA_MeshUtils.MA_SaveMeshPrefab(newMesh, meshName, savePath, material: material);
assetPaths.Add(asset);
}
}
}
}
return assetPaths.ToArray();
}
private static string[] ExportAtlasObj(MA_TextureAtlasserProAtlas atlas, ModelExportSettings modelExportSettings, string savePath = EXPORT_ASSET_PATH)
{
if (atlas == null || atlas.textureQuads == null)
return null;
List<string> assetPaths = new List<string>();
foreach (MA_TextureAtlasserProQuad quad in atlas.textureQuads)
{
//Export Mesh
if (quad.meshes != null)
{
for (int m = 0; m < quad.meshes.Count; m++)
{
if (quad.meshes[m] != null)
{
//Create new mesh
Mesh newMesh = new Mesh();
//Duplicate it from the current one
newMesh = MA_MeshUtils.MA_DuplicateMesh(quad.meshes[m]);
//Remap UV's
newMesh = MA_MeshUtils.MA_UVReMap(newMesh, atlas.textureAtlasSize, quad.guiRect, modelExportSettings.uvChannel, modelExportSettings.uvFlipY, modelExportSettings.uvWrap);
//Save it
string meshName = string.IsNullOrEmpty(quad.name) ? "" : quad.name + "-";
meshName += quad.meshes[m].name;
int n = m + 1;
meshName += "_" + n.ToString("#000");
string asset = MA_MeshUtils.MeshToFile(newMesh, meshName, savePath);
assetPaths.Add(asset);
}
}
}
}
return assetPaths.ToArray();
}
public static void ExportAtlasTextures(MA_TextureAtlasserProAtlas atlas, TextureExportSettings textureExportSettings, string savePath = EXPORT_ASSET_PATH, string tempPath = TEXTURE_ATLASSER_PATH)
public static string[] ExportAtlasTextures(MA_TextureAtlasserProAtlas atlas, TextureExportSettings textureExportSettings, string savePath = EXPORT_ASSET_PATH, string tempPath = TEXTURE_ATLASSER_PATH)
{
switch (textureExportSettings.textureFormat)
{
case TextureFormat.None:
break;
case TextureFormat.Png:
ExportAtlasPNG(atlas, textureExportSettings, savePath);
break;
return ExportAtlasPNG(atlas, textureExportSettings, savePath);
default:
break;
}
return null;
}
private static void ExportAtlasPNG(MA_TextureAtlasserProAtlas atlas, TextureExportSettings textureExportSettings, string savePath = EXPORT_ASSET_PATH, string tempPath = TEMP_ASSET_PATH)
private static string[] ExportAtlasPNG(MA_TextureAtlasserProAtlas atlas, TextureExportSettings textureExportSettings, string savePath = EXPORT_ASSET_PATH, string tempPath = TEMP_ASSET_PATH)
{
if (atlas == null || atlas.textureQuads == null || atlas.textureGroupRegistration == null)
return;
return null;
//Foreach texture group
for (int i = 0; i < atlas.textureGroupRegistration.Count; i++)
string[] assetPaths = new string[atlas.textureGroupRegistration.Count];
//Create temp folder
CreateFolder(tempPath);
//Foreach texture group
for (int i = 0; i < atlas.textureGroupRegistration.Count; i++)
{
//Create new Texture Atlas
Texture2D newTexture = new Texture2D((int)atlas.textureAtlasSize.x, (int)atlas.textureAtlasSize.y)
@ -496,9 +553,6 @@ namespace MA_TextureAtlasserPro
string orginalTexturePath = AssetDatabase.GetAssetPath(q.textureGroups[i].texture);
string orginalTextureExtension = System.IO.Path.GetExtension(orginalTexturePath);
//Create temp folder
CreateFolder(tempPath);
string tempTexturePath = tempPath + q.textureGroups[i].texture.name + orginalTextureExtension;
AssetDatabase.CopyAsset(orginalTexturePath, tempTexturePath);
@ -528,12 +582,11 @@ namespace MA_TextureAtlasserPro
}
}
//Delete temp folder
DeleteFolder(tempPath);
//Save it
newTexture.MA_Save2D(newTexture.name, savePath);
assetPaths[i] = (savePath + newTexture.name + '.' + textureExportSettings.textureFormat.ToString());
//Set settings.
switch (textureExportSettings.textureType)
{
@ -555,8 +608,13 @@ namespace MA_TextureAtlasserPro
}
}
//Refresh
AssetDatabase.Refresh();
//Delete temp folder
DeleteFolder(tempPath);
//Refresh
AssetDatabase.Refresh();
return assetPaths;
}
private static void SetAtlasSpriteSettings(MA_TextureAtlasserProAtlas atlas, TextureExportSettings textureExportSettings, string savePath = EXPORT_ASSET_PATH)
@ -603,26 +661,41 @@ namespace MA_TextureAtlasserPro
}
}
public static void ExportAtlasMaterial(MA_TextureAtlasserProAtlas atlas, MaterialExportSettings materialExportSettings, Texture[] textures, string savePath = EXPORT_ASSET_PATH)
public static string ExportAtlasMaterial(MA_TextureAtlasserProAtlas atlas, MaterialExportSettings materialExportSettings, string[] textures = null, string savePath = EXPORT_ASSET_PATH)
{
if (atlas == null || atlas.textureQuads == null || atlas.textureGroupRegistration == null || textures == null)
return;
if (atlas == null || atlas.textureQuads == null || atlas.textureGroupRegistration == null)
return null;
Shader shader = Shader.Find(materialExportSettings.shader);
string assetPath = "";
Shader shader = materialExportSettings.shader;
if (shader)
{
Material material = new Material(shader);
material.name = atlas.name;
for (int i = 0; i < (int)Mathf.Max(materialExportSettings.shaderPropertyNames.Length - 1, textures.Length - 1); i++)
Material material = new Material(shader)
{
material.SetTexture(materialExportSettings.shaderPropertyNames[i], textures[i]);
name = atlas.name
};
if(textures != null)
{
for (int i = 0; i < (int)Mathf.Min(materialExportSettings.shaderPropertyNames.Count, textures.Length); i++)
{
Texture t = AssetDatabase.LoadAssetAtPath<Texture>(textures[i]);
if (t != null)
{
material.SetTexture(materialExportSettings.shaderPropertyNames[i], t);
}
}
}
assetPath = savePath + material.name + ".mat";
//Save material
AssetDatabase.CreateAsset(material, EXPORT_ASSET_PATH + material.name);
AssetDatabase.CreateAsset(material, assetPath);
AssetDatabase.Refresh();
}
return assetPath;
}
#endregion
}

View File

@ -122,7 +122,7 @@ namespace MA_TextureAtlasserPro
}
if(GUILayout.Button("+", EditorStyles.miniButtonRight, GUILayout.ExpandWidth(false)))
{
curWindow.textureAtlas.selectedTextureQuad.meshes.Insert(i, null);
curWindow.textureAtlas.selectedTextureQuad.meshes.Insert(i + 1, null);
}
GUILayout.EndHorizontal();
}

View File

@ -10,7 +10,7 @@ namespace MA_TextureAtlasserPro
{
public class MA_TextureAtlasserProExportWindow : EditorWindow
{
private const int windowHeight = 300;
private const int windowHeight = 385;
private const int windowWidth = 320;
//Editor
@ -19,6 +19,7 @@ namespace MA_TextureAtlasserPro
//Data
private static bool isLoaded = false; //Make sure we wait a frame at the start to setup and don't draw.
private Vector2 scrollPos;
[MenuItem("MA_ToolKit/MA_TextureAtlasserPro/Export Atlas")]
private static void Init()
@ -91,8 +92,7 @@ namespace MA_TextureAtlasserPro
GUILayout.BeginArea(new Rect(MA_TextureAtlasserProUtils.VIEW_OFFSET, MA_TextureAtlasserProUtils.VIEW_OFFSET, position.width - (MA_TextureAtlasserProUtils.VIEW_OFFSET * 2), position.height - (MA_TextureAtlasserProUtils.VIEW_OFFSET * 2)));
GUILayout.BeginVertical();
if(curWindow != null && curWindow.textureAtlas != null)
if (curWindow != null && curWindow.textureAtlas != null)
{
//Export
GUILayout.BeginVertical();
@ -102,7 +102,7 @@ namespace MA_TextureAtlasserPro
if(curWindow.textureAtlas.exportSettings != null)
{
DrawExportAdvancedOptions();
DrawExportOptions();
}
GUILayout.EndVertical();
@ -154,9 +154,41 @@ namespace MA_TextureAtlasserPro
if (GUILayout.Button("Export", GUILayout.ExpandWidth(true), GUILayout.Height(37)))
{
MA_TextureAtlasserProUtils.ExportAtlasModels(curWindow.textureAtlas, curWindow.textureAtlas.exportSettings.modelExportSettings);
MA_TextureAtlasserProUtils.ExportAtlasTextures(curWindow.textureAtlas, curWindow.textureAtlas.exportSettings.textureExportSettings);
//MA_TextureAtlasserProUtils.ExportAtlasMaterial(curWindow.textureAtlas, curWindow.textureAtlas.exportSettings.materialExportSettings);
bool export = false;
if(curWindow.textureAtlas.exportSettings.modelExportSettings.modelFormat == ModelFormat.ReplaceMesh)
{
if(EditorUtility.DisplayDialog("Replace original models?", "Are you sure you want to replace the original models, this can't be undone!", "Replace", "Cancel"))
{
export = true;
}
}
else
{
export = true;
}
if(export)
{
string[] textures = null;
string material = null;
string[] models = null;
if (curWindow.textureAtlas.exportSettings.exportTextures)
{
textures = MA_TextureAtlasserProUtils.ExportAtlasTextures(curWindow.textureAtlas, curWindow.textureAtlas.exportSettings.textureExportSettings);
}
if(curWindow.textureAtlas.exportSettings.exportMaterials)
{
material = MA_TextureAtlasserProUtils.ExportAtlasMaterial(curWindow.textureAtlas, curWindow.textureAtlas.exportSettings.materialExportSettings, textures: textures);
}
if(curWindow.textureAtlas.exportSettings.exportModels)
{
models = MA_TextureAtlasserProUtils.ExportAtlasModels(curWindow.textureAtlas, curWindow.textureAtlas.exportSettings.modelExportSettings, material: material);
}
}
}
GUI.enabled = wasEnabled;
@ -164,7 +196,7 @@ namespace MA_TextureAtlasserPro
GUILayout.EndHorizontal();
}
private void DrawExportAdvancedOptions()
private void DrawExportOptions()
{
bool wasEnabled = GUI.enabled;
@ -179,18 +211,37 @@ namespace MA_TextureAtlasserPro
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
GUILayout.Label("Models:", EditorStyles.miniBoldLabel);
curWindow.textureAtlas.exportSettings.exportModels = GUILayout.Toggle(curWindow.textureAtlas.exportSettings.exportModels, "Models:", EditorStyles.toggle);
curWindow.textureAtlas.exportSettings.modelExportSettings.modelFormat = (ModelFormat)EditorGUILayout.EnumPopup("ModelFormat:", curWindow.textureAtlas.exportSettings.modelExportSettings.modelFormat);
curWindow.textureAtlas.exportSettings.modelExportSettings.replaceModel = EditorGUILayout.Toggle("ReplaceModels:", curWindow.textureAtlas.exportSettings.modelExportSettings.replaceModel);
curWindow.textureAtlas.exportSettings.modelExportSettings.uvFlipY = EditorGUILayout.Toggle("UV FlipY:", curWindow.textureAtlas.exportSettings.modelExportSettings.uvFlipY);
curWindow.textureAtlas.exportSettings.modelExportSettings.uvChannel = EditorGUILayout.IntField("UV Channel:", curWindow.textureAtlas.exportSettings.modelExportSettings.uvChannel);
curWindow.textureAtlas.exportSettings.modelExportSettings.uvWrap = EditorGUILayout.Toggle("UV Wrap:", curWindow.textureAtlas.exportSettings.modelExportSettings.uvWrap);
GUILayout.Label("Textures:", EditorStyles.miniBoldLabel);
curWindow.textureAtlas.exportSettings.exportTextures = GUILayout.Toggle(curWindow.textureAtlas.exportSettings.exportTextures, "Textures:", EditorStyles.toggle);
curWindow.textureAtlas.exportSettings.textureExportSettings.textureFormat = (TextureFormat)EditorGUILayout.EnumPopup("TextureFormat:", curWindow.textureAtlas.exportSettings.textureExportSettings.textureFormat);
curWindow.textureAtlas.exportSettings.textureExportSettings.textureType = (TextureType)EditorGUILayout.EnumPopup("TextureType:", curWindow.textureAtlas.exportSettings.textureExportSettings.textureType);
curWindow.textureAtlas.exportSettings.textureExportSettings.textureScaleMode = (MA_TextureUtils.TextureScaleMode)EditorGUILayout.EnumPopup("TextureScaleMode:", curWindow.textureAtlas.exportSettings.textureExportSettings.textureScaleMode);
curWindow.textureAtlas.exportSettings.exportMaterials = GUILayout.Toggle(curWindow.textureAtlas.exportSettings.exportMaterials, "Materials:", EditorStyles.toggle);
curWindow.textureAtlas.exportSettings.materialExportSettings.shader = (Shader)EditorGUILayout.ObjectField("Shader:", curWindow.textureAtlas.exportSettings.materialExportSettings.shader, typeof(UnityEngine.Shader), false);
scrollPos = EditorGUILayout.BeginScrollView(scrollPos, false, false, GUILayout.ExpandWidth(true), GUILayout.ExpandHeight(true));
for (int i = 0; i < curWindow.textureAtlas.exportSettings.materialExportSettings.shaderPropertyNames.Count; i++)
{
GUILayout.BeginHorizontal();
curWindow.textureAtlas.exportSettings.materialExportSettings.shaderPropertyNames[i] = EditorGUILayout.TextField("", curWindow.textureAtlas.exportSettings.materialExportSettings.shaderPropertyNames[i]);
if (GUILayout.Button("-", EditorStyles.miniButtonLeft, GUILayout.ExpandWidth(false)))
{
curWindow.textureAtlas.exportSettings.materialExportSettings.shaderPropertyNames.RemoveAt(i);
}
if (GUILayout.Button("+", EditorStyles.miniButtonRight, GUILayout.ExpandWidth(false)))
{
curWindow.textureAtlas.exportSettings.materialExportSettings.shaderPropertyNames.Insert(i + 1, "");
}
GUILayout.EndHorizontal();
}
EditorGUILayout.EndScrollView();
EditorGUILayout.EndVertical();
GUI.enabled = wasEnabled;

View File

@ -17,12 +17,9 @@ namespace MA_Mesh
{
public static class MA_MeshUtils
{
public static void MA_SaveMeshAsset(Mesh mesh, string savePath, string meshName = "")
public static string MA_SaveMeshAsset(Mesh mesh, string meshName, string savePath)
{
Mesh newMesh = new Mesh();
newMesh.SetVertices(new List<Vector3>(mesh.vertices));
newMesh.SetTriangles(mesh.triangles, 0);
newMesh.SetUVs(0, new List<Vector2>(mesh.uv));
Mesh newMesh = mesh;
if(meshName == "")
{
@ -33,10 +30,51 @@ namespace MA_Mesh
newMesh.name = meshName;
}
AssetDatabase.CreateAsset(newMesh, savePath);
AssetDatabase.SaveAssets();
string assetPath = savePath + newMesh.name + ".asset";
AssetDatabase.CreateAsset(newMesh, assetPath);
AssetDatabase.SaveAssets();
return assetPath;
}
public static string MA_SaveMeshPrefab(Mesh mesh, string meshName, string savePath, string material)
{
string assetPath = "";
if (meshName == "")
{
meshName = mesh.name;
}
string meshPath = MA_SaveMeshAsset(mesh, meshName, savePath);
Mesh curMesh = AssetDatabase.LoadAssetAtPath<Mesh>(meshPath);
if (curMesh != null)
{
GameObject gameObject = new GameObject
{
name = meshName
};
gameObject.AddComponent<MeshFilter>().mesh = curMesh;
gameObject.AddComponent<MeshRenderer>();
Material curMaterial = AssetDatabase.LoadAssetAtPath<Material>(material);
if (curMaterial != null)
{
gameObject.GetComponent<MeshRenderer>().material = curMaterial;
}
assetPath = savePath + meshName + ".prefab";
PrefabUtility.SaveAsPrefabAsset(gameObject, assetPath);
UnityEngine.GameObject.DestroyImmediate(gameObject);
}
return assetPath;
}
public static Mesh MA_DuplicateMesh(Mesh mesh)
{
Mesh newMesh = new Mesh
@ -199,12 +237,18 @@ namespace MA_Mesh
return sb.ToString();
}
public static void MeshToFile(Mesh mesh, string filename, string savePath)
public static string MeshToFile(Mesh mesh, string filename, string savePath)
{
using (StreamWriter sw = new StreamWriter(savePath + filename + ".obj"))
string assetPath = savePath + filename + ".obj";
using (StreamWriter sw = new StreamWriter(assetPath))
{
sw.Write(MeshToString(mesh));
}
AssetDatabase.Refresh();
return assetPath;
}
//End
}