Support old prefab system

Added support for the prefab system used before Unity 2018.
This commit is contained in:
max 2019-11-29 00:03:18 +01:00
parent 406720d718
commit 0dfa466d78
5 changed files with 516 additions and 521 deletions

View File

@ -1,21 +1 @@
# MA_TextureAtlasser README: https://github.com/maxartz15/MA_TextureAtlasser/blob/master/README.md
Texture atlas creator for Unity
[![Image](https://maxartz15.com/wp-content/uploads/2019/04/MA_TextureAtlas.png)]()
You can combine textures and/or remap the UVs for the 3D models.
By having full control over the size and position of the textures that are being placed in the atlas you will never stand for surprises when exporting. This will cost some more time than auto-generating your texture atlases but you know whats going on and which models/textures are getting priority. The tool can also be used to make 2D sprite sheets.
- Combine textures/sprites.
- Automatically adjusts the UV's of the assigned meshes to match the new texture atlas.
- Exports meshes as OBJ.
- Exports texture atlas as PNG.
- Exports texture atlas as a (sliced) sprite sheet.
[Example video](https://youtu.be/PBRKlopkZP0)
Download the UnityPackage here: https://github.com/maxartz15/MA_TextureAtlasser/releases
[![Github All Releases](https://img.shields.io/github/downloads/maxartz15/MA_TextureAtlasser/total.svg)]()
For more information: https://maxartz15.com/ma-textureatlasser/

View File

@ -8,50 +8,48 @@ using MA_Texture;
namespace MA_TextureAtlasserPro namespace MA_TextureAtlasserPro
{ {
public static class MA_TextureAtlasserProUtils
{
public static class MA_TextureAtlasserProUtils
{
public const string TEXTURE_ATLASSER_PATH = "Assets/MA_ToolBox/MA_TextureAtlasserPro/"; public const string TEXTURE_ATLASSER_PATH = "Assets/MA_ToolBox/MA_TextureAtlasserPro/";
public const string SETTINGS_ASSET_PATH = "Assets/MA_ToolBox/MA_TextureAtlasserPro/Settings/"; public const string SETTINGS_ASSET_PATH = "Assets/MA_ToolBox/MA_TextureAtlasserPro/Settings/";
public const string SAVE_ASSET_PATH = "Assets/MA_ToolBox/MA_TextureAtlasserPro/Atlasses/"; public const string SAVE_ASSET_PATH = "Assets/MA_ToolBox/MA_TextureAtlasserPro/Atlasses/";
public const string LOAD_ASSET_PATH = "Assets/MA_ToolBox/MA_TextureAtlasserPro/Atlasses/"; public const string LOAD_ASSET_PATH = "Assets/MA_ToolBox/MA_TextureAtlasserPro/Atlasses/";
public const string EXPORT_ASSET_PATH = "Assets/MA_ToolBox/MA_TextureAtlasserPro/Exports/"; public const string EXPORT_ASSET_PATH = "Assets/MA_ToolBox/MA_TextureAtlasserPro/Exports/";
public const string TEMP_ASSET_PATH = "Assets/MA_ToolBox/MA_TextureAtlasserPro/Temp/"; public const string TEMP_ASSET_PATH = "Assets/MA_ToolBox/MA_TextureAtlasserPro/Temp/";
public const string DEFAULT_TEXTURE_GROUP_NAME = "Albedo"; public const string DEFAULT_TEXTURE_GROUP_NAME = "Albedo";
public const float VIEW_OFFSET = 20; public const float VIEW_OFFSET = 20;
public static MA_TextureAtlasserProSettings CreateSettings() public static MA_TextureAtlasserProSettings CreateSettings()
{ {
MA_TextureAtlasserProSettings _settings = ScriptableObject.CreateInstance<MA_TextureAtlasserProSettings>(); MA_TextureAtlasserProSettings _settings = ScriptableObject.CreateInstance<MA_TextureAtlasserProSettings>();
if(_settings != null) if (_settings != null)
{ {
CreateFolder(SETTINGS_ASSET_PATH); CreateFolder(SETTINGS_ASSET_PATH);
AssetDatabase.CreateAsset(_settings, SETTINGS_ASSET_PATH + "MA_TextureAtlasserProSettings.asset"); AssetDatabase.CreateAsset(_settings, SETTINGS_ASSET_PATH + "MA_TextureAtlasserProSettings.asset");
AssetDatabase.SaveAssets(); AssetDatabase.SaveAssets();
AssetDatabase.Refresh(); AssetDatabase.Refresh();
return _settings; return _settings;
} }
else else
{ {
return null; return null;
} }
} }
public static MA_TextureAtlasserProSettings LoadSettings() public static MA_TextureAtlasserProSettings LoadSettings()
{ {
MA_TextureAtlasserProSettings _settings = AssetDatabase.LoadAssetAtPath(SETTINGS_ASSET_PATH + "MA_TextureAtlasserProSettings.asset", typeof(MA_TextureAtlasserProSettings)) as MA_TextureAtlasserProSettings; MA_TextureAtlasserProSettings _settings = AssetDatabase.LoadAssetAtPath(SETTINGS_ASSET_PATH + "MA_TextureAtlasserProSettings.asset", typeof(MA_TextureAtlasserProSettings)) as MA_TextureAtlasserProSettings;
if (_settings == null) if (_settings == null)
{ {
_settings = CreateSettings(); _settings = CreateSettings();
} }
return _settings; return _settings;
} }
public static MA_TextureAtlasserProExportSettings CreateExportSettings(string name, bool canModify = true) public static MA_TextureAtlasserProExportSettings CreateExportSettings(string name, bool canModify = true)
{ {
@ -89,273 +87,273 @@ namespace MA_TextureAtlasserPro
} }
public static MA_TextureAtlasserProAtlas CreateTextureAtlas(string name, Vector2 size) public static MA_TextureAtlasserProAtlas CreateTextureAtlas(string name, Vector2 size)
{ {
MA_TextureAtlasserProAtlas _atlas = ScriptableObject.CreateInstance<MA_TextureAtlasserProAtlas>(); MA_TextureAtlasserProAtlas _atlas = ScriptableObject.CreateInstance<MA_TextureAtlasserProAtlas>();
if(_atlas != null) if (_atlas != null)
{ {
_atlas.CreateAtlas(name, size); _atlas.CreateAtlas(name, size);
MA_CheckTextureAtlas(_atlas); MA_CheckTextureAtlas(_atlas);
CreateFolder(SAVE_ASSET_PATH); CreateFolder(SAVE_ASSET_PATH);
AssetDatabase.CreateAsset(_atlas, SAVE_ASSET_PATH + name + ".asset"); AssetDatabase.CreateAsset(_atlas, SAVE_ASSET_PATH + name + ".asset");
AssetDatabase.SaveAssets(); AssetDatabase.SaveAssets();
AssetDatabase.Refresh(); AssetDatabase.Refresh();
return _atlas; return _atlas;
} }
else else
{ {
return null; return null;
} }
} }
public static MA_TextureAtlasserProAtlas LoadTextureAtlas() public static MA_TextureAtlasserProAtlas LoadTextureAtlas()
{ {
MA_TextureAtlasserProAtlas _atlas = null; MA_TextureAtlasserProAtlas _atlas = null;
string absPath = EditorUtility.OpenFilePanel("Select Texture Atlas", LOAD_ASSET_PATH, ""); string absPath = EditorUtility.OpenFilePanel("Select Texture Atlas", LOAD_ASSET_PATH, "");
if(absPath.StartsWith(Application.dataPath)) if (absPath.StartsWith(Application.dataPath))
{ {
string relPath = absPath.Substring(Application.dataPath.Length - "Assets".Length); string relPath = absPath.Substring(Application.dataPath.Length - "Assets".Length);
_atlas = AssetDatabase.LoadAssetAtPath(relPath, typeof(MA_TextureAtlasserProAtlas)) as MA_TextureAtlasserProAtlas; _atlas = AssetDatabase.LoadAssetAtPath(relPath, typeof(MA_TextureAtlasserProAtlas)) as MA_TextureAtlasserProAtlas;
MA_CheckTextureAtlas(_atlas); MA_CheckTextureAtlas(_atlas);
if(_atlas) if (_atlas)
{ {
EditorPrefs.SetString("AtlasPath", null); EditorPrefs.SetString("AtlasPath", null);
} }
} }
if(_atlas != null) if (_atlas != null)
{ {
if(_atlas.selectedTextureQuad != null) if (_atlas.selectedTextureQuad != null)
{ {
_atlas.selectedTextureQuad.isSelected = false; _atlas.selectedTextureQuad.isSelected = false;
} }
_atlas.selectedTextureQuad = null; _atlas.selectedTextureQuad = null;
} }
return _atlas;
}
public static void MA_CheckTextureAtlas(MA_TextureAtlasserProAtlas atlas) return _atlas;
{ }
if(atlas.textureGroupRegistration == null)
{
atlas.textureGroupRegistration = new List<MA_TextureGroupRegistration>();
MA_TextureGroupRegistration groupRegistration = new MA_TextureGroupRegistration public static void MA_CheckTextureAtlas(MA_TextureAtlasserProAtlas atlas)
{ {
name = DEFAULT_TEXTURE_GROUP_NAME if (atlas.textureGroupRegistration == null)
}; {
atlas.textureGroupRegistration = new List<MA_TextureGroupRegistration>();
atlas.textureGroupRegistration.Add(groupRegistration); MA_TextureGroupRegistration groupRegistration = new MA_TextureGroupRegistration
} {
name = DEFAULT_TEXTURE_GROUP_NAME
};
if(atlas.textureQuads == null) atlas.textureGroupRegistration.Add(groupRegistration);
{ }
atlas.textureQuads = new List<MA_TextureAtlasserProQuad>();
}
else
{
bool _sameCount = true;
foreach (MA_TextureAtlasserProQuad q in atlas.textureQuads)
{
if(q.textureGroups.Count != atlas.textureGroupRegistration.Count)
{
_sameCount = false;
Debug.LogWarning("TextureAtlasser: " + q.name + " doesn't have the right amount of texture groups!");
}
}
if(_sameCount) if (atlas.textureQuads == null)
{ {
foreach (MA_TextureAtlasserProQuad q in atlas.textureQuads) atlas.textureQuads = new List<MA_TextureAtlasserProQuad>();
{ }
for (int i = 0; i < atlas.textureQuads.Count; i++) else
{ {
for (int j = 0; j < atlas.textureGroupRegistration.Count; j++) bool _sameCount = true;
{ foreach (MA_TextureAtlasserProQuad q in atlas.textureQuads)
if(atlas.textureQuads[i].textureGroups[j].name != atlas.textureGroupRegistration[j].name) {
{ if (q.textureGroups.Count != atlas.textureGroupRegistration.Count)
Debug.LogWarning("TextureAtlasser: " + q.name + " doesn't have the right texture group name!"); {
} _sameCount = false;
} Debug.LogWarning("TextureAtlasser: " + q.name + " doesn't have the right amount of texture groups!");
} }
} }
}
}
if(atlas.exportSettings == null) if (_sameCount)
{
foreach (MA_TextureAtlasserProQuad q in atlas.textureQuads)
{
for (int i = 0; i < atlas.textureQuads.Count; i++)
{
for (int j = 0; j < atlas.textureGroupRegistration.Count; j++)
{
if (atlas.textureQuads[i].textureGroups[j].name != atlas.textureGroupRegistration[j].name)
{
Debug.LogWarning("TextureAtlasser: " + q.name + " doesn't have the right texture group name!");
}
}
}
}
}
}
if (atlas.exportSettings == null)
{ {
atlas.exportSettings = LoadExportSettings(); atlas.exportSettings = LoadExportSettings();
} }
} }
public static MA_TextureAtlasserProQuad CreateTextureQuad(MA_TextureAtlasserProAtlas atlas, string name, Rect rect, bool focus = true) public static MA_TextureAtlasserProQuad CreateTextureQuad(MA_TextureAtlasserProAtlas atlas, string name, Rect rect, bool focus = true)
{ {
if(atlas != null) if (atlas != null)
{ {
//Create new list if we haven't one already //Create new list if we haven't one already
if(atlas.textureQuads == null) if (atlas.textureQuads == null)
{ {
atlas.textureQuads = new List<MA_TextureAtlasserProQuad>(); atlas.textureQuads = new List<MA_TextureAtlasserProQuad>();
} }
//Create new quad //Create new quad
MA_TextureAtlasserProQuad _quad = ScriptableObject.CreateInstance<MA_TextureAtlasserProQuad>(); MA_TextureAtlasserProQuad _quad = ScriptableObject.CreateInstance<MA_TextureAtlasserProQuad>();
//Add quad to asset //Add quad to asset
if(_quad != null) if (_quad != null)
{ {
//Set quad settings //Set quad settings
_quad.name = name; _quad.name = name;
_quad.rect = rect; _quad.rect = rect;
SetTextureGroups(atlas, _quad); SetTextureGroups(atlas, _quad);
atlas.textureQuads.Add(_quad);
AssetDatabase.AddObjectToAsset(_quad, atlas); atlas.textureQuads.Add(_quad);
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
if(focus) AssetDatabase.AddObjectToAsset(_quad, atlas);
{ AssetDatabase.SaveAssets();
atlas.selectedTextureQuad = atlas.textureQuads[atlas.textureQuads.Count - 1]; AssetDatabase.Refresh();
}
return _quad; if (focus)
} {
else atlas.selectedTextureQuad = atlas.textureQuads[atlas.textureQuads.Count - 1];
{ }
Debug.LogError("CreateTextureQuad Failed: _TextureQuad");
}
}
else
{
Debug.LogError("CreateTextureQuad Failed: textureAtlas");
}
return null; return _quad;
} }
else
{
Debug.LogError("CreateTextureQuad Failed: _TextureQuad");
}
}
else
{
Debug.LogError("CreateTextureQuad Failed: textureAtlas");
}
public static void RemoveTextureQuad(MA_TextureAtlasserProAtlas atlas, bool focus = true) return null;
{ }
if(atlas != null && atlas.selectedTextureQuad != null)
{
int _index = atlas.textureQuads.IndexOf(atlas.selectedTextureQuad);
atlas.textureQuads.RemoveAt(_index); public static void RemoveTextureQuad(MA_TextureAtlasserProAtlas atlas, bool focus = true)
Object.DestroyImmediate(atlas.selectedTextureQuad, true); {
AssetDatabase.SaveAssets(); if (atlas != null && atlas.selectedTextureQuad != null)
AssetDatabase.Refresh(); {
int _index = atlas.textureQuads.IndexOf(atlas.selectedTextureQuad);
if (focus && atlas.textureQuads.Count > 0) atlas.textureQuads.RemoveAt(_index);
{ Object.DestroyImmediate(atlas.selectedTextureQuad, true);
_index = Mathf.Clamp(_index, 0, atlas.textureQuads.Count - 1); AssetDatabase.SaveAssets();
atlas.selectedTextureQuad = atlas.textureQuads[_index]; AssetDatabase.Refresh();
}
}
}
public static void DuplicateTextureQuad(MA_TextureAtlasserProAtlas atlas, bool focus = true, bool copyData = false, string namePrefix = "new ") if (focus && atlas.textureQuads.Count > 0)
{ {
if(atlas != null && atlas.selectedTextureQuad != null) _index = Mathf.Clamp(_index, 0, atlas.textureQuads.Count - 1);
{ atlas.selectedTextureQuad = atlas.textureQuads[_index];
MA_TextureAtlasserProQuad q = CreateTextureQuad(atlas, namePrefix + atlas.selectedTextureQuad.name, atlas.selectedTextureQuad.rect, false); }
}
}
if (copyData) public static void DuplicateTextureQuad(MA_TextureAtlasserProAtlas atlas, bool focus = true, bool copyData = false, string namePrefix = "new ")
{ {
q.meshes = new List<Mesh>(); if (atlas != null && atlas.selectedTextureQuad != null)
for (int i = 0; i < atlas.selectedTextureQuad.meshes.Count; i++) {
{ MA_TextureAtlasserProQuad q = CreateTextureQuad(atlas, namePrefix + atlas.selectedTextureQuad.name, atlas.selectedTextureQuad.rect, false);
q.meshes.Add(atlas.selectedTextureQuad.meshes[i]);
}
for (int i = 0; i < atlas.selectedTextureQuad.textureGroups.Count; i++) if (copyData)
{ {
q.textureGroups[i].texture = atlas.selectedTextureQuad.textureGroups[i].texture; q.meshes = new List<Mesh>();
} for (int i = 0; i < atlas.selectedTextureQuad.meshes.Count; i++)
} {
q.meshes.Add(atlas.selectedTextureQuad.meshes[i]);
}
if(focus) for (int i = 0; i < atlas.selectedTextureQuad.textureGroups.Count; i++)
{ {
atlas.selectedTextureQuad = q; q.textureGroups[i].texture = atlas.selectedTextureQuad.textureGroups[i].texture;
} }
}
AssetDatabase.SaveAssets(); if (focus)
AssetDatabase.Refresh(); {
} atlas.selectedTextureQuad = q;
} }
public static void SetTextureGroups(MA_TextureAtlasserProAtlas atlas, MA_TextureAtlasserProQuad quad) AssetDatabase.SaveAssets();
{ AssetDatabase.Refresh();
if(quad.textureGroups == null) }
{ }
quad.textureGroups = new List<MA_TextureGroup>();
}
//Add texture groups public static void SetTextureGroups(MA_TextureAtlasserProAtlas atlas, MA_TextureAtlasserProQuad quad)
foreach (MA_TextureGroupRegistration tgr in atlas.textureGroupRegistration) {
{ if (quad.textureGroups == null)
MA_TextureGroup textureGroup = new MA_TextureGroup {
{ quad.textureGroups = new List<MA_TextureGroup>();
name = tgr.name }
};
quad.textureGroups.Add(textureGroup);
}
}
public static void CreateTextureGroup(MA_TextureAtlasserProAtlas atlas, string name) //Add texture groups
{ foreach (MA_TextureGroupRegistration tgr in atlas.textureGroupRegistration)
MA_TextureGroupRegistration _textureGroupRegistration = new MA_TextureGroupRegistration {
{ MA_TextureGroup textureGroup = new MA_TextureGroup
name = name {
}; name = tgr.name
atlas.textureGroupRegistration.Add(_textureGroupRegistration); };
quad.textureGroups.Add(textureGroup);
}
}
foreach (MA_TextureAtlasserProQuad q in atlas.textureQuads) public static void CreateTextureGroup(MA_TextureAtlasserProAtlas atlas, string name)
{ {
MA_TextureGroup _textureGroup = new MA_TextureGroup MA_TextureGroupRegistration _textureGroupRegistration = new MA_TextureGroupRegistration
{ {
name = name name = name
}; };
q.textureGroups.Add(_textureGroup); atlas.textureGroupRegistration.Add(_textureGroupRegistration);
}
}
public static void RemoveTextureGroup(MA_TextureAtlasserProAtlas atlas, int index) foreach (MA_TextureAtlasserProQuad q in atlas.textureQuads)
{ {
atlas.textureGroupRegistration.RemoveAt(index); MA_TextureGroup _textureGroup = new MA_TextureGroup
{
name = name
};
q.textureGroups.Add(_textureGroup);
}
}
foreach (MA_TextureAtlasserProQuad q in atlas.textureQuads) public static void RemoveTextureGroup(MA_TextureAtlasserProAtlas atlas, int index)
{ {
q.textureGroups.RemoveAt(index); atlas.textureGroupRegistration.RemoveAt(index);
}
}
public static void CloseWindow(MA_TextureAtlasserProWindow curWindow) foreach (MA_TextureAtlasserProQuad q in atlas.textureQuads)
{ {
if(curWindow == null) q.textureGroups.RemoveAt(index);
{ }
Debug.LogError("Closing window Failed: curWindow == null"); }
}
curWindow.Close();
}
public static bool IsPowerOfTwo(int value) public static void CloseWindow(MA_TextureAtlasserProWindow curWindow)
{ {
//While x is even and > 1 if (curWindow == null)
while (((value % 2) == 0) && value > 1) {
{ Debug.LogError("Closing window Failed: curWindow == null");
value /= 2; }
} curWindow.Close();
}
return (value == 1); public static bool IsPowerOfTwo(int value)
} {
//While x is even and > 1
while (((value % 2) == 0) && value > 1)
{
value /= 2;
}
return (value == 1);
}
public static void CreateFolder(string folderPath) public static void CreateFolder(string folderPath)
{ {
@ -391,7 +389,7 @@ namespace MA_TextureAtlasserPro
#region Export #region Export
public static string[] ExportAtlasModels(MA_TextureAtlasserProAtlas atlas, ModelExportSettings modelExportSettings, string material = null, 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) switch (modelExportSettings.modelFormat)
{ {
case ModelFormat.None: case ModelFormat.None:
break; break;
@ -457,13 +455,14 @@ namespace MA_TextureAtlasserPro
newMesh = MA_MeshUtils.MA_DuplicateMesh(quad.meshes[m]); newMesh = MA_MeshUtils.MA_DuplicateMesh(quad.meshes[m]);
//Remap UV's //Remap UV's
newMesh = MA_MeshUtils.MA_UVReMap(newMesh, atlas.textureAtlasSize, quad.guiRect, modelExportSettings.uvChannel, modelExportSettings.uvFlipY, modelExportSettings.uvWrap); newMesh = MA_MeshUtils.MA_UVReMap(newMesh, atlas.textureAtlasSize, quad.guiRect, modelExportSettings.uvChannel, modelExportSettings.uvFlipY, modelExportSettings.uvWrap);
//Save it //Set name
string meshName = string.IsNullOrEmpty(quad.name) ? "" : quad.name + "-"; string meshName = string.IsNullOrEmpty(quad.name) ? "" : quad.name + "-";
meshName += quad.meshes[m].name; meshName += quad.meshes[m].name;
int n = m + 1; int n = m + 1;
meshName += "_" + n.ToString("#000"); meshName += "_" + n.ToString("#000");
newMesh.name = meshName;
string asset = MA_MeshUtils.MA_SaveMeshPrefab(newMesh, meshName, savePath, material: material); //Save it
string asset = MA_MeshUtils.MA_SaveMeshPrefab(newMesh, meshName, savePath, materialPath: material);
assetPaths.Add(asset); assetPaths.Add(asset);
} }
} }
@ -473,8 +472,8 @@ namespace MA_TextureAtlasserPro
return assetPaths.ToArray(); return assetPaths.ToArray();
} }
private static string[] ExportAtlasObj(MA_TextureAtlasserProAtlas atlas, ModelExportSettings modelExportSettings, string savePath = EXPORT_ASSET_PATH) private static string[] ExportAtlasObj(MA_TextureAtlasserProAtlas atlas, ModelExportSettings modelExportSettings, string savePath = EXPORT_ASSET_PATH)
{ {
if (atlas == null || atlas.textureQuads == null) if (atlas == null || atlas.textureQuads == null)
return null; return null;
@ -509,27 +508,27 @@ namespace MA_TextureAtlasserPro
} }
return assetPaths.ToArray(); return assetPaths.ToArray();
} }
public static string[] 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) switch (textureExportSettings.textureFormat)
{ {
case TextureFormat.None: case TextureFormat.None:
break; break;
case TextureFormat.Png: case TextureFormat.Png:
return ExportAtlasPNG(atlas, textureExportSettings, savePath); return ExportAtlasPNG(atlas, textureExportSettings, savePath);
default: default:
break; break;
} }
return null; return null;
} }
private static string[] 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) if (atlas == null || atlas.textureQuads == null || atlas.textureGroupRegistration == null)
return null; return null;
string[] assetPaths = new string[atlas.textureGroupRegistration.Count]; string[] assetPaths = new string[atlas.textureGroupRegistration.Count];
@ -538,17 +537,17 @@ namespace MA_TextureAtlasserPro
//Foreach texture group //Foreach texture group
for (int i = 0; i < atlas.textureGroupRegistration.Count; i++) for (int i = 0; i < atlas.textureGroupRegistration.Count; i++)
{ {
//Create new Texture Atlas //Create new Texture Atlas
Texture2D newTexture = new Texture2D((int)atlas.textureAtlasSize.x, (int)atlas.textureAtlasSize.y) Texture2D newTexture = new Texture2D((int)atlas.textureAtlasSize.x, (int)atlas.textureAtlasSize.y)
{ {
name = atlas.name + "_" + atlas.textureGroupRegistration[i].name name = atlas.name + "_" + atlas.textureGroupRegistration[i].name
}; };
foreach (MA_TextureAtlasserProQuad q in atlas.textureQuads) foreach (MA_TextureAtlasserProQuad q in atlas.textureQuads)
{ {
if (q.textureGroups != null && q.textureGroups[i].texture != null) if (q.textureGroups != null && q.textureGroups[i].texture != null)
{ {
//Make temp copy //Make temp copy
string orginalTexturePath = AssetDatabase.GetAssetPath(q.textureGroups[i].texture); string orginalTexturePath = AssetDatabase.GetAssetPath(q.textureGroups[i].texture);
string orginalTextureExtension = System.IO.Path.GetExtension(orginalTexturePath); string orginalTextureExtension = System.IO.Path.GetExtension(orginalTexturePath);
@ -570,20 +569,20 @@ namespace MA_TextureAtlasserPro
//Create new texture part //Create new texture part
Texture2D newTexturePart = (Texture2D)MA_TextureUtils.ConvertToReadableTexture(tempCopy); Texture2D newTexturePart = (Texture2D)MA_TextureUtils.ConvertToReadableTexture(tempCopy);
//Scale it //Scale it
newTexturePart = newTexturePart.MA_Scale2D((int)q.guiRect.width, (int)q.guiRect.height, textureExportSettings.textureScaleMode); newTexturePart = newTexturePart.MA_Scale2D((int)q.guiRect.width, (int)q.guiRect.height, textureExportSettings.textureScaleMode);
//Add it //Add it
newTexture = newTexture.MA_Combine2D(newTexturePart, (int)q.guiRect.x, (int)q.guiRect.y); newTexture = newTexture.MA_Combine2D(newTexturePart, (int)q.guiRect.x, (int)q.guiRect.y);
//Delete temp copy //Delete temp copy
AssetDatabase.DeleteAsset(tempTextureImporter.assetPath); AssetDatabase.DeleteAsset(tempTextureImporter.assetPath);
} }
} }
//Save it //Save it
newTexture.MA_Save2D(newTexture.name, savePath); newTexture.MA_Save2D(newTexture.name, savePath);
assetPaths[i] = (savePath + newTexture.name + '.' + textureExportSettings.textureFormat.ToString()); assetPaths[i] = (savePath + newTexture.name + '.' + textureExportSettings.textureFormat.ToString());
@ -606,7 +605,7 @@ namespace MA_TextureAtlasserPro
default: default:
break; break;
} }
} }
//Delete temp folder //Delete temp folder
DeleteFolder(tempPath); DeleteFolder(tempPath);
@ -615,51 +614,51 @@ namespace MA_TextureAtlasserPro
AssetDatabase.Refresh(); AssetDatabase.Refresh();
return assetPaths; return assetPaths;
} }
private static void SetAtlasSpriteSettings(MA_TextureAtlasserProAtlas atlas, TextureExportSettings textureExportSettings, string savePath = EXPORT_ASSET_PATH) private static void SetAtlasSpriteSettings(MA_TextureAtlasserProAtlas atlas, TextureExportSettings textureExportSettings, string savePath = EXPORT_ASSET_PATH)
{ {
//Foreach texture group //Foreach texture group
for (int i = 0; i < atlas.textureGroupRegistration.Count; i++) for (int i = 0; i < atlas.textureGroupRegistration.Count; i++)
{ {
//Convert //Convert
string textureName = atlas.name + "_" + atlas.textureGroupRegistration[i].name + '.' + textureExportSettings.textureFormat.ToString(); string textureName = atlas.name + "_" + atlas.textureGroupRegistration[i].name + '.' + textureExportSettings.textureFormat.ToString();
TextureImporter textureImporter = (TextureImporter)AssetImporter.GetAtPath(savePath + textureName); TextureImporter textureImporter = (TextureImporter)AssetImporter.GetAtPath(savePath + textureName);
textureImporter.textureType = TextureImporterType.Sprite; textureImporter.textureType = TextureImporterType.Sprite;
textureImporter.alphaIsTransparency = true; textureImporter.alphaIsTransparency = true;
//Slice sprites. //Slice sprites.
if (textureExportSettings.textureType == TextureType.SpriteSliced) if (textureExportSettings.textureType == TextureType.SpriteSliced)
{ {
textureImporter.spriteImportMode = SpriteImportMode.None; //Reset it to update? textureImporter.spriteImportMode = SpriteImportMode.None; //Reset it to update?
textureImporter.spriteImportMode = SpriteImportMode.Multiple; textureImporter.spriteImportMode = SpriteImportMode.Multiple;
List<SpriteMetaData> spriteMetaData = new List<SpriteMetaData>(); List<SpriteMetaData> spriteMetaData = new List<SpriteMetaData>();
foreach (MA_TextureAtlasserProQuad q in atlas.textureQuads) foreach (MA_TextureAtlasserProQuad q in atlas.textureQuads)
{ {
if (q.textureGroups != null && q.textureGroups[i].texture != null) if (q.textureGroups != null && q.textureGroups[i].texture != null)
{ {
//Create new SpriteMetaData. //Create new SpriteMetaData.
SpriteMetaData smd = new SpriteMetaData SpriteMetaData smd = new SpriteMetaData
{ {
name = q.name, name = q.name,
rect = new Rect(q.guiRect.x, atlas.textureAtlasSize.y - q.guiRect.y - q.guiRect.height, q.guiRect.width, q.guiRect.height) rect = new Rect(q.guiRect.x, atlas.textureAtlasSize.y - q.guiRect.y - q.guiRect.height, q.guiRect.width, q.guiRect.height)
}; };
spriteMetaData.Add(smd); spriteMetaData.Add(smd);
} }
} }
textureImporter.spritesheet = spriteMetaData.ToArray(); textureImporter.spritesheet = spriteMetaData.ToArray();
} }
else else
{ {
textureImporter.spriteImportMode = SpriteImportMode.Single; textureImporter.spriteImportMode = SpriteImportMode.Single;
} }
textureImporter.SaveAndReimport(); textureImporter.SaveAndReimport();
} }
} }
public static string ExportAtlasMaterial(MA_TextureAtlasserProAtlas atlas, MaterialExportSettings materialExportSettings, string[] textures = null, string savePath = EXPORT_ASSET_PATH) public static string ExportAtlasMaterial(MA_TextureAtlasserProAtlas atlas, MaterialExportSettings materialExportSettings, string[] textures = null, string savePath = EXPORT_ASSET_PATH)
{ {
@ -676,7 +675,7 @@ namespace MA_TextureAtlasserPro
name = atlas.name name = atlas.name
}; };
if(textures != null) if (textures != null)
{ {
for (int i = 0; i < (int)Mathf.Min(materialExportSettings.shaderPropertyNames.Count, textures.Length); i++) for (int i = 0; i < (int)Mathf.Min(materialExportSettings.shaderPropertyNames.Count, textures.Length); i++)
{ {

View File

@ -15,91 +15,102 @@ using UnityEditor;
namespace MA_Mesh namespace MA_Mesh
{ {
public static class MA_MeshUtils public static class MA_MeshUtils
{ {
public static string MA_SaveMeshAsset(Mesh mesh, string meshName, string savePath) public static string MA_SaveMeshAsset(Mesh mesh, string savePath)
{ {
Mesh newMesh = mesh; if (string.IsNullOrEmpty(mesh.name))
{
mesh.name = UnityEngine.Random.Range(11111, 99999).ToString();
}
if(meshName == "") string assetPath = savePath + mesh.name + ".asset";
{
newMesh.name = mesh.name;
}
else
{
newMesh.name = meshName;
}
string assetPath = savePath + newMesh.name + ".asset"; AssetDatabase.CreateAsset(mesh, assetPath);
AssetDatabase.CreateAsset(newMesh, assetPath);
AssetDatabase.SaveAssets(); AssetDatabase.SaveAssets();
return assetPath; return assetPath;
} }
public static string MA_SaveMeshPrefab(Mesh mesh, string meshName, string savePath, string material) public static string MA_SaveMeshPrefab(Mesh mesh, string prefabName, string savePath, string materialPath)
{ {
string assetPath = ""; string assetPath = null;
if (meshName == "") string meshAssetPath = MA_SaveMeshAsset(mesh, savePath);
{ Mesh meshAsset = AssetDatabase.LoadAssetAtPath<Mesh>(meshAssetPath);
meshName = mesh.name;
}
string meshPath = MA_SaveMeshAsset(mesh, meshName, savePath); if (meshAsset != null)
Mesh curMesh = AssetDatabase.LoadAssetAtPath<Mesh>(meshPath);
if (curMesh != null)
{ {
GameObject gameObject = new GameObject GameObject gameObject = new GameObject
{ {
name = meshName name = prefabName
}; };
gameObject.AddComponent<MeshFilter>().mesh = curMesh; gameObject.AddComponent<MeshFilter>().mesh = meshAsset;
gameObject.AddComponent<MeshRenderer>(); gameObject.AddComponent<MeshRenderer>();
Material curMaterial = AssetDatabase.LoadAssetAtPath<Material>(material); Material curMaterial = AssetDatabase.LoadAssetAtPath<Material>(materialPath);
if (curMaterial != null) if (curMaterial != null)
{ {
gameObject.GetComponent<MeshRenderer>().material = curMaterial; gameObject.GetComponent<MeshRenderer>().material = curMaterial;
} }
assetPath = savePath + meshName + ".prefab"; if (string.IsNullOrEmpty(prefabName))
{
prefabName = UnityEngine.Random.Range(11111, 99999).ToString();
}
assetPath = savePath + prefabName + ".prefab";
#if UNITY_2018_4_OR_NEWER
PrefabUtility.SaveAsPrefabAsset(gameObject, assetPath); PrefabUtility.SaveAsPrefabAsset(gameObject, assetPath);
#else
GameObject go = AssetDatabase.LoadAssetAtPath<GameObject>(assetPath);
if (go != null)
{
PrefabUtility.ReplacePrefab(gameObject, go, ReplacePrefabOptions.ReplaceNameBased);
}
else
{
PrefabUtility.CreatePrefab(assetPath, gameObject, ReplacePrefabOptions.ReplaceNameBased);
}
#endif
UnityEngine.GameObject.DestroyImmediate(gameObject); UnityEngine.GameObject.DestroyImmediate(gameObject);
} }
return assetPath; return assetPath;
} }
public static Mesh MA_DuplicateMesh(Mesh mesh) public static Mesh MA_DuplicateMesh(Mesh mesh)
{ {
Mesh newMesh = new Mesh Mesh newMesh = new Mesh
{ {
name = mesh.name, name = mesh.name,
bounds = mesh.bounds, bounds = mesh.bounds,
subMeshCount = mesh.subMeshCount subMeshCount = mesh.subMeshCount
}; };
newMesh.SetVertices(new List<Vector3>(mesh.vertices)); newMesh.SetVertices(new List<Vector3>(mesh.vertices));
for (int i = 0; i < mesh.subMeshCount; i++) for (int i = 0; i < mesh.subMeshCount; i++)
{ {
newMesh.SetTriangles(mesh.GetTriangles(i), i); newMesh.SetTriangles(mesh.GetTriangles(i), i);
} }
newMesh.SetNormals(new List<Vector3>(mesh.normals)); newMesh.SetNormals(new List<Vector3>(mesh.normals));
newMesh.SetUVs(0, new List<Vector2>(mesh.uv)); newMesh.SetUVs(0, new List<Vector2>(mesh.uv));
newMesh.SetTangents(new List<Vector4>(mesh.tangents)); newMesh.SetTangents(new List<Vector4>(mesh.tangents));
newMesh.SetColors(new List<Color>(mesh.colors)); newMesh.SetColors(new List<Color>(mesh.colors));
return newMesh; return newMesh;
} }
public static Mesh MA_ReMapUV(this Mesh mesh, Vector2 atlasSize, Vector2 textureSize, Vector2 texturePosition, int uvChannel = 0) public static Mesh MA_ReMapUV(this Mesh mesh, Vector2 atlasSize, Vector2 textureSize, Vector2 texturePosition, int uvChannel = 0)
{ {
/* /*
0 1 0 1
512 x 512 512 x 512
@ -109,154 +120,154 @@ namespace MA_Mesh
+ pos + pos
*/ */
List<Vector2> uvs = new List<Vector2>(); List<Vector2> uvs = new List<Vector2>();
//Get UV's
mesh.GetUVs(uvChannel, uvs);
foreach (Vector2 uvCordinate in uvs) //Get UV's
{ mesh.GetUVs(uvChannel, uvs);
float x = (uvCordinate.x / atlasSize.x * textureSize.x) + texturePosition.x;
float y = (uvCordinate.y / atlasSize.y * textureSize.y) + texturePosition.y;
uvCordinate.Set(x, y);
}
mesh.SetUVs(uvChannel, uvs); foreach (Vector2 uvCordinate in uvs)
{
float x = (uvCordinate.x / atlasSize.x * textureSize.x) + texturePosition.x;
float y = (uvCordinate.y / atlasSize.y * textureSize.y) + texturePosition.y;
uvCordinate.Set(x, y);
}
return mesh; mesh.SetUVs(uvChannel, uvs);
}
public static Mesh MA_UVReMap(this Mesh mesh, Vector2 atlasSize, Rect textureRect, int uvChannel = 0, bool flipY = true, bool wrap = true) return mesh;
{ }
//Get UV's
List<Vector2> uvs = new List<Vector2>();
mesh.GetUVs(uvChannel, uvs);
//Min and max bounds in 0-1 space. public static Mesh MA_UVReMap(this Mesh mesh, Vector2 atlasSize, Rect textureRect, int uvChannel = 0, bool flipY = true, bool wrap = true)
float xMin, xMax, yMin, yMax; {
xMin = (1f / atlasSize.x * textureRect.width); //Get UV's
xMax = (1f / atlasSize.x * textureRect.x); List<Vector2> uvs = new List<Vector2>();
yMin = (1f / atlasSize.y * textureRect.height); mesh.GetUVs(uvChannel, uvs);
//Flip uv's if needed. //Min and max bounds in 0-1 space.
if (flipY) float xMin, xMax, yMin, yMax;
{ xMin = (1f / atlasSize.x * textureRect.width);
yMax = (1f / atlasSize.y * (atlasSize.y - textureRect.height - textureRect.y)); xMax = (1f / atlasSize.x * textureRect.x);
} yMin = (1f / atlasSize.y * textureRect.height);
else
{
yMax = (1f / atlasSize.y * textureRect.y);
}
for (int i = 0; i < uvs.Count; i++) //Flip uv's if needed.
{ if (flipY)
float newX = uvs[i].x * xMin + xMax; {
float newY = uvs[i].y * yMin + yMax; yMax = (1f / atlasSize.y * (atlasSize.y - textureRect.height - textureRect.y));
}
else
{
yMax = (1f / atlasSize.y * textureRect.y);
}
//Wrap the verts outside of the uv space around back into the uv space. for (int i = 0; i < uvs.Count; i++)
if (wrap) {
{ float newX = uvs[i].x * xMin + xMax;
newX = Wrap(newX, xMax, xMin + xMax); float newY = uvs[i].y * yMin + yMax;
newY = Wrap(newY, yMax, yMin + yMax);
}
uvs[i] = new Vector2(newX, newY); //Wrap the verts outside of the uv space around back into the uv space.
} if (wrap)
{
newX = Wrap(newX, xMax, xMin + xMax);
newY = Wrap(newY, yMax, yMin + yMax);
}
mesh.SetUVs(uvChannel, uvs); uvs[i] = new Vector2(newX, newY);
}
return mesh; mesh.SetUVs(uvChannel, uvs);
}
public static float Wrap(float val, float min, float max) return mesh;
{ }
val -= (float)Math.Round((val - min) / (max - min)) * (max - min);
if (val < min)
val = val + max - min;
return val;
}
//Start http://wiki.unity3d.com/index.php?title=ObjExporter public static float Wrap(float val, float min, float max)
public static string MeshToString(Mesh mesh) {
{ val -= (float)Math.Round((val - min) / (max - min)) * (max - min);
int vertexOffset = 0; if (val < min)
int normalOffset = 0; val = val + max - min;
int uvOffset = 0; return val;
}
Material material = new Material(Shader.Find("Standard")); //Start http://wiki.unity3d.com/index.php?title=ObjExporter
public static string MeshToString(Mesh mesh)
StringBuilder sb = new StringBuilder(); {
int vertexOffset = 0;
sb.Append("g ").Append(mesh.name).Append("\n"); int normalOffset = 0;
int uvOffset = 0;
foreach(Vector3 v in mesh.vertices) Material material = new Material(Shader.Find("Standard"));
{
//This is sort of ugly - inverting x-component since we're in
//a different coordinate system than "everyone" is "used to".
sb.Append(string.Format("v {0} {1} {2}\n", -v.x, v.y, v.z));
}
sb.Append("\n"); StringBuilder sb = new StringBuilder();
foreach(Vector3 v in mesh.normals) sb.Append("g ").Append(mesh.name).Append("\n");
{
sb.Append(string.Format("vn {0} {1} {2}\n", -v.x, v.y, v.z));
}
sb.Append("\n"); foreach (Vector3 v in mesh.vertices)
{
//This is sort of ugly - inverting x-component since we're in
//a different coordinate system than "everyone" is "used to".
sb.Append(string.Format("v {0} {1} {2}\n", -v.x, v.y, v.z));
}
foreach(Vector3 v in mesh.uv) sb.Append("\n");
{
sb.Append(string.Format("vt {0} {1}\n", v.x, v.y));
}
for (int m = 0 ; m < mesh.subMeshCount; m++) foreach (Vector3 v in mesh.normals)
{ {
sb.Append("\n"); sb.Append(string.Format("vn {0} {1} {2}\n", -v.x, v.y, v.z));
sb.Append("usemtl ").Append(material.name + m).Append("\n"); }
sb.Append("usemap ").Append(material.name + m).Append("\n");
// int[] triangles = mesh.GetTriangles(m);
// 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));
// }
int[] triangles = mesh.GetTriangles(m); sb.Append("\n");
for (int i = 0; i < triangles.Length; i += 3)
{
//Because we inverted the x-component, we also needed to alter the triangle winding.
sb.Append(string.Format("f {1}/{1}/{1} {0}/{0}/{0} {2}/{2}/{2}\n", triangles[i]+ 1 + vertexOffset, triangles[i + 1] + 1 + normalOffset, triangles[i +2 ] + 1 + uvOffset));
}
}
//vertexOffset += mesh.vertices.Length; foreach (Vector3 v in mesh.uv)
//normalOffset += mesh.normals.Length; {
//uvOffset += mesh.uv.Length; sb.Append(string.Format("vt {0} {1}\n", v.x, v.y));
}
return sb.ToString(); for (int m = 0; m < mesh.subMeshCount; m++)
} {
sb.Append("\n");
public static string MeshToFile(Mesh mesh, string filename, string savePath) sb.Append("usemtl ").Append(material.name + m).Append("\n");
{ sb.Append("usemap ").Append(material.name + m).Append("\n");
// int[] triangles = mesh.GetTriangles(m);
// 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));
// }
int[] triangles = mesh.GetTriangles(m);
for (int i = 0; i < triangles.Length; i += 3)
{
//Because we inverted the x-component, we also needed to alter the triangle winding.
sb.Append(string.Format("f {1}/{1}/{1} {0}/{0}/{0} {2}/{2}/{2}\n", triangles[i] + 1 + vertexOffset, triangles[i + 1] + 1 + normalOffset, triangles[i + 2] + 1 + uvOffset));
}
}
//vertexOffset += mesh.vertices.Length;
//normalOffset += mesh.normals.Length;
//uvOffset += mesh.uv.Length;
return sb.ToString();
}
public static string MeshToFile(Mesh mesh, string filename, string savePath)
{
string assetPath = savePath + filename + ".obj"; string assetPath = savePath + filename + ".obj";
using (StreamWriter sw = new StreamWriter(assetPath)) using (StreamWriter sw = new StreamWriter(assetPath))
{ {
sw.Write(MeshToString(mesh)); sw.Write(MeshToString(mesh));
} }
AssetDatabase.Refresh(); AssetDatabase.Refresh();
return assetPath; return assetPath;
} }
//End //End
} }
//struct ObjMaterial //struct ObjMaterial
//{ //{
// public string name; // public string name;
// public string textureName; // public string textureName;
//} //}
} }
#endif #endif

View File

@ -1,7 +1,12 @@
{ {
"dependencies": { "dependencies": {
"com.unity.package-manager-ui": "2.1.2", "com.unity.2d.sprite": "1.0.0",
"com.unity.ext.nunit": "1.0.0",
"com.unity.package-manager-ui": "2.2.0",
"com.unity.test-framework": "1.0.13",
"com.unity.ugui": "1.0.0",
"com.unity.modules.ai": "1.0.0", "com.unity.modules.ai": "1.0.0",
"com.unity.modules.androidjni": "1.0.0",
"com.unity.modules.animation": "1.0.0", "com.unity.modules.animation": "1.0.0",
"com.unity.modules.assetbundle": "1.0.0", "com.unity.modules.assetbundle": "1.0.0",
"com.unity.modules.audio": "1.0.0", "com.unity.modules.audio": "1.0.0",

View File

@ -1,2 +1,2 @@
m_EditorVersion: 2019.1.10f1 m_EditorVersion: 2019.2.13f1
m_EditorVersionWithRevision: 2019.1.10f1 (f007ed779b7a) m_EditorVersionWithRevision: 2019.2.13f1 (e20f6c7e5017)