From 8ff2db7e87114ec7aa1a2b001455f8e11f2f239e Mon Sep 17 00:00:00 2001 From: max Date: Mon, 20 Apr 2020 22:30:08 +0200 Subject: [PATCH] Model groups. Added model group support, you can now have multiple meshes in one export. Removed OBJ and mesh replace export options. Mesh replace didn't work, might get added again in the feature. OBJ needs to be rewritten as well to support the multiple meshes, and Unity now has model export options in engine. Version 1.8.0+ is now only supports Unity2018.3+. --- .../Scripts/Data/MA_ModelGroup.cs | 15 + .../Scripts/Data/MA_ModelGroup.cs.meta | 11 + .../Data/MA_TextureAtlasserProAtlas.cs | 2 +- .../MA_TextureAtlasserProExportSettings.cs | 4 +- .../Scripts/Data/MA_TextureAtlasserProQuad.cs | 18 +- .../Data/MA_TextureAtlasserProSettings.cs | 1 - .../Utils/MA_TextureAtlasserProGuiLoader.cs | 6 +- .../Utils/MA_TextureAtlasserProUtils.cs | 210 +++++------ .../MA_TextureAtlasserProInspectorView.cs | 156 ++++---- .../Views/MA_TextureAtlasserProMenuView.cs | 2 +- .../Views/MA_TextureAtlasserProWorkView.cs | 4 +- .../MA_TextureAtlasserProExportWindow.cs | 39 +- .../MA_Utilities/MeshUtils/MA_MeshUtils.cs | 335 ++++++------------ .../MA_ToolBox/MA_Utilities/PrefabUtils.meta | 8 + .../PrefabUtils/MA_PrefabUtils.cs | 41 +++ .../PrefabUtils/MA_PrefabUtils.cs.meta | 11 + .../MA_ToolBox/MA_Utilities/StringUtils.meta | 8 + .../StringUtils/MA_StringUtils.cs | 28 ++ .../StringUtils/MA_StringUtils.cs.meta | 11 + README.md | 12 +- 20 files changed, 469 insertions(+), 453 deletions(-) create mode 100644 Assets/MA_ToolBox/MA_TextureAtlasserPro/Scripts/Data/MA_ModelGroup.cs create mode 100644 Assets/MA_ToolBox/MA_TextureAtlasserPro/Scripts/Data/MA_ModelGroup.cs.meta create mode 100644 Assets/MA_ToolBox/MA_Utilities/PrefabUtils.meta create mode 100644 Assets/MA_ToolBox/MA_Utilities/PrefabUtils/MA_PrefabUtils.cs create mode 100644 Assets/MA_ToolBox/MA_Utilities/PrefabUtils/MA_PrefabUtils.cs.meta create mode 100644 Assets/MA_ToolBox/MA_Utilities/StringUtils.meta create mode 100644 Assets/MA_ToolBox/MA_Utilities/StringUtils/MA_StringUtils.cs create mode 100644 Assets/MA_ToolBox/MA_Utilities/StringUtils/MA_StringUtils.cs.meta diff --git a/Assets/MA_ToolBox/MA_TextureAtlasserPro/Scripts/Data/MA_ModelGroup.cs b/Assets/MA_ToolBox/MA_TextureAtlasserPro/Scripts/Data/MA_ModelGroup.cs new file mode 100644 index 0000000..0d1e45c --- /dev/null +++ b/Assets/MA_ToolBox/MA_TextureAtlasserPro/Scripts/Data/MA_ModelGroup.cs @@ -0,0 +1,15 @@ +#if UNITY_EDITOR +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +namespace MA_TextureAtlasserPro +{ + [System.Serializable] + public class MA_ModelGroup + { + public string name = "Model"; + public List meshes = new List(); + } +} +#endif \ No newline at end of file diff --git a/Assets/MA_ToolBox/MA_TextureAtlasserPro/Scripts/Data/MA_ModelGroup.cs.meta b/Assets/MA_ToolBox/MA_TextureAtlasserPro/Scripts/Data/MA_ModelGroup.cs.meta new file mode 100644 index 0000000..5f32932 --- /dev/null +++ b/Assets/MA_ToolBox/MA_TextureAtlasserPro/Scripts/Data/MA_ModelGroup.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1f74ddc7d8c9c30429ec163b4fc801c4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MA_ToolBox/MA_TextureAtlasserPro/Scripts/Data/MA_TextureAtlasserProAtlas.cs b/Assets/MA_ToolBox/MA_TextureAtlasserPro/Scripts/Data/MA_TextureAtlasserProAtlas.cs index 657b215..454ffc3 100644 --- a/Assets/MA_ToolBox/MA_TextureAtlasserPro/Scripts/Data/MA_TextureAtlasserProAtlas.cs +++ b/Assets/MA_ToolBox/MA_TextureAtlasserPro/Scripts/Data/MA_TextureAtlasserProAtlas.cs @@ -15,7 +15,7 @@ namespace MA_TextureAtlasserPro public List textureQuads; public MA_TextureAtlasserProQuad selectedTextureQuad; private Rect editorWorkRect; - public bool showTextures = false; + public bool showTextures = true; public MA_TextureAtlasserProExportSettings exportSettings; //Data diff --git a/Assets/MA_ToolBox/MA_TextureAtlasserPro/Scripts/Data/MA_TextureAtlasserProExportSettings.cs b/Assets/MA_ToolBox/MA_TextureAtlasserPro/Scripts/Data/MA_TextureAtlasserProExportSettings.cs index 5303868..8ca9393 100644 --- a/Assets/MA_ToolBox/MA_TextureAtlasserPro/Scripts/Data/MA_TextureAtlasserProExportSettings.cs +++ b/Assets/MA_ToolBox/MA_TextureAtlasserPro/Scripts/Data/MA_TextureAtlasserProExportSettings.cs @@ -50,9 +50,7 @@ namespace MA_TextureAtlasserPro public enum ModelFormat { None, - UnityMeshPrefab, - ReplaceMesh, - Obj + UnityMeshPrefab } public enum TextureFormat diff --git a/Assets/MA_ToolBox/MA_TextureAtlasserPro/Scripts/Data/MA_TextureAtlasserProQuad.cs b/Assets/MA_ToolBox/MA_TextureAtlasserPro/Scripts/Data/MA_TextureAtlasserProQuad.cs index 327937c..5295c92 100644 --- a/Assets/MA_ToolBox/MA_TextureAtlasserPro/Scripts/Data/MA_TextureAtlasserProQuad.cs +++ b/Assets/MA_ToolBox/MA_TextureAtlasserPro/Scripts/Data/MA_TextureAtlasserProQuad.cs @@ -11,22 +11,28 @@ namespace MA_TextureAtlasserPro public class MA_TextureAtlasserProQuad : ScriptableObject { //Editor - public bool isSelected = false; //Is this thing selected - public Rect rect; //The internal rect - public Rect guiRect; //The visual clamped and snapped rect - public bool debugMode = false; //Are we debugging, for showing some other things (like handles) + [HideInInspector] + public bool isSelected = false; //Is this thing selected + public Rect rect; //The internal rect + [HideInInspector] + public Rect guiRect; //The visual clamped and snapped rect + [HideInInspector] + public bool debugMode = false; //Are we debugging, for showing some other things (like handles) - private bool isDragging = false; //Are we editing the pos or size + private bool isDragging = false; //Are we editing the pos or size private bool isDraggingRectHeigt = false; + [HideInInspector] public Rect dragRectHeight; private bool isDraggingRectWidth = false; + [HideInInspector] public Rect dragRectWidth; private bool isDraggingRectPos = false; + [HideInInspector] public Rect dragRectPos; //Data public List textureGroups; - public List meshes; + public List modelGroups; public void UpdateTextureQuad(Event e, Rect editorViewRect, Rect editorWorkRect, Vector2 zoomCoordsOrigin, bool useEvents, bool showTexture) { diff --git a/Assets/MA_ToolBox/MA_TextureAtlasserPro/Scripts/Data/MA_TextureAtlasserProSettings.cs b/Assets/MA_ToolBox/MA_TextureAtlasserPro/Scripts/Data/MA_TextureAtlasserProSettings.cs index fbecbf8..f5583d8 100644 --- a/Assets/MA_ToolBox/MA_TextureAtlasserPro/Scripts/Data/MA_TextureAtlasserProSettings.cs +++ b/Assets/MA_ToolBox/MA_TextureAtlasserPro/Scripts/Data/MA_TextureAtlasserProSettings.cs @@ -23,7 +23,6 @@ namespace MA_TextureAtlasserPro public KeyCode zoomOutHotKey = KeyCode.Minus; [Header("Duplication:")] - public bool copySelectedQuadData = true; public string duplicatedQuadNamePrefix = "new "; [Header("Selection")] diff --git a/Assets/MA_ToolBox/MA_TextureAtlasserPro/Scripts/Editor/Utils/MA_TextureAtlasserProGuiLoader.cs b/Assets/MA_ToolBox/MA_TextureAtlasserPro/Scripts/Editor/Utils/MA_TextureAtlasserProGuiLoader.cs index 6530c52..9dffdd8 100644 --- a/Assets/MA_ToolBox/MA_TextureAtlasserPro/Scripts/Editor/Utils/MA_TextureAtlasserProGuiLoader.cs +++ b/Assets/MA_ToolBox/MA_TextureAtlasserPro/Scripts/Editor/Utils/MA_TextureAtlasserProGuiLoader.cs @@ -96,9 +96,9 @@ namespace MA_TextureAtlasserPro exportAtlasGC.tooltip = "Opens the export window."; if (settings.useHotkeys) { - createQuadGC.tooltip = string.Format("({0} + {1}), Creates a new quad.", settings.modifierKey, settings.addQuadHotKey); - removeQuadGC.tooltip = string.Format("({0} + {1}), Removes the selected quad.", settings.modifierKey, settings.removeQuadHotKey); - duplicateQuadGC.tooltip = string.Format("({0} + {1}), Duplicates the selected quad.", settings.modifierKey, settings.duplicateHotKey); + createQuadGC.tooltip = string.Format("({0}+{1}), Creates a new quad.", settings.modifierKey, settings.addQuadHotKey); + removeQuadGC.tooltip = string.Format("({0}+{1}), Removes the selected quad.", settings.modifierKey, settings.removeQuadHotKey); + duplicateQuadGC.tooltip = string.Format("({0}+{1}), Duplicates the selected quad.", settings.modifierKey, settings.duplicateHotKey); } else { diff --git a/Assets/MA_ToolBox/MA_TextureAtlasserPro/Scripts/Editor/Utils/MA_TextureAtlasserProUtils.cs b/Assets/MA_ToolBox/MA_TextureAtlasserPro/Scripts/Editor/Utils/MA_TextureAtlasserProUtils.cs index ae98a04..d255614 100644 --- a/Assets/MA_ToolBox/MA_TextureAtlasserPro/Scripts/Editor/Utils/MA_TextureAtlasserProUtils.cs +++ b/Assets/MA_ToolBox/MA_TextureAtlasserPro/Scripts/Editor/Utils/MA_TextureAtlasserProUtils.cs @@ -5,6 +5,8 @@ using UnityEngine; using UnityEditor; using MA_Mesh; using MA_Texture; +using MA_Toolbox.Utils.Editor; +using MA_Toolbox.Utils; namespace MA_TextureAtlasserPro { @@ -259,25 +261,16 @@ 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, string namePrefix = "new ") { 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); + MA_TextureAtlasserProQuad q = Object.Instantiate(atlas.selectedTextureQuad); + q.name = string.Format("{0}{1}", namePrefix, atlas.selectedTextureQuad.name); + atlas.textureQuads.Add(q); - if (copyData) - { - q.meshes = new List(); - for (int i = 0; i < atlas.selectedTextureQuad.meshes.Count; i++) - { - q.meshes.Add(atlas.selectedTextureQuad.meshes[i]); - } - - for (int i = 0; i < atlas.selectedTextureQuad.textureGroups.Count; i++) - { - q.textureGroups[i].texture = atlas.selectedTextureQuad.textureGroups[i].texture; - } - } + AssetDatabase.AddObjectToAsset(q, atlas); if (focus) { @@ -365,6 +358,12 @@ namespace MA_TextureAtlasserPro if (!AssetDatabase.IsValidFolder(folderPath)) { string parentPath = folderPath.Substring(0, folderPath.LastIndexOf('/')); + + if(!AssetDatabase.IsValidFolder(parentPath)) + { + CreateFolder(parentPath); + } + string folderName = folderPath.Substring(folderPath.LastIndexOf('/') + 1); AssetDatabase.CreateFolder(parentPath, folderName); @@ -387,19 +386,16 @@ namespace MA_TextureAtlasserPro } #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 materialPath = null, string savePath = EXPORT_ASSET_PATH) { switch (modelExportSettings.modelFormat) { case ModelFormat.None: break; - 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); + return ExportAtlasUnityMeshPrefab(atlas, modelExportSettings, materialPath: materialPath, savePath: savePath); + //case ModelFormat.Obj: + // return ExportAtlasObj(atlas, modelExportSettings, savePath: savePath); default: break; } @@ -407,103 +403,78 @@ namespace MA_TextureAtlasserPro return null; } - private static void ReplaceAtlasMesh(MA_TextureAtlasserProAtlas atlas, ModelExportSettings modelExportSettings, string savePath = EXPORT_ASSET_PATH) + private static string[] ExportAtlasUnityMeshPrefab(MA_TextureAtlasserProAtlas atlas, ModelExportSettings modelExportSettings, string materialPath = null, string savePath = EXPORT_ASSET_PATH) { if (atlas == null || atlas.textureQuads == null) - return; - - var quads = atlas.textureQuads; - for (var index = 0; index < quads.Count; index++) { - var quad = quads[index]; - if (quad.meshes == 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]); - } - } - - 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 assetPaths = new List(); - 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); - //Set name - string meshName = string.IsNullOrEmpty(quad.name) ? "" : quad.name + "-"; - meshName += quad.meshes[m].name; - int n = m + 1; - meshName += "_" + n.ToString("#000"); - newMesh.name = meshName; - //Save it - string asset = MA_MeshUtils.MA_SaveMeshPrefab(newMesh, meshName, savePath, materialPath: 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 assetPaths = new List(); + //Directories. + string savePathPrefab = savePath + atlas.name + "/"; + string savePathMeshes = savePathPrefab + "Meshes/"; + CreateFolder(savePathPrefab); + CreateFolder(savePathMeshes); foreach (MA_TextureAtlasserProQuad quad in atlas.textureQuads) { - //Export Mesh - if (quad.meshes != null) + foreach (MA_ModelGroup mg in quad.modelGroups) { - for (int m = 0; m < quad.meshes.Count; m++) + //Validate name. + if (string.IsNullOrEmpty(mg.name) || string.IsNullOrWhiteSpace(mg.name)) { - 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"); + mg.name = MA_StringUtils.RandomAlphabetString(6); + Debug.LogWarning("No valid model name assigned!"); + } - string asset = MA_MeshUtils.MeshToFile(newMesh, meshName, savePath); - assetPaths.Add(asset); + //Create new prefab asset. + string newPrefabPath = MA_PrefabUtils.CreatePrefab(mg.name, savePathPrefab); + GameObject newPrefab = AssetDatabase.LoadAssetAtPath(newPrefabPath); + + foreach (Mesh m in mg.meshes) + { + if(m != null) + { + //Validate name. + if (string.IsNullOrEmpty(m.name) || string.IsNullOrWhiteSpace(m.name)) + { + m.name = MA_StringUtils.RandomAlphabetString(6); + Debug.LogWarning("No valid mesh name assigned!"); + } + + //Create new mesh. + //Duplicate it from the current one. + Mesh newMesh = MA_MeshUtils.MA_DuplicateMesh(m); + //Remap UV's. + newMesh = MA_MeshUtils.MA_UVReMap(newMesh, atlas.textureAtlasSize, quad.guiRect, modelExportSettings.uvChannel, modelExportSettings.uvFlipY, modelExportSettings.uvWrap); + //Set name. + newMesh.name = string.Format("{0}_{1}", mg.name, m.name); + //Save mesh. + string savedMeshPath = MA_MeshUtils.MA_SaveMeshAsset(newMesh, savePathMeshes); + + //Load mesh. + Mesh savedMesh = AssetDatabase.LoadAssetAtPath(savedMeshPath); + //Load material. + Material savedMaterial = AssetDatabase.LoadAssetAtPath(materialPath); + + //Create gameObject. + GameObject newGameObject = new GameObject(m.name); + //Add mesh filter. + MeshFilter mf = newGameObject.AddComponent(); + mf.mesh = savedMesh; + //Add mesh renderer. + MeshRenderer mr = newGameObject.AddComponent(); + mr.material = savedMaterial; + + //Add to parent gameObject (prefab). + MA_PrefabUtils.AddChild(newPrefab, newGameObject); + Object.DestroyImmediate(newGameObject); } } + + assetPaths.Add(newPrefabPath); } } @@ -528,10 +499,16 @@ namespace MA_TextureAtlasserPro 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 null; + } string[] assetPaths = new string[atlas.textureGroupRegistration.Count]; + //Directories. + string savePathTextures = savePath + atlas.name + "/Textures/"; + CreateFolder(savePathTextures); + //Create temp folder CreateFolder(tempPath); @@ -582,25 +559,24 @@ namespace MA_TextureAtlasserPro } //Save it - newTexture.MA_Save2D(newTexture.name, savePath); - - assetPaths[i] = (savePath + newTexture.name + '.' + textureExportSettings.textureFormat.ToString()); + newTexture.MA_Save2D(newTexture.name, savePathTextures); + assetPaths[i] = (savePathTextures + newTexture.name + '.' + textureExportSettings.textureFormat.ToString()); //Set settings. switch (textureExportSettings.textureType) { case TextureType.Default: { - TextureImporter textureImporter = (TextureImporter)AssetImporter.GetAtPath(savePath + newTexture.name + '.' + textureExportSettings.textureFormat.ToString()); + TextureImporter textureImporter = (TextureImporter)AssetImporter.GetAtPath(savePathTextures + newTexture.name + '.' + textureExportSettings.textureFormat.ToString()); textureImporter.textureType = TextureImporterType.Default; textureImporter.SaveAndReimport(); } break; case TextureType.Sprite: - SetAtlasSpriteSettings(atlas, textureExportSettings, savePath); + SetAtlasSpriteSettings(atlas, textureExportSettings, savePathTextures); break; case TextureType.SpriteSliced: - SetAtlasSpriteSettings(atlas, textureExportSettings, savePath); + SetAtlasSpriteSettings(atlas, textureExportSettings, savePathTextures); break; default: break; @@ -616,7 +592,7 @@ namespace MA_TextureAtlasserPro 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) { //Foreach texture group for (int i = 0; i < atlas.textureGroupRegistration.Count; i++) @@ -663,9 +639,13 @@ namespace MA_TextureAtlasserPro 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) + { return null; + } - string assetPath = ""; + //Directories. + string savePathMaterial = savePath + atlas.name + "/Materials/"; + CreateFolder(savePathMaterial); Shader shader = materialExportSettings.shader; if (shader) @@ -687,14 +667,16 @@ namespace MA_TextureAtlasserPro } } - assetPath = savePath + material.name + ".mat"; + string assetPath = savePathMaterial + material.name + ".mat"; //Save material AssetDatabase.CreateAsset(material, assetPath); AssetDatabase.Refresh(); + + return assetPath; } - return assetPath; + return null; } #endregion } diff --git a/Assets/MA_ToolBox/MA_TextureAtlasserPro/Scripts/Editor/Views/MA_TextureAtlasserProInspectorView.cs b/Assets/MA_ToolBox/MA_TextureAtlasserPro/Scripts/Editor/Views/MA_TextureAtlasserProInspectorView.cs index 4941278..eab011e 100644 --- a/Assets/MA_ToolBox/MA_TextureAtlasserPro/Scripts/Editor/Views/MA_TextureAtlasserProInspectorView.cs +++ b/Assets/MA_ToolBox/MA_TextureAtlasserPro/Scripts/Editor/Views/MA_TextureAtlasserProInspectorView.cs @@ -4,22 +4,19 @@ using System.Collections.Generic; using UnityEngine; using UnityEditor; using MA_Editor; +using MA_Toolbox.Utils; namespace MA_TextureAtlasserPro { - public class MA_TextureAtlasserProInspectorView : MA_TextureAtlasserProViewBase + public class MA_TextureAtlasserProInspectorView : MA_TextureAtlasserProViewBase { private MA_TextureAtlasserProQuad lastSelectedQuad; - - private bool isEditing = false; - + private bool isEditing = false; private GUIStyle labelStyle = new GUIStyle(GUI.skin.label); - bool useAddMeshButton = false; - - public MA_TextureAtlasserProInspectorView(MA_TextureAtlasserProWindow currentEditorWindow, string title) : base(currentEditorWindow, title) + public MA_TextureAtlasserProInspectorView(MA_TextureAtlasserProWindow currentEditorWindow, string title) : base(currentEditorWindow, title) { - + } public override void UpdateView(Event e, Rect editorViewRect) @@ -27,32 +24,19 @@ namespace MA_TextureAtlasserPro //Update base derived class base.UpdateView(e, editorViewRect); - if(isLoaded) + if (isLoaded) { //Draw inspector - if(curWindow.textureAtlas != null && curWindow.textureAtlas.selectedTextureQuad != null) + if (curWindow.textureAtlas != null && curWindow.textureAtlas.selectedTextureQuad != null) { - //Change layout during layout event to prevent gui errors - if (e.type == EventType.Layout) - { - if (curWindow.textureAtlas.selectedTextureQuad.meshes != null && curWindow.textureAtlas.selectedTextureQuad.meshes.Count == 0) - { - useAddMeshButton = true; - } - else - { - useAddMeshButton = false; - } - } - - //Deselect GUI elements when we are focusing on a new quad - if (lastSelectedQuad != curWindow.textureAtlas.selectedTextureQuad) + //Deselect GUI elements when we are focusing on a new quad + if (lastSelectedQuad != curWindow.textureAtlas.selectedTextureQuad) { lastSelectedQuad = curWindow.textureAtlas.selectedTextureQuad; GUI.FocusControl(null); } - GUILayout.BeginArea(editorViewRect, EditorStyles.helpBox); + GUILayout.BeginArea(editorViewRect, EditorStyles.helpBox); GUILayout.BeginVertical(GUILayout.ExpandWidth(true)); GUILayout.Label("Quad Name"); @@ -63,21 +47,21 @@ namespace MA_TextureAtlasserPro //Textures GUILayout.BeginHorizontal(); GUILayout.Label("Textures", GUILayout.ExpandWidth(true)); - if(GUILayout.Button(MA_TextureAtlasserProGuiLoader.editGC, EditorStyles.miniButton, GUILayout.Width(36), GUILayout.Height(15))) + if (GUILayout.Button(MA_TextureAtlasserProGuiLoader.editGC, EditorStyles.miniButton, GUILayout.Width(36), GUILayout.Height(15))) { isEditing = !isEditing; } GUILayout.EndHorizontal(); - if(curWindow.textureAtlas.textureGroupRegistration == null || curWindow.textureAtlas.textureGroupRegistration.Count == 0) + if (curWindow.textureAtlas.textureGroupRegistration == null || curWindow.textureAtlas.textureGroupRegistration.Count == 0) { - if(GUILayout.Button("+", EditorStyles.miniButton, GUILayout.ExpandWidth(true))) + if (GUILayout.Button("+", EditorStyles.miniButton, GUILayout.ExpandWidth(true))) { MA_TextureAtlasserProUtils.CreateTextureGroup(curWindow.textureAtlas, "New TextureGroup"); } } for (int i = 0; i < curWindow.textureAtlas.textureGroupRegistration.Count; i++) { - if(isEditing) + if (isEditing) { curWindow.textureAtlas.textureGroupRegistration[i].name = curWindow.textureAtlas.selectedTextureQuad.textureGroups[i].name = EditorGUILayout.TextField(curWindow.textureAtlas.textureGroupRegistration[i].name); } @@ -87,11 +71,11 @@ namespace MA_TextureAtlasserPro } GUILayout.BeginHorizontal(); curWindow.textureAtlas.selectedTextureQuad.textureGroups[i].texture = (Texture)EditorGUILayout.ObjectField(curWindow.textureAtlas.selectedTextureQuad.textureGroups[i].texture, typeof(Texture), false); - if(isEditing && GUILayout.Button("-", EditorStyles.miniButtonLeft, GUILayout.ExpandWidth(false))) + if (isEditing && GUILayout.Button("-", EditorStyles.miniButtonLeft, GUILayout.ExpandWidth(false))) { MA_TextureAtlasserProUtils.RemoveTextureGroup(curWindow.textureAtlas, i); } - if(isEditing && GUILayout.Button("+", EditorStyles.miniButtonRight, GUILayout.ExpandWidth(false))) + if (isEditing && GUILayout.Button("+", EditorStyles.miniButtonRight, GUILayout.ExpandWidth(false))) { MA_TextureAtlasserProUtils.CreateTextureGroup(curWindow.textureAtlas, "New TextureGroup"); } @@ -100,58 +84,90 @@ namespace MA_TextureAtlasserPro GUILayout.Space(MA_TextureAtlasserProUtils.VIEW_OFFSET / 2); - //Meshes - GUILayout.Label("Meshes"); - if (useAddMeshButton) - { + //Models + GUILayout.Label("Models"); + + SerializedObject serializedObject = new SerializedObject(curWindow.textureAtlas.selectedTextureQuad); + serializedObject.Update(); + + if (curWindow.textureAtlas.selectedTextureQuad.modelGroups != null) + { + SerializedProperty modelGroupsSP = serializedObject.FindProperty("modelGroups"); + + for (int i = 0; i < curWindow.textureAtlas.selectedTextureQuad.modelGroups.Count; i++) + { + using (new GUILayout.VerticalScope(EditorStyles.helpBox)) + { + using (new GUILayout.HorizontalScope()) + { + curWindow.textureAtlas.selectedTextureQuad.modelGroups[i].name = EditorGUILayout.TextField(curWindow.textureAtlas.selectedTextureQuad.modelGroups[i].name); + if (GUILayout.Button("-", EditorStyles.miniButton, GUILayout.ExpandWidth(true))) + { + curWindow.textureAtlas.selectedTextureQuad.modelGroups.RemoveAt(i); + break; + } + } + + SerializedProperty meshesSP = modelGroupsSP.GetArrayElementAtIndex(i).FindPropertyRelative("meshes"); + EditorGUILayout.PropertyField(meshesSP, false, GUILayout.ExpandWidth(false), GUILayout.MaxWidth(editorViewRect.width * 0.5f)); + + if (meshesSP.isExpanded) + { + for (int j = 0; j < curWindow.textureAtlas.selectedTextureQuad.modelGroups[i].meshes.Count; j++) + { + using (new GUILayout.HorizontalScope()) + { + curWindow.textureAtlas.selectedTextureQuad.modelGroups[i].meshes[j] = (Mesh)EditorGUILayout.ObjectField(curWindow.textureAtlas.selectedTextureQuad.modelGroups[i].meshes[j], typeof(Mesh), false); + if (GUILayout.Button("-", EditorStyles.miniButton, GUILayout.ExpandWidth(true))) + { + curWindow.textureAtlas.selectedTextureQuad.modelGroups[i].meshes.RemoveAt(j); + break; + } + } + } + } + + if (GUILayout.Button("+", EditorStyles.miniButton)) + { + curWindow.textureAtlas.selectedTextureQuad.modelGroups[i].meshes.Add(null); + } + } + } + if (GUILayout.Button("+", EditorStyles.miniButton, GUILayout.ExpandWidth(true))) { - curWindow.textureAtlas.selectedTextureQuad.meshes.Add(null); + curWindow.textureAtlas.selectedTextureQuad.modelGroups.Add(new MA_ModelGroup() { name = MA_StringUtils.RandomAlphabetString(6) }); } } - - if (curWindow.textureAtlas.selectedTextureQuad.meshes != null) + else { - for (int i = 0; i < curWindow.textureAtlas.selectedTextureQuad.meshes.Count; i++) - { - GUILayout.BeginHorizontal(); - curWindow.textureAtlas.selectedTextureQuad.meshes[i] = (Mesh)EditorGUILayout.ObjectField(curWindow.textureAtlas.selectedTextureQuad.meshes[i], typeof(Mesh), false); - if(GUILayout.Button("-", EditorStyles.miniButtonLeft, GUILayout.ExpandWidth(false))) - { - curWindow.textureAtlas.selectedTextureQuad.meshes.RemoveAt(i); - } - if(GUILayout.Button("+", EditorStyles.miniButtonRight, GUILayout.ExpandWidth(false))) - { - curWindow.textureAtlas.selectedTextureQuad.meshes.Insert(i + 1, null); - } - GUILayout.EndHorizontal(); - } + curWindow.textureAtlas.selectedTextureQuad.modelGroups = new List(); + } + + serializedObject.ApplyModifiedProperties(); + + GUILayout.Space(MA_TextureAtlasserProUtils.VIEW_OFFSET / 2); + + //x, y, w, h. + GUILayout.FlexibleSpace(); + if (!MA_TextureAtlasserProUtils.IsPowerOfTwo((int)curWindow.textureAtlas.selectedTextureQuad.guiRect.width) || !MA_TextureAtlasserProUtils.IsPowerOfTwo((int)curWindow.textureAtlas.selectedTextureQuad.guiRect.height)) + { + labelStyle.normal.textColor = Color.red; } else { - curWindow.textureAtlas.selectedTextureQuad.meshes = new List(); + labelStyle.normal.textColor = GUI.skin.label.normal.textColor; } + GUILayout.Label("x " + curWindow.textureAtlas.selectedTextureQuad.guiRect.x.ToString() + ", y " + curWindow.textureAtlas.selectedTextureQuad.guiRect.y.ToString()); + GUILayout.Label("w " + curWindow.textureAtlas.selectedTextureQuad.guiRect.width.ToString() + ", h " + curWindow.textureAtlas.selectedTextureQuad.guiRect.height.ToString(), labelStyle); - GUILayout.FlexibleSpace(); - if (!MA_TextureAtlasserProUtils.IsPowerOfTwo((int)curWindow.textureAtlas.selectedTextureQuad.guiRect.width) || !MA_TextureAtlasserProUtils.IsPowerOfTwo((int)curWindow.textureAtlas.selectedTextureQuad.guiRect.height)) - { - labelStyle.normal.textColor = Color.red; - } - else - { - labelStyle.normal.textColor = GUI.skin.label.normal.textColor; - } - - GUILayout.Label("x " + curWindow.textureAtlas.selectedTextureQuad.guiRect.x.ToString() + ", y " + curWindow.textureAtlas.selectedTextureQuad.guiRect.y.ToString()); - GUILayout.Label("w " + curWindow.textureAtlas.selectedTextureQuad.guiRect.width.ToString() + ", h " + curWindow.textureAtlas.selectedTextureQuad.guiRect.height.ToString(), labelStyle); - - GUILayout.EndVertical(); - GUILayout.EndArea(); + GUILayout.EndVertical(); + GUILayout.EndArea(); } } - if(curWindow.textureAtlas != null && curWindow.textureAtlas.selectedTextureQuad != null) + if (curWindow.textureAtlas != null && curWindow.textureAtlas.selectedTextureQuad != null) ProcessEvents(e, editorViewRect); } diff --git a/Assets/MA_ToolBox/MA_TextureAtlasserPro/Scripts/Editor/Views/MA_TextureAtlasserProMenuView.cs b/Assets/MA_ToolBox/MA_TextureAtlasserPro/Scripts/Editor/Views/MA_TextureAtlasserProMenuView.cs index 05a5745..b2c6fc4 100644 --- a/Assets/MA_ToolBox/MA_TextureAtlasserPro/Scripts/Editor/Views/MA_TextureAtlasserProMenuView.cs +++ b/Assets/MA_ToolBox/MA_TextureAtlasserPro/Scripts/Editor/Views/MA_TextureAtlasserProMenuView.cs @@ -63,7 +63,7 @@ namespace MA_TextureAtlasserPro if (curWindow.textureAtlas.selectedTextureQuad != null && GUILayout.Button(MA_TextureAtlasserProGuiLoader.duplicateQuadGC, GUILayout.ExpandWidth(false), GUILayout.ExpandHeight(true))) { if (curWindow.textureAtlas.selectedTextureQuad != null) - MA_TextureAtlasserProUtils.DuplicateTextureQuad(curWindow.textureAtlas, curWindow.settings.autoFocus, curWindow.settings.copySelectedQuadData, curWindow.settings.duplicatedQuadNamePrefix); + MA_TextureAtlasserProUtils.DuplicateTextureQuad(curWindow.textureAtlas, curWindow.settings.autoFocus, curWindow.settings.duplicatedQuadNamePrefix); } } diff --git a/Assets/MA_ToolBox/MA_TextureAtlasserPro/Scripts/Editor/Views/MA_TextureAtlasserProWorkView.cs b/Assets/MA_ToolBox/MA_TextureAtlasserPro/Scripts/Editor/Views/MA_TextureAtlasserProWorkView.cs index 2fe4067..c0fa3d8 100644 --- a/Assets/MA_ToolBox/MA_TextureAtlasserPro/Scripts/Editor/Views/MA_TextureAtlasserProWorkView.cs +++ b/Assets/MA_ToolBox/MA_TextureAtlasserPro/Scripts/Editor/Views/MA_TextureAtlasserProWorkView.cs @@ -91,7 +91,7 @@ namespace MA_TextureAtlasserPro e.Use(); } - //Hotkeys. + //HotKeys. if (curWindow.settings.useHotkeys) { if(curWindow.textureAtlas != null) @@ -123,7 +123,7 @@ namespace MA_TextureAtlasserPro if (curWindow.settings.GetHotKey(e, curWindow.settings.duplicateHotKey)) { - MA_TextureAtlasserProUtils.DuplicateTextureQuad(curWindow.textureAtlas, curWindow.settings.autoFocus, curWindow.settings.copySelectedQuadData, curWindow.settings.duplicatedQuadNamePrefix); + MA_TextureAtlasserProUtils.DuplicateTextureQuad(curWindow.textureAtlas, curWindow.settings.autoFocus, curWindow.settings.duplicatedQuadNamePrefix); e.Use(); } } diff --git a/Assets/MA_ToolBox/MA_TextureAtlasserPro/Scripts/Editor/Windows/MA_TextureAtlasserProExportWindow.cs b/Assets/MA_ToolBox/MA_TextureAtlasserPro/Scripts/Editor/Windows/MA_TextureAtlasserProExportWindow.cs index fb41570..ea6e919 100644 --- a/Assets/MA_ToolBox/MA_TextureAtlasserPro/Scripts/Editor/Windows/MA_TextureAtlasserProExportWindow.cs +++ b/Assets/MA_ToolBox/MA_TextureAtlasserPro/Scripts/Editor/Windows/MA_TextureAtlasserProExportWindow.cs @@ -154,40 +154,23 @@ namespace MA_TextureAtlasserPro if (GUILayout.Button("Export", GUILayout.ExpandWidth(true), GUILayout.Height(37))) { - bool export = false; + string[] textures = null; + string material = null; + string[] models = null; - if(curWindow.textureAtlas.exportSettings.modelExportSettings.modelFormat == ModelFormat.ReplaceMesh) + if (curWindow.textureAtlas.exportSettings.exportTextures) { - 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; + textures = MA_TextureAtlasserProUtils.ExportAtlasTextures(curWindow.textureAtlas, curWindow.textureAtlas.exportSettings.textureExportSettings); } - if(export) + if (curWindow.textureAtlas.exportSettings.exportMaterials) { - string[] textures = null; - string material = null; - string[] models = null; + material = MA_TextureAtlasserProUtils.ExportAtlasMaterial(curWindow.textureAtlas, curWindow.textureAtlas.exportSettings.materialExportSettings, textures: textures); + } - 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); - } + if (curWindow.textureAtlas.exportSettings.exportModels) + { + models = MA_TextureAtlasserProUtils.ExportAtlasModels(curWindow.textureAtlas, curWindow.textureAtlas.exportSettings.modelExportSettings, materialPath: material); } } diff --git a/Assets/MA_ToolBox/MA_Utilities/MeshUtils/MA_MeshUtils.cs b/Assets/MA_ToolBox/MA_Utilities/MeshUtils/MA_MeshUtils.cs index 4827ca8..2914f41 100644 --- a/Assets/MA_ToolBox/MA_Utilities/MeshUtils/MA_MeshUtils.cs +++ b/Assets/MA_ToolBox/MA_Utilities/MeshUtils/MA_MeshUtils.cs @@ -15,259 +15,160 @@ using UnityEditor; namespace MA_Mesh { - public static class MA_MeshUtils - { - public static string MA_SaveMeshAsset(Mesh mesh, string savePath) - { - if (string.IsNullOrEmpty(mesh.name)) - { - mesh.name = UnityEngine.Random.Range(11111, 99999).ToString(); - } + public static class MA_MeshUtils + { + public static string MA_SaveMeshAsset(Mesh mesh, string savePath) + { + if (string.IsNullOrEmpty(mesh.name)) + { + mesh.name = UnityEngine.Random.Range(11111, 99999).ToString(); + } - string assetPath = savePath + mesh.name + ".asset"; + string assetPath = savePath + mesh.name + ".asset"; - AssetDatabase.CreateAsset(mesh, assetPath); - AssetDatabase.SaveAssets(); + AssetDatabase.CreateAsset(mesh, assetPath); + AssetDatabase.SaveAssets(); - return assetPath; - } + return assetPath; + } - public static string MA_SaveMeshPrefab(Mesh mesh, string prefabName, string savePath, string materialPath) - { - string assetPath = null; + public static string MA_SaveMeshPrefab(Mesh mesh, string prefabName, string savePath, string materialPath) + { + string assetPath = null; - string meshAssetPath = MA_SaveMeshAsset(mesh, savePath); - Mesh meshAsset = AssetDatabase.LoadAssetAtPath(meshAssetPath); + string meshAssetPath = MA_SaveMeshAsset(mesh, savePath); + Mesh meshAsset = AssetDatabase.LoadAssetAtPath(meshAssetPath); - if (meshAsset != null) - { - GameObject gameObject = new GameObject - { - name = prefabName - }; + if (meshAsset != null) + { + GameObject gameObject = new GameObject + { + name = prefabName + }; - gameObject.AddComponent().mesh = meshAsset; - gameObject.AddComponent(); + gameObject.AddComponent().mesh = meshAsset; + gameObject.AddComponent(); - Material curMaterial = AssetDatabase.LoadAssetAtPath(materialPath); - if (curMaterial != null) - { - gameObject.GetComponent().material = curMaterial; - } + Material curMaterial = AssetDatabase.LoadAssetAtPath(materialPath); + if (curMaterial != null) + { + gameObject.GetComponent().material = curMaterial; + } - if (string.IsNullOrEmpty(prefabName)) - { - prefabName = UnityEngine.Random.Range(11111, 99999).ToString(); - } + if (string.IsNullOrEmpty(prefabName)) + { + prefabName = UnityEngine.Random.Range(11111, 99999).ToString(); + } - assetPath = savePath + prefabName + ".prefab"; + assetPath = savePath + prefabName + ".prefab"; -#if UNITY_2018_3_OR_NEWER + PrefabUtility.SaveAsPrefabAsset(gameObject, assetPath); + UnityEngine.Object.DestroyImmediate(gameObject); + } - PrefabUtility.SaveAsPrefabAsset(gameObject, assetPath); + return assetPath; + } -#else + public static Mesh MA_DuplicateMesh(Mesh mesh) + { + Mesh newMesh = new Mesh + { + name = mesh.name, + bounds = mesh.bounds, + subMeshCount = mesh.subMeshCount + }; - GameObject go = AssetDatabase.LoadAssetAtPath(assetPath); - if (go != null) - { - PrefabUtility.ReplacePrefab(gameObject, go, ReplacePrefabOptions.ReplaceNameBased); - } - else - { - PrefabUtility.CreatePrefab(assetPath, gameObject, ReplacePrefabOptions.ReplaceNameBased); - } + newMesh.SetVertices(new List(mesh.vertices)); + for (int i = 0; i < mesh.subMeshCount; i++) + { + newMesh.SetTriangles(mesh.GetTriangles(i), i); + } + newMesh.SetNormals(new List(mesh.normals)); + newMesh.SetUVs(0, new List(mesh.uv)); + newMesh.SetTangents(new List(mesh.tangents)); + newMesh.SetColors(new List(mesh.colors)); -#endif + return newMesh; + } - UnityEngine.GameObject.DestroyImmediate(gameObject); - } - - return assetPath; - } - - public static Mesh MA_DuplicateMesh(Mesh mesh) - { - Mesh newMesh = new Mesh - { - name = mesh.name, - bounds = mesh.bounds, - subMeshCount = mesh.subMeshCount - }; - - newMesh.SetVertices(new List(mesh.vertices)); - for (int i = 0; i < mesh.subMeshCount; i++) - { - newMesh.SetTriangles(mesh.GetTriangles(i), i); - } - newMesh.SetNormals(new List(mesh.normals)); - newMesh.SetUVs(0, new List(mesh.uv)); - newMesh.SetTangents(new List(mesh.tangents)); - newMesh.SetColors(new List(mesh.colors)); - - 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 512 x 512 - 0 .5 = 1 / 512 * 256 + 0 .5 = 1 / 512 * 256 256 x 256 + pos */ - List uvs = new List(); + List uvs = new List(); - //Get UV's - mesh.GetUVs(uvChannel, uvs); + //Get UV's + mesh.GetUVs(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); - } + 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); + } - mesh.SetUVs(uvChannel, uvs); + mesh.SetUVs(uvChannel, uvs); - return mesh; - } + return mesh; + } - public static Mesh MA_UVReMap(this Mesh mesh, Vector2 atlasSize, Rect textureRect, int uvChannel = 0, bool flipY = true, bool wrap = true) - { - //Get UV's - List uvs = new List(); - mesh.GetUVs(uvChannel, uvs); + public static Mesh MA_UVReMap(this Mesh mesh, Vector2 atlasSize, Rect textureRect, int uvChannel = 0, bool flipY = true, bool wrap = true) + { + //Get UV's + List uvs = new List(); + mesh.GetUVs(uvChannel, uvs); - //Min and max bounds in 0-1 space. - float xMin, xMax, yMin, yMax; - xMin = (1f / atlasSize.x * textureRect.width); - xMax = (1f / atlasSize.x * textureRect.x); - yMin = (1f / atlasSize.y * textureRect.height); + //Min and max bounds in 0-1 space. + float xMin, xMax, yMin, yMax; + xMin = (1f / atlasSize.x * textureRect.width); + xMax = (1f / atlasSize.x * textureRect.x); + yMin = (1f / atlasSize.y * textureRect.height); - //Flip uv's if needed. - if (flipY) - { - yMax = (1f / atlasSize.y * (atlasSize.y - textureRect.height - textureRect.y)); - } - else - { - yMax = (1f / atlasSize.y * textureRect.y); - } + //Flip uv's if needed. + if (flipY) + { + yMax = (1f / atlasSize.y * (atlasSize.y - textureRect.height - textureRect.y)); + } + else + { + yMax = (1f / atlasSize.y * textureRect.y); + } - for (int i = 0; i < uvs.Count; i++) - { - float newX = uvs[i].x * xMin + xMax; - float newY = uvs[i].y * yMin + yMax; + for (int i = 0; i < uvs.Count; i++) + { + float newX = uvs[i].x * xMin + xMax; + float newY = uvs[i].y * yMin + yMax; - //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); - } + //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); + } - uvs[i] = new Vector2(newX, newY); - } + uvs[i] = new Vector2(newX, newY); + } - mesh.SetUVs(uvChannel, uvs); + mesh.SetUVs(uvChannel, uvs); - return mesh; - } + return mesh; + } - public static float Wrap(float val, float min, float max) - { - 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 string MeshToString(Mesh mesh) - { - int vertexOffset = 0; - int normalOffset = 0; - int uvOffset = 0; - - Material material = new Material(Shader.Find("Standard")); - - StringBuilder sb = new StringBuilder(); - - sb.Append("g ").Append(mesh.name).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)); - } - - sb.Append("\n"); - - foreach (Vector3 v in mesh.normals) - { - sb.Append(string.Format("vn {0} {1} {2}\n", -v.x, v.y, v.z)); - } - - sb.Append("\n"); - - foreach (Vector3 v in mesh.uv) - { - sb.Append(string.Format("vt {0} {1}\n", v.x, v.y)); - } - - for (int m = 0; m < mesh.subMeshCount; m++) - { - sb.Append("\n"); - 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"; - - using (StreamWriter sw = new StreamWriter(assetPath)) - { - sw.Write(MeshToString(mesh)); - } - - AssetDatabase.Refresh(); - - return assetPath; - } - //End - } - - //struct ObjMaterial - //{ - // public string name; - // public string textureName; - //} + public static float Wrap(float val, float min, float max) + { + val -= (float)Math.Round((val - min) / (max - min)) * (max - min); + if (val < min) + val = val + max - min; + return val; + } + } } #endif \ No newline at end of file diff --git a/Assets/MA_ToolBox/MA_Utilities/PrefabUtils.meta b/Assets/MA_ToolBox/MA_Utilities/PrefabUtils.meta new file mode 100644 index 0000000..f7b45af --- /dev/null +++ b/Assets/MA_ToolBox/MA_Utilities/PrefabUtils.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 9946d57c8e1c3714183228268fff08a5 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MA_ToolBox/MA_Utilities/PrefabUtils/MA_PrefabUtils.cs b/Assets/MA_ToolBox/MA_Utilities/PrefabUtils/MA_PrefabUtils.cs new file mode 100644 index 0000000..0502f10 --- /dev/null +++ b/Assets/MA_ToolBox/MA_Utilities/PrefabUtils/MA_PrefabUtils.cs @@ -0,0 +1,41 @@ +//- + +#if UNITY_EDITOR +using UnityEditor; +using UnityEngine; + +namespace MA_Toolbox.Utils.Editor +{ + public static class MA_PrefabUtils + { + public static string CreatePrefab(string prefabName, string savePath) + { + if(string.IsNullOrEmpty(prefabName) || string.IsNullOrWhiteSpace(prefabName)) + { + Debug.LogError("Invalid prefab name."); + return null; + } + + GameObject gameObject = new GameObject + { + name = prefabName + }; + + string assetPath = savePath + prefabName + ".prefab"; + + PrefabUtility.SaveAsPrefabAsset(gameObject, assetPath); + UnityEngine.Object.DestroyImmediate(gameObject); + + return assetPath; + } + + public static void AddChild(GameObject prefab, GameObject child) + { + GameObject p = PrefabUtility.InstantiatePrefab(prefab) as GameObject; + child.transform.SetParent(p.transform); + PrefabUtility.ApplyPrefabInstance(p, InteractionMode.AutomatedAction); + UnityEngine.Object.DestroyImmediate(p); + } + } +} +#endif \ No newline at end of file diff --git a/Assets/MA_ToolBox/MA_Utilities/PrefabUtils/MA_PrefabUtils.cs.meta b/Assets/MA_ToolBox/MA_Utilities/PrefabUtils/MA_PrefabUtils.cs.meta new file mode 100644 index 0000000..d5f5f80 --- /dev/null +++ b/Assets/MA_ToolBox/MA_Utilities/PrefabUtils/MA_PrefabUtils.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 04e1a62b7d6bb434eb0314336ac94f8f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MA_ToolBox/MA_Utilities/StringUtils.meta b/Assets/MA_ToolBox/MA_Utilities/StringUtils.meta new file mode 100644 index 0000000..30dac0d --- /dev/null +++ b/Assets/MA_ToolBox/MA_Utilities/StringUtils.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: f38cac7c10bd77748ab01c8642751035 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MA_ToolBox/MA_Utilities/StringUtils/MA_StringUtils.cs b/Assets/MA_ToolBox/MA_Utilities/StringUtils/MA_StringUtils.cs new file mode 100644 index 0000000..93f2e41 --- /dev/null +++ b/Assets/MA_ToolBox/MA_Utilities/StringUtils/MA_StringUtils.cs @@ -0,0 +1,28 @@ +//- + +using UnityEditor; +using UnityEngine; + +namespace MA_Toolbox.Utils +{ + public static class MA_StringUtils + { + private const string ALPHABET = "aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ"; + + public static string RandomAlphabetString(int length) + { + string s = ""; + for (int i = 0; i < length; i++) + { + s += RandomAlphabetChar(); + } + + return s; + } + + public static char RandomAlphabetChar() + { + return ALPHABET[Random.Range(0, ALPHABET.Length)]; + } + } +} \ No newline at end of file diff --git a/Assets/MA_ToolBox/MA_Utilities/StringUtils/MA_StringUtils.cs.meta b/Assets/MA_ToolBox/MA_Utilities/StringUtils/MA_StringUtils.cs.meta new file mode 100644 index 0000000..ba5006b --- /dev/null +++ b/Assets/MA_ToolBox/MA_Utilities/StringUtils/MA_StringUtils.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fc1a5e241141bb549b81ad11dfdc0962 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/README.md b/README.md index 8885c19..d37016d 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[![Image](https://maxartz15.com/wp-content/uploads/2019/04/MA_TextureAtlas.png)]() +[![Image](https://maxartz15.com/wp-content/uploads/2020/04/MA_TextureAtlas2.png)](https://maxartz15.com/wp-content/uploads/2020/04/MA_TextureAtlas2.png) # MA_TextureAtlasser Texture atlas creator tool for Unity.
This tool is made to combine textures and/or remap the UV’s for 3D models. The tool can also be used to make 2D sprite sheets. The visual editor gives you the ability to set and prioritize the sizes and positions in the texture atlas/sprite sheet. @@ -6,17 +6,15 @@ Texture atlas creator tool for Unity.
This tool is made to combine textures - Automatically adjusts the UV's of the assigned meshes to match the new texture atlas. ### Download unitypackage -https://github.com/maxartz15/MA_TextureAtlasser/releases
-[![Github All Releases](https://img.shields.io/github/downloads/maxartz15/MA_TextureAtlasser/total.svg)]() +[![Github All Releases](https://img.shields.io/github/downloads/maxartz15/MA_TextureAtlasser/total.svg)](https://github.com/maxartz15/MA_TextureAtlasser/releases) -### Tested Unity versions -[![Image](https://img.shields.io/badge/Unity-2017.4-green)]() [![Image](https://img.shields.io/badge/Unity-2018.4-green)]() [![Image](https://img.shields.io/badge/Unity-2019.3-green)]() +### Unity versions +- Latest release requires Unity 2018.3 or higher. +- Releases before 1.8 should work with older Unity versions. ## Export options ### Meshes - UnityMesh (with prefab setup) -- OBJ -- Replace orginal (this will replace the orginal model, make sure to backup before doing this!) ### Textures - PNG - PNG (sliced) sprite sheet