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,8 +8,6 @@ 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/";
@ -26,7 +24,7 @@ namespace MA_TextureAtlasserPro
{ {
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");
@ -92,7 +90,7 @@ namespace MA_TextureAtlasserPro
{ {
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);
@ -115,22 +113,22 @@ namespace MA_TextureAtlasserPro
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;
} }
@ -142,7 +140,7 @@ namespace MA_TextureAtlasserPro
public static void MA_CheckTextureAtlas(MA_TextureAtlasserProAtlas atlas) public static void MA_CheckTextureAtlas(MA_TextureAtlasserProAtlas atlas)
{ {
if(atlas.textureGroupRegistration == null) if (atlas.textureGroupRegistration == null)
{ {
atlas.textureGroupRegistration = new List<MA_TextureGroupRegistration>(); atlas.textureGroupRegistration = new List<MA_TextureGroupRegistration>();
@ -154,7 +152,7 @@ namespace MA_TextureAtlasserPro
atlas.textureGroupRegistration.Add(groupRegistration); atlas.textureGroupRegistration.Add(groupRegistration);
} }
if(atlas.textureQuads == null) if (atlas.textureQuads == null)
{ {
atlas.textureQuads = new List<MA_TextureAtlasserProQuad>(); atlas.textureQuads = new List<MA_TextureAtlasserProQuad>();
} }
@ -163,14 +161,14 @@ namespace MA_TextureAtlasserPro
bool _sameCount = true; bool _sameCount = true;
foreach (MA_TextureAtlasserProQuad q in atlas.textureQuads) foreach (MA_TextureAtlasserProQuad q in atlas.textureQuads)
{ {
if(q.textureGroups.Count != atlas.textureGroupRegistration.Count) if (q.textureGroups.Count != atlas.textureGroupRegistration.Count)
{ {
_sameCount = false; _sameCount = false;
Debug.LogWarning("TextureAtlasser: " + q.name + " doesn't have the right amount of texture groups!"); Debug.LogWarning("TextureAtlasser: " + q.name + " doesn't have the right amount of texture groups!");
} }
} }
if(_sameCount) if (_sameCount)
{ {
foreach (MA_TextureAtlasserProQuad q in atlas.textureQuads) foreach (MA_TextureAtlasserProQuad q in atlas.textureQuads)
{ {
@ -178,7 +176,7 @@ namespace MA_TextureAtlasserPro
{ {
for (int j = 0; j < atlas.textureGroupRegistration.Count; j++) for (int j = 0; j < atlas.textureGroupRegistration.Count; j++)
{ {
if(atlas.textureQuads[i].textureGroups[j].name != atlas.textureGroupRegistration[j].name) if (atlas.textureQuads[i].textureGroups[j].name != atlas.textureGroupRegistration[j].name)
{ {
Debug.LogWarning("TextureAtlasser: " + q.name + " doesn't have the right texture group name!"); Debug.LogWarning("TextureAtlasser: " + q.name + " doesn't have the right texture group name!");
} }
@ -188,7 +186,7 @@ namespace MA_TextureAtlasserPro
} }
} }
if(atlas.exportSettings == null) if (atlas.exportSettings == null)
{ {
atlas.exportSettings = LoadExportSettings(); atlas.exportSettings = LoadExportSettings();
} }
@ -196,10 +194,10 @@ namespace MA_TextureAtlasserPro
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>();
} }
@ -208,7 +206,7 @@ namespace MA_TextureAtlasserPro
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;
@ -222,7 +220,7 @@ namespace MA_TextureAtlasserPro
AssetDatabase.SaveAssets(); AssetDatabase.SaveAssets();
AssetDatabase.Refresh(); AssetDatabase.Refresh();
if(focus) if (focus)
{ {
atlas.selectedTextureQuad = atlas.textureQuads[atlas.textureQuads.Count - 1]; atlas.selectedTextureQuad = atlas.textureQuads[atlas.textureQuads.Count - 1];
} }
@ -244,7 +242,7 @@ namespace MA_TextureAtlasserPro
public static void RemoveTextureQuad(MA_TextureAtlasserProAtlas atlas, bool focus = true) public static void RemoveTextureQuad(MA_TextureAtlasserProAtlas atlas, bool focus = true)
{ {
if(atlas != null && atlas.selectedTextureQuad != null) if (atlas != null && atlas.selectedTextureQuad != null)
{ {
int _index = atlas.textureQuads.IndexOf(atlas.selectedTextureQuad); int _index = atlas.textureQuads.IndexOf(atlas.selectedTextureQuad);
@ -263,7 +261,7 @@ namespace MA_TextureAtlasserPro
public static void DuplicateTextureQuad(MA_TextureAtlasserProAtlas atlas, bool focus = true, bool copyData = false, string namePrefix = "new ") public static void DuplicateTextureQuad(MA_TextureAtlasserProAtlas atlas, bool focus = true, bool copyData = false, string namePrefix = "new ")
{ {
if(atlas != null && atlas.selectedTextureQuad != null) if (atlas != null && atlas.selectedTextureQuad != null)
{ {
MA_TextureAtlasserProQuad q = CreateTextureQuad(atlas, namePrefix + atlas.selectedTextureQuad.name, atlas.selectedTextureQuad.rect, false); MA_TextureAtlasserProQuad q = CreateTextureQuad(atlas, namePrefix + atlas.selectedTextureQuad.name, atlas.selectedTextureQuad.rect, false);
@ -281,7 +279,7 @@ namespace MA_TextureAtlasserPro
} }
} }
if(focus) if (focus)
{ {
atlas.selectedTextureQuad = q; atlas.selectedTextureQuad = q;
} }
@ -293,7 +291,7 @@ namespace MA_TextureAtlasserPro
public static void SetTextureGroups(MA_TextureAtlasserProAtlas atlas, MA_TextureAtlasserProQuad quad) public static void SetTextureGroups(MA_TextureAtlasserProAtlas atlas, MA_TextureAtlasserProQuad quad)
{ {
if(quad.textureGroups == null) if (quad.textureGroups == null)
{ {
quad.textureGroups = new List<MA_TextureGroup>(); quad.textureGroups = new List<MA_TextureGroup>();
} }
@ -339,7 +337,7 @@ namespace MA_TextureAtlasserPro
public static void CloseWindow(MA_TextureAtlasserProWindow curWindow) public static void CloseWindow(MA_TextureAtlasserProWindow curWindow)
{ {
if(curWindow == null) if (curWindow == null)
{ {
Debug.LogError("Closing window Failed: curWindow == null"); Debug.LogError("Closing window Failed: curWindow == null");
} }
@ -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);
} }
} }
@ -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

@ -17,58 +17,69 @@ 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))
if(meshName == "")
{ {
newMesh.name = mesh.name; mesh.name = UnityEngine.Random.Range(11111, 99999).ToString();
}
else
{
newMesh.name = meshName;
} }
string assetPath = savePath + newMesh.name + ".asset"; string assetPath = savePath + mesh.name + ".asset";
AssetDatabase.CreateAsset(newMesh, assetPath); AssetDatabase.CreateAsset(mesh, 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);
} }
@ -189,7 +200,7 @@ namespace MA_Mesh
sb.Append("g ").Append(mesh.name).Append("\n"); sb.Append("g ").Append(mesh.name).Append("\n");
foreach(Vector3 v in mesh.vertices) foreach (Vector3 v in mesh.vertices)
{ {
//This is sort of ugly - inverting x-component since we're in //This is sort of ugly - inverting x-component since we're in
//a different coordinate system than "everyone" is "used to". //a different coordinate system than "everyone" is "used to".
@ -198,19 +209,19 @@ namespace MA_Mesh
sb.Append("\n"); sb.Append("\n");
foreach(Vector3 v in mesh.normals) foreach (Vector3 v in mesh.normals)
{ {
sb.Append(string.Format("vn {0} {1} {2}\n", -v.x, v.y, v.z)); sb.Append(string.Format("vn {0} {1} {2}\n", -v.x, v.y, v.z));
} }
sb.Append("\n"); sb.Append("\n");
foreach(Vector3 v in mesh.uv) foreach (Vector3 v in mesh.uv)
{ {
sb.Append(string.Format("vt {0} {1}\n", v.x, v.y)); sb.Append(string.Format("vt {0} {1}\n", v.x, v.y));
} }
for (int m = 0 ; m < mesh.subMeshCount; m++) for (int m = 0; m < mesh.subMeshCount; m++)
{ {
sb.Append("\n"); sb.Append("\n");
sb.Append("usemtl ").Append(material.name + m).Append("\n"); sb.Append("usemtl ").Append(material.name + m).Append("\n");
@ -226,7 +237,7 @@ namespace MA_Mesh
for (int i = 0; i < triangles.Length; i += 3) for (int i = 0; i < triangles.Length; i += 3)
{ {
//Because we inverted the x-component, we also needed to alter the triangle winding. //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)); 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));
} }
} }

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)