14 Commits
1.1 ... 1.6.1

Author SHA1 Message Date
max
a728366035 Export presets, wrap uv's, bugfixes and formatting.
[MA_TextureAtlas] Updated export window to use scriptable asset export presets. The option to wrap uv's (default = true). Bigfixes and code formatting.
2019-11-06 18:08:01 +01:00
max
e81a4ec119 Merged goto01 and reworked some code.
Implemented the texture scaler provided by goto01 (Kiryl Tkachou) and removed the old ones.
Implmented the mesh export bugfixes.
Changed mesh export names.
Changed texture export names.
Updated the the export window.
Updated export functionality.
Updated hotkeys.
Fixed quad duplication bug.
Minor visual changes.

Co-Authored-By: Kiryl Tkachou <goto01@users.noreply.github.com>
2019-08-30 01:11:33 +02:00
26a0f68454 Merge pull request #1 from goto01/master
Adding the scaling and export options.

Merging the changes made.
Sub-meshes export bug-fix.
Export window changes.
New texture scaling function.

(TODO: some old code cleanup.)
2019-08-29 18:56:01 +02:00
9f5240967a Added bilinear scaling and mesh replacing export mode 2019-07-26 15:52:40 +03:00
9a13ddb24e Fixed quad title 2019-07-26 15:51:51 +03:00
6ac386c1b5 Fixed quad title 2019-07-23 23:56:38 +03:00
e2abb77afe Fixed quad title 2019-07-23 23:53:53 +03:00
68b3ddaaa1 Fixed importing. 2019-07-23 23:48:36 +03:00
9d53f74c4b Fixed mesh duplication. 2019-07-23 18:51:39 +03:00
max
7f17793af0 Fixed gray texture on export.
Fixed gray texture on export bug, it was caused by the texture scale function (during upscaling), right now it's required to have the texture dimensions be a power of 2 width/height.
Optional OBJ/PNG/sprite export options.
Chanaged readme.
TODO: Cleanup export code. Make proper scale options (bilinear & point).
2019-07-16 14:12:32 +02:00
09f7c488b9 Update README.md 2019-07-04 23:22:57 +02:00
max
1251736f5b Updated & tested with Unity 2019.1.8f1
Minor changes.
2019-07-03 00:02:40 +02:00
max
78e4fb0ad1 #if UNITY_EDITOR
Added '#if UNITY_EDITOR' to all the scripts that should only run/be used in the editor.
2019-05-04 13:29:02 +02:00
max
7990f987dc Settings, Hotkey bugfix.
null errors.
2019-03-31 18:45:16 +02:00
26 changed files with 863 additions and 283 deletions

View File

@ -1,3 +1,4 @@
#if UNITY_EDITOR
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
@ -15,7 +16,7 @@ namespace MA_TextureAtlasserPro
public MA_TextureAtlasserProQuad selectedTextureQuad;
private Rect editorWorkRect;
public bool showTextures = false;
public MA_TextureAtlasserProExportSettings exportSettings;
//Data
public Vector2 textureAtlasSize;
@ -35,7 +36,8 @@ namespace MA_TextureAtlasserPro
editorWorkRect = new Rect(Vector2.zero - zoomCoordsOrigin, textureAtlasSize);
GUI.backgroundColor = new Color(0, 0, 0, 0.1f);
GUI.Box(editorWorkRect, this.name);
GUI.Box(editorWorkRect, "");
GUI.Box(new Rect(editorWorkRect.x, editorWorkRect.y - 25, editorWorkRect.width, 20), this.name);
GUI.backgroundColor = Color.white;
MA_Editor.Grid.Grid.DrawZoomableGrid(editorWorkRect, 64, new Color(0, 0, 0, 0.1f), zoomCoordsOrigin);
@ -100,4 +102,5 @@ namespace MA_TextureAtlasserPro
}
}
}
}
}
#endif

View File

@ -0,0 +1,63 @@
using UnityEngine;
using System.Collections;
using MA_Texture;
namespace MA_TextureAtlasserPro
{
[System.Serializable]
public class MA_TextureAtlasserProExportSettings : ScriptableObject
{
[HideInInspector]
public bool canModify = true;
public ModelExportSettings modelExportSettings = new ModelExportSettings();
public TextureExportSettings textureExportSettings = new TextureExportSettings();
}
[System.Serializable]
public class ModelExportSettings
{
[Header("Model settings:")]
public ModelFormat modelFormat = ModelFormat.Obj;
public bool replaceModel = false;
public bool uvFlipY = true;
public int uvChannel = 0;
public bool uvWrap = true;
}
[System.Serializable]
public class TextureExportSettings
{
[Header("Texture settings:")]
public TextureFormat textureFormat = TextureFormat.Png;
public TextureType textureType = TextureType.Default;
public MA_TextureUtils.TextureScaleMode textureScaleMode = MA_TextureUtils.TextureScaleMode.Bilinear;
}
public enum ExportPreset
{
Custom,
Default,
Sprites,
ReplaceObjMeshes
}
public enum ModelFormat
{
None,
Obj
}
public enum TextureFormat
{
None,
Png
}
public enum TextureType
{
Default,
Sprite,
SpriteSliced
}
}

View File

@ -1,3 +1,4 @@
#if UNITY_EDITOR
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
@ -24,7 +25,6 @@ namespace MA_TextureAtlasserPro
public Rect dragRectPos;
//Data
public Texture texture; //Replace this with texture groups
public List<MA_TextureGroup> textureGroups;
public List<Mesh> meshes;
@ -42,7 +42,7 @@ namespace MA_TextureAtlasserPro
//Clamp and snap the guiRect
guiRect = new Rect(Mathf.RoundToInt(rect.x / 32) * 32, Mathf.RoundToInt(rect.y / 32) * 32, Mathf.RoundToInt(rect.width / 32) * 32, Mathf.RoundToInt(rect.height / 32) * 32);
//Draw the sqaud background
//Draw the quad background
if(showTexture && textureGroups != null && textureGroups.Count > 0 && textureGroups[0].texture != null)
GUI.DrawTexture(new Rect(guiRect.x - zoomCoordsOrigin.x, guiRect.y - zoomCoordsOrigin.y, guiRect.width, guiRect.height), textureGroups[0].texture, ScaleMode.StretchToFill);
else
@ -52,7 +52,10 @@ namespace MA_TextureAtlasserPro
GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
GUILayout.Label(this.name);
var tempColor = GUI.backgroundColor;
GUI.backgroundColor = new Color(1, 1, 1, 0.7f);
GUILayout.Label(" " + this.name + " ", GUI.skin.box);
GUI.backgroundColor = tempColor;
GUILayout.FlexibleSpace();
GUILayout.EndHorizontal();
@ -163,4 +166,5 @@ namespace MA_TextureAtlasserPro
debugMode = isDebugging;
}
}
}
}
#endif

View File

@ -1,4 +1,5 @@
using System.Collections;
#if UNITY_EDITOR
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
@ -9,17 +10,31 @@ namespace MA_TextureAtlasserPro
[System.Serializable]
public class MA_TextureAtlasserProSettings : ScriptableObject
{
[Header("Selection")]
public bool autoFocus = true;
[Header("Duplication:")]
public bool copySelectedQuadData = false;
public string duplicatedQuadNamePrefix = "new ";
[Header("Hotkeys:")]
public bool useHotkeys = false;
public EventModifiers modifierKey = EventModifiers.Alt;
public KeyCode addQuadHotKey = KeyCode.Q;
public KeyCode removeQuadHotKey = KeyCode.R;
public KeyCode duplicateHotKey = KeyCode.D;
public KeyCode zoomInHotKey = KeyCode.Equals;
public KeyCode zoomOutHotKey = KeyCode.Minus;
[Header("Duplication:")]
public bool copySelectedQuadData = true;
public string duplicatedQuadNamePrefix = "new ";
[Header("Selection")]
public bool autoFocus = true;
public bool GetHotKey(Event e, KeyCode shortKey)
{
if (e.type == EventType.KeyDown && e.modifiers == modifierKey && e.keyCode == shortKey)
{
return true;
}
return false;
}
}
}
}
#endif

View File

@ -1,4 +1,5 @@
using System.Collections;
#if UNITY_EDITOR
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
@ -17,3 +18,4 @@ namespace MA_TextureAtlasserPro
public string name;
}
}
#endif

View File

@ -1,3 +1,4 @@
#if UNITY_EDITOR
using UnityEngine;
using UnityEditor;
@ -32,4 +33,5 @@ namespace MA_TextureAtlasserPro
editIcon = new GUIContent("", (Texture)EditorGUIUtility.Load(LOADICONPATH + "editIcon" + ".png"));
}
}
}
}
#endif

View File

@ -1,3 +1,4 @@
#if UNITY_EDITOR
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
@ -7,10 +8,13 @@ using MA_Texture;
namespace MA_TextureAtlasserPro
{
public static class MA_TextureAtlasserProUtils
{
public const string SETTINGSASSETPATH = "Assets/MA_ToolBox/MA_TextureAtlasserPro/Settings/";
public const string SAVEASSETPATH = "Assets/MA_ToolBox/MA_TextureAtlasserPro/Atlasses/";
public const string EXPORTSETTINGSASSETPATH = "Assets/MA_ToolBox/MA_TextureAtlasserPro/Settings/ExportSettings/";
public const string SAVEASSETPATH = "Assets/MA_ToolBox/MA_TextureAtlasserPro/Atlasses/";
public const string LOADASSETPATH = "Assets/MA_ToolBox/MA_TextureAtlasserPro/Atlasses/";
public const string EXPORTASSETPATH = "Assets/MA_ToolBox/MA_TextureAtlasserPro/Exports/";
public const float VIEWOFFSET = 20;
@ -18,7 +22,7 @@ namespace MA_TextureAtlasserPro
public static MA_TextureAtlasserProSettings CreateSettings()
{
MA_TextureAtlasserProSettings _settings = (MA_TextureAtlasserProSettings)ScriptableObject.CreateInstance<MA_TextureAtlasserProSettings>();
MA_TextureAtlasserProSettings _settings = ScriptableObject.CreateInstance<MA_TextureAtlasserProSettings>();
if(_settings != null)
{
@ -46,9 +50,41 @@ namespace MA_TextureAtlasserPro
return _settings;
}
public static MA_TextureAtlasserProAtlas CreateTextureAtlas(string name, Vector2 size)
public static MA_TextureAtlasserProExportSettings CreateExportSettings(string name, bool canModify = true)
{
MA_TextureAtlasserProExportSettings _settings = ScriptableObject.CreateInstance<MA_TextureAtlasserProExportSettings>();
_settings.canModify = canModify;
if (_settings != null)
{
AssetDatabase.CreateAsset(_settings, EXPORTSETTINGSASSETPATH + name + ".asset");
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
return _settings;
}
else
{
return null;
}
}
public static MA_TextureAtlasserProExportSettings LoadExportSettings()
{
string name = "MA_DefaultExportSettings";
MA_TextureAtlasserProExportSettings _settings = AssetDatabase.LoadAssetAtPath(EXPORTSETTINGSASSETPATH + name + ".asset", typeof(MA_TextureAtlasserProExportSettings)) as MA_TextureAtlasserProExportSettings;
if (_settings == null)
{
_settings = CreateExportSettings(name, false);
}
return _settings;
}
public static MA_TextureAtlasserProAtlas CreateTextureAtlas(string name, Vector2 size)
{
MA_TextureAtlasserProAtlas _atlas = (MA_TextureAtlasserProAtlas)ScriptableObject.CreateInstance<MA_TextureAtlasserProAtlas>();
MA_TextureAtlasserProAtlas _atlas = ScriptableObject.CreateInstance<MA_TextureAtlasserProAtlas>();
if(_atlas != null)
{
@ -103,8 +139,10 @@ namespace MA_TextureAtlasserPro
{
atlas.textureGroupRegistration = new List<MA_TextureGroupRegistration>();
MA_TextureGroupRegistration groupRegistration = new MA_TextureGroupRegistration();
groupRegistration.name = DEFAULTTEXTUREGROUPNAME;
MA_TextureGroupRegistration groupRegistration = new MA_TextureGroupRegistration
{
name = DEFAULTTEXTUREGROUPNAME
};
atlas.textureGroupRegistration.Add(groupRegistration);
}
@ -142,9 +180,14 @@ namespace MA_TextureAtlasserPro
}
}
}
if(atlas.exportSettings == null)
{
atlas.exportSettings = LoadExportSettings();
}
}
public static void 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)
{
@ -155,7 +198,7 @@ namespace MA_TextureAtlasserPro
}
//Create new quad
MA_TextureAtlasserProQuad _quad = (MA_TextureAtlasserProQuad)ScriptableObject.CreateInstance("MA_TextureAtlasserProQuad");
MA_TextureAtlasserProQuad _quad = ScriptableObject.CreateInstance<MA_TextureAtlasserProQuad>();
//Add quad to asset
if(_quad != null)
@ -166,7 +209,7 @@ namespace MA_TextureAtlasserPro
SetTextureGroups(atlas, _quad);
atlas.textureQuads.Add((MA_TextureAtlasserProQuad)_quad);
atlas.textureQuads.Add(_quad);
AssetDatabase.AddObjectToAsset(_quad, atlas);
AssetDatabase.SaveAssets();
@ -176,6 +219,8 @@ namespace MA_TextureAtlasserPro
{
atlas.selectedTextureQuad = atlas.textureQuads[atlas.textureQuads.Count - 1];
}
return _quad;
}
else
{
@ -186,6 +231,8 @@ namespace MA_TextureAtlasserPro
{
Debug.LogError("CreateTextureQuad Failed: textureAtlas");
}
return null;
}
public static void RemoveTextureQuad(MA_TextureAtlasserProAtlas atlas, bool focus = true)
@ -195,7 +242,7 @@ namespace MA_TextureAtlasserPro
int _index = atlas.textureQuads.IndexOf(atlas.selectedTextureQuad);
atlas.textureQuads.RemoveAt(_index);
GameObject.DestroyImmediate(atlas.selectedTextureQuad, true);
Object.DestroyImmediate(atlas.selectedTextureQuad, true);
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
@ -211,18 +258,29 @@ namespace MA_TextureAtlasserPro
{
if(atlas != null && atlas.selectedTextureQuad != null)
{
CreateTextureQuad(atlas, namePrefix + atlas.selectedTextureQuad.name, atlas.selectedTextureQuad.rect);
MA_TextureAtlasserProQuad q = CreateTextureQuad(atlas, namePrefix + atlas.selectedTextureQuad.name, atlas.selectedTextureQuad.rect, false);
if(copyData)
if (copyData)
{
atlas.textureQuads[atlas.textureQuads.Count - 1].meshes = atlas.selectedTextureQuad.meshes;
atlas.textureQuads[atlas.textureQuads.Count - 1].textureGroups = atlas.selectedTextureQuad.textureGroups;
q.meshes = new List<Mesh>();
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;
}
}
if(focus)
{
atlas.selectedTextureQuad = atlas.textureQuads[atlas.textureQuads.Count - 1];
atlas.selectedTextureQuad = q;
}
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
}
}
@ -236,22 +294,28 @@ namespace MA_TextureAtlasserPro
//Add texture groups
foreach (MA_TextureGroupRegistration tgr in atlas.textureGroupRegistration)
{
MA_TextureGroup textureGroup = new MA_TextureGroup();
textureGroup.name = tgr.name;
MA_TextureGroup textureGroup = new MA_TextureGroup
{
name = tgr.name
};
quad.textureGroups.Add(textureGroup);
}
}
public static void CreateTextureGroup(MA_TextureAtlasserProAtlas atlas, string name)
{
MA_TextureGroupRegistration _textureGroupRegistration = new MA_TextureGroupRegistration();
_textureGroupRegistration.name = name;
MA_TextureGroupRegistration _textureGroupRegistration = new MA_TextureGroupRegistration
{
name = name
};
atlas.textureGroupRegistration.Add(_textureGroupRegistration);
foreach (MA_TextureAtlasserProQuad q in atlas.textureQuads)
{
MA_TextureGroup _textureGroup = new MA_TextureGroup();
_textureGroup.name = name;
MA_TextureGroup _textureGroup = new MA_TextureGroup
{
name = name
};
q.textureGroups.Add(_textureGroup);
}
}
@ -275,106 +339,190 @@ namespace MA_TextureAtlasserPro
curWindow.Close();
}
public static void ExportAtlas(MA_TextureAtlasserProAtlas atlas, string savePath = EXPORTASSETPATH)
public static bool IsPowerOfTwo(int value)
{
if(atlas != null && atlas.textureQuads != null)
//While x is even and > 1
while (((value % 2) == 0) && value > 1)
{
ExportAtlasMeshesObj(atlas);
ExportAtlasTexturesPNG(atlas);
AssetDatabase.Refresh();
value /= 2;
}
return (value == 1);
}
public static void ExportAtlasMeshesObj(MA_TextureAtlasserProAtlas atlas, string savePath = EXPORTASSETPATH)
#region Export
public static void ExportAtlasModels(MA_TextureAtlasserProAtlas atlas, ModelExportSettings modelExportSettings, string savePath = EXPORTASSETPATH)
{
switch(modelExportSettings.modelFormat)
{
case ModelFormat.None:
break;
case ModelFormat.Obj:
ExportAtlasObj(atlas, modelExportSettings, savePath);
break;
default:
break;
}
}
private static void ExportAtlasObj(MA_TextureAtlasserProAtlas atlas, ModelExportSettings modelExportSettings, string savePath = EXPORTASSETPATH)
{
if(atlas != null && atlas.textureQuads != null)
if (atlas == null || atlas.textureQuads == null)
return;
if(modelExportSettings.replaceModel)
{
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();
}
else
{
foreach (MA_TextureAtlasserProQuad quad in atlas.textureQuads)
{
//Export Mesh
if (quad.meshes != null)
{
for (int m = 0; m < quad.meshes.Count; m++)
{
if (quad.meshes[m] != null)
{
//Create new mesh
Mesh newMesh = new Mesh();
//Duplicate it from the current one
newMesh = MA_MeshUtils.MA_DuplicateMesh(quad.meshes[m]);
//Remap UV's
newMesh = MA_MeshUtils.MA_UVReMap(newMesh, atlas.textureAtlasSize, quad.guiRect, modelExportSettings.uvChannel, modelExportSettings.uvFlipY, modelExportSettings.uvWrap);
//Save it
string modelName = string.IsNullOrEmpty(quad.name) ? "" : quad.name + "-";
modelName += quad.meshes[m].name;
int n = m + 1;
modelName += "_" + n.ToString("#000");
MA_MeshUtils.MeshToFile(newMesh, modelName, savePath);
}
}
}
}
}
}
public static void ExportAtlasTextures(MA_TextureAtlasserProAtlas atlas, TextureExportSettings textureExportSettings, string savePath = EXPORTASSETPATH)
{
switch (textureExportSettings.textureFormat)
{
case TextureFormat.None:
break;
case TextureFormat.Png:
ExportAtlasPNG(atlas, textureExportSettings, savePath);
break;
default:
break;
}
}
private static void ExportAtlasPNG(MA_TextureAtlasserProAtlas atlas, TextureExportSettings textureExportSettings, string savePath = EXPORTASSETPATH)
{
if (atlas == null || atlas.textureQuads == null || atlas.textureGroupRegistration == null)
return;
//Foreach texture group
for (int i = 0; i < atlas.textureGroupRegistration.Count; i++)
{
foreach (MA_TextureAtlasserProQuad ta in atlas.textureQuads)
//Create new Texture Atlas
Texture2D newTexture = new Texture2D((int)atlas.textureAtlasSize.x, (int)atlas.textureAtlasSize.y)
{
//Export Mesh
if(ta.meshes != null)
name = atlas.name + "_" + atlas.textureGroupRegistration[i].name
};
foreach (MA_TextureAtlasserProQuad q in atlas.textureQuads)
{
if (q.textureGroups != null && q.textureGroups[i].texture != null)
{
for (int m = 0; m < ta.meshes.Count; m++)
{
if(ta.meshes[m] != null)
{
//Create new mesh
Mesh newMesh = new Mesh();
//Duplicate it from the current one
newMesh = MA_MeshUtils.MA_DuplicateMesh(ta.meshes[m]);
//Remap uvs
newMesh = MA_MeshUtils.MA_UVReMap(newMesh, atlas.textureAtlasSize, ta.guiRect);
//Save it
MA_MeshUtils.MeshToFile(newMesh, "MA_" + ta.name, savePath);
}
}
//Create new texture part
Texture2D newTexturePart = (Texture2D)MA_TextureUtils.ConvertToReadableTexture(q.textureGroups[i].texture);
//Scale it
newTexturePart = newTexturePart.MA_Scale2D((int)q.guiRect.width, (int)q.guiRect.height, textureExportSettings.textureScaleMode);
//Add it
newTexture = newTexture.MA_Combine2D(newTexturePart, (int)q.guiRect.x, (int)q.guiRect.y);
}
}
//Save it
newTexture.MA_Save2D(newTexture.name, savePath);
TextureImporter textureImporter = (TextureImporter)AssetImporter.GetAtPath(savePath + newTexture.name + ".png");
textureImporter.textureType = TextureImporterType.Default;
textureImporter.SaveAndReimport();
}
SetAtlasPNGSpriteSettings(atlas, textureExportSettings, savePath);
//Refresh
AssetDatabase.Refresh();
}
// public static void ExportAtlasTexturePNG(MA_TextureAtlasserProAtlas atlas, string savePath = EXPORTASSETPATH)
// {
// if(atlas != null && atlas.textureQuads != null)
// {
// //Create new Texture Atlas
// Texture2D newTexture = new Texture2D((int)atlas.textureAtlasSize.x, (int)atlas.textureAtlasSize.y);
// newTexture.name = atlas.name;
// foreach (MA_TextureAtlasserProQuad ta in atlas.textureQuads)
// {
// //Export Texture Atlas
// //TODO: Replace with texture groups (foreacht ...)
// if(ta.texture != null)
// {
// //Create new texture part
// Texture2D newTexturePart = (Texture2D)MA_Texture.MA_TextureUtils.ConvertToReadableTexture(ta.texture);
// //Scale it
// newTexturePart = newTexturePart.MA_Scale2D((int)ta.guiRect.width, (int)ta.guiRect.height);
// //Add it
// newTexture = newTexture.MA_Combine2D(newTexturePart, (int)ta.guiRect.x, (int)ta.guiRect.y);
// }
// }
// //Save it
// newTexture.MA_Save2D("MA_" + newTexture.name, savePath);
// //Refresh
// AssetDatabase.Refresh();
// }
// }
public static void ExportAtlasTexturesPNG(MA_TextureAtlasserProAtlas atlas, string savePath = EXPORTASSETPATH)
private static void SetAtlasPNGSpriteSettings(MA_TextureAtlasserProAtlas atlas, TextureExportSettings textureExportSettings, string savePath = EXPORTASSETPATH)
{
if(atlas != null && atlas.textureQuads != null && atlas.textureGroupRegistration != null)
//Foreach texture group
for (int i = 0; i < atlas.textureGroupRegistration.Count; i++)
{
//Foreach texture group
for (int i = 0; i < atlas.textureGroupRegistration.Count; i++)
//Convert
string textureName = atlas.name + "_" + atlas.textureGroupRegistration[i].name + ".png";
TextureImporter textureImporter = (TextureImporter)AssetImporter.GetAtPath(savePath + textureName);
textureImporter.textureType = TextureImporterType.Sprite;
textureImporter.alphaIsTransparency = true;
//Slice sprites.
if (textureExportSettings.textureType == TextureType.SpriteSliced)
{
//Create new Texture Atlas
Texture2D newTexture = new Texture2D((int)atlas.textureAtlasSize.x, (int)atlas.textureAtlasSize.y);
newTexture.name = atlas.name + "_" + atlas.textureGroupRegistration[i].name;
textureImporter.spriteImportMode = SpriteImportMode.None; //Reset it to update?
textureImporter.spriteImportMode = SpriteImportMode.Multiple;
List<SpriteMetaData> spriteMetaData = new List<SpriteMetaData>();
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 texture part
Texture2D newTexturePart = (Texture2D)MA_Texture.MA_TextureUtils.ConvertToReadableTexture(q.textureGroups[i].texture);
//Scale it
newTexturePart = newTexturePart.MA_Scale2D((int)q.guiRect.width, (int)q.guiRect.height);
//Add it
newTexture = newTexture.MA_Combine2D(newTexturePart, (int)q.guiRect.x, (int)q.guiRect.y);
//Create new SpriteMetaData.
SpriteMetaData smd = new SpriteMetaData
{
name = q.name,
rect = new Rect(q.guiRect.x, atlas.textureAtlasSize.y - q.guiRect.y - q.guiRect.height, q.guiRect.width, q.guiRect.height)
};
spriteMetaData.Add(smd);
}
}
//Save it
newTexture.MA_Save2D("MA_" + newTexture.name, savePath);
textureImporter.spritesheet = spriteMetaData.ToArray();
}
else
{
textureImporter.spriteImportMode = SpriteImportMode.Single;
}
//Refresh
AssetDatabase.Refresh();
textureImporter.SaveAndReimport();
}
}
#endregion
}
}
}
#endif

View File

@ -1,3 +1,4 @@
#if UNITY_EDITOR
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
@ -32,7 +33,7 @@ namespace MA_TextureAtlasserPro
curWindow.workView.ResetWindow();
}
if(curWindow.textureAtlas != null)
if (curWindow.textureAtlas != null)
{
GUILayout.FlexibleSpace();
//GUILayout.Label(curWindow.textureAtlas.textureAtlasSize.ToString());
@ -75,4 +76,5 @@ namespace MA_TextureAtlasserPro
}
}
}
}
}
#endif

View File

@ -1,3 +1,4 @@
#if UNITY_EDITOR
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
@ -12,6 +13,8 @@ namespace MA_TextureAtlasserPro
private bool isEditing = false;
private GUIStyle labelStyle = new GUIStyle(GUI.skin.label);
public MA_TextureAtlasserProInspectorView(MA_TextureAtlasserProWindow currentEditorWindow, string title) : base(currentEditorWindow, title)
{
@ -114,8 +117,17 @@ namespace MA_TextureAtlasserPro
}
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 = Color.black;
}
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());
GUILayout.Label("w " + curWindow.textureAtlas.selectedTextureQuad.guiRect.width.ToString() + ", h " + curWindow.textureAtlas.selectedTextureQuad.guiRect.height.ToString(), labelStyle);
GUILayout.EndVertical();
GUILayout.EndArea();
@ -131,4 +143,5 @@ namespace MA_TextureAtlasserPro
base.ProcessEvents(e, editorViewRect);
}
}
}
}
#endif

View File

@ -1,3 +1,4 @@
#if UNITY_EDITOR
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
@ -78,4 +79,5 @@ namespace MA_TextureAtlasserPro
base.ProcessEvents(e, editorViewRect);
}
}
}
}
#endif

View File

@ -1,4 +1,5 @@
using System.Collections;
#if UNITY_EDITOR
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
@ -52,4 +53,5 @@ namespace MA_TextureAtlasserPro
}
}
}
}
}
#endif

View File

@ -1,4 +1,5 @@
using System.Collections;
#if UNITY_EDITOR
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using MA_Editor;
@ -18,7 +19,7 @@ namespace MA_TextureAtlasserPro
private const float kZoomMax = 2.0f;
private Rect zoomArea;
private float zoom = 1.0f;
public float Zoom { get { return zoom; } }
public float Zoom { get { return zoom; } set { zoom = Mathf.Clamp(value, kZoomMin, kZoomMax); } }
private Vector2 zoomCoordsOrigin = Vector2.zero;
public override void UpdateView(Event e, Rect editorViewRect)
@ -93,25 +94,39 @@ namespace MA_TextureAtlasserPro
//Hotkeys.
if (curWindow.settings.useHotkeys)
{
if (e.type == EventType.KeyDown && e.keyCode == curWindow.settings.addQuadHotKey)
if(curWindow.textureAtlas != null)
{
MA_TextureAtlasserProUtils.CreateTextureQuad(curWindow.textureAtlas, "new Quad", new Rect(0, 0, 128, 128), curWindow.settings.autoFocus);
e.Use();
}
if (curWindow.textureAtlas.selectedTextureQuad != null)
{
if (e.type == EventType.KeyDown && e.keyCode == curWindow.settings.removeQuadHotKey)
if (curWindow.settings.GetHotKey(e, curWindow.settings.addQuadHotKey))
{
MA_TextureAtlasserProUtils.RemoveTextureQuad(curWindow.textureAtlas, curWindow.settings.autoFocus);
MA_TextureAtlasserProUtils.CreateTextureQuad(curWindow.textureAtlas, "new Quad", new Rect(0, 0, 128, 128), curWindow.settings.autoFocus);
e.Use();
}
if (e.type == EventType.KeyDown && e.keyCode == curWindow.settings.duplicateHotKey)
if(curWindow.settings.GetHotKey(e, curWindow.settings.zoomInHotKey))
{
MA_TextureAtlasserProUtils.DuplicateTextureQuad(curWindow.textureAtlas, curWindow.settings.autoFocus);
Zoom += 0.25f;
e.Use();
}
if(curWindow.settings.GetHotKey(e, curWindow.settings.zoomOutHotKey))
{
Zoom -= 0.25f;
e.Use();
}
if (curWindow.textureAtlas.selectedTextureQuad != null)
{
if (curWindow.settings.GetHotKey(e, curWindow.settings.removeQuadHotKey))
{
MA_TextureAtlasserProUtils.RemoveTextureQuad(curWindow.textureAtlas, curWindow.settings.autoFocus);
e.Use();
}
if (curWindow.settings.GetHotKey(e, curWindow.settings.duplicateHotKey))
{
MA_TextureAtlasserProUtils.DuplicateTextureQuad(curWindow.textureAtlas, curWindow.settings.autoFocus, curWindow.settings.copySelectedQuadData, curWindow.settings.duplicatedQuadNamePrefix);
e.Use();
}
}
}
}
}
@ -144,4 +159,5 @@ namespace MA_TextureAtlasserPro
zoomCoordsOrigin = new Vector2(-(curWindow.position.width / 2) + (curWindow.position.width / 3), -(curWindow.position.height / 2) + (curWindow.position.height / 3));
}
}
}
}
#endif

View File

@ -0,0 +1,88 @@
#if UNITY_EDITOR
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using MA_Editor;
using MA_Texture;
namespace MA_TextureAtlasserPro
{
public class MA_TextureAtlasserProCreateExportWindow : EditorWindow
{
private const int windowHeight = 97;
private const int windowWidth = 320;
//Editor
private static MA_TextureAtlasserProCreateExportWindow thisWindow;
public static MA_TextureAtlasserProWindow curWindow;
//Data
string settingsName = "Settings name";
bool nameError = true;
[MenuItem("MA_ToolKit/MA_TextureAtlasserPro/New Export Settings")]
public static void Init()
{
InitWindow(null);
}
public static void InitWindow(MA_TextureAtlasserProWindow currentEditorWindow)
{
curWindow = currentEditorWindow;
GetCurrentWindow();
thisWindow.minSize = new Vector2(windowWidth, windowHeight);
thisWindow.maxSize = new Vector2(windowWidth, windowHeight);
thisWindow.titleContent.text = "MA_CreateExportSettings";
thisWindow.Show();
}
private static void GetCurrentWindow()
{
thisWindow = (MA_TextureAtlasserProCreateExportWindow)EditorWindow.GetWindow<MA_TextureAtlasserProCreateExportWindow>();
}
void OnGUI()
{
GUILayout.BeginArea(new Rect(MA_TextureAtlasserProUtils.VIEWOFFSET, MA_TextureAtlasserProUtils.VIEWOFFSET, position.width - (MA_TextureAtlasserProUtils.VIEWOFFSET * 2), position.height - (MA_TextureAtlasserProUtils.VIEWOFFSET * 2)));
GUILayout.BeginVertical();
//Input options
settingsName = EditorGUILayout.TextField("Settings name", settingsName, GUILayout.ExpandWidth(true));
if (settingsName == "Settings name" || string.IsNullOrEmpty(settingsName))
{
nameError = true;
GUI.backgroundColor = Color.red;
GUILayout.Box("Error: Enter a valid settings name!", EditorStyles.helpBox);
GUI.backgroundColor = Color.white;
}
else
{
nameError = false;
}
//Create
if (!nameError)
{
if (GUILayout.Button("Create!", GUILayout.ExpandWidth(true), GUILayout.Height(37)))
{
MA_TextureAtlasserProExportSettings exportSettings = MA_TextureAtlasserProUtils.CreateExportSettings(settingsName, true);
if (curWindow != null && curWindow.textureAtlas != null)
{
curWindow.textureAtlas.exportSettings = exportSettings;
}
this.Close();
}
}
GUILayout.EndVertical();
GUILayout.EndArea();
}
}
}
#endif

View File

@ -1,4 +1,5 @@
using System.Collections;
#if UNITY_EDITOR
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
@ -167,4 +168,5 @@ namespace MA_TextureAtlasserPro
isLoaded = true;
}
}
}
}
#endif

View File

@ -1,32 +1,35 @@
using System.Collections;
#if UNITY_EDITOR
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using MA_Editor;
using MA_Texture;
namespace MA_TextureAtlasserPro
{
public class MA_TextureAtlasserProExportWindow : EditorWindow
{
//Editor
private static MA_TextureAtlasserProExportWindow thisWindow;
public static MA_TextureAtlasserProWindow curWindow;
public class MA_TextureAtlasserProExportWindow : EditorWindow
{
private const int windowHeight = 300;
private const int windowWidth = 320;
//Data
private static bool isLoaded = false; //Make sure we wait a frame at the start to setup and don't draw.
//Editor
private static MA_TextureAtlasserProExportWindow thisWindow;
public static MA_TextureAtlasserProWindow curWindow;
[MenuItem("MA_ToolKit/MA_TextureAtlasserPro/Export Atlas")]
//Data
private static bool isLoaded = false; //Make sure we wait a frame at the start to setup and don't draw.
[MenuItem("MA_ToolKit/MA_TextureAtlasserPro/Export Atlas")]
private static void Init()
{
GetCurrentWindow();
GetCurrentWindow();
thisWindow.minSize = new Vector2(500,160);
thisWindow.maxSize = new Vector2(500,160);
thisWindow.minSize = new Vector2(windowWidth, windowHeight);
thisWindow.titleContent.text = "MA_ExportTextureAtlas";
thisWindow.titleContent.text = "MA_ExportTextureAtlas";
thisWindow.Show();
}
thisWindow.Show();
}
public static void InitEditorWindow(MA_TextureAtlasserProWindow currentEditorWindow)
{
@ -34,9 +37,7 @@ namespace MA_TextureAtlasserPro
GetCurrentWindow();
thisWindow.minSize = new Vector2(500,160);
thisWindow.maxSize = new Vector2(500,160);
thisWindow.minSize = new Vector2(windowWidth, windowHeight);
thisWindow.titleContent.text = "MA_ExportTextureAtlas";
thisWindow.Show();
@ -93,17 +94,16 @@ namespace MA_TextureAtlasserPro
if(curWindow != null && curWindow.textureAtlas != null)
{
//Export options
GUILayout.Box("Note: No custom export options right now.. :<", EditorStyles.helpBox);
//Export
GUILayout.BeginVertical(EditorStyles.helpBox);
GUILayout.BeginVertical();
DrawExportMenu();
GUILayout.Label("Meshes: OBJ | Textures: PNG");
if(GUILayout.Button("Export Atlas", GUILayout.ExpandWidth(true), GUILayout.Height(37)))
{
MA_TextureAtlasserProUtils.ExportAtlas(curWindow.textureAtlas);
}
curWindow.textureAtlas.exportSettings = (MA_TextureAtlasserProExportSettings)EditorGUILayout.ObjectField(curWindow.textureAtlas.exportSettings, typeof(MA_TextureAtlasserProExportSettings), false);
if(curWindow.textureAtlas.exportSettings != null)
{
DrawExportAdvancedOptions();
}
GUILayout.EndVertical();
}
@ -131,5 +131,69 @@ namespace MA_TextureAtlasserPro
if(e.type == EventType.Repaint)
isLoaded = true;
}
private void DrawExportMenu()
{
GUILayout.BeginHorizontal(EditorStyles.helpBox, GUILayout.Height(44));
if (GUILayout.Button(MA_TextureAtlasserProIcons.createAtlasIcon, GUILayout.ExpandWidth(false), GUILayout.ExpandHeight(true)))
{
MA_TextureAtlasserProCreateExportWindow.InitWindow(curWindow);
}
bool wasEnabled = GUI.enabled;
if (curWindow.textureAtlas.exportSettings != null)
{
GUI.enabled = true;
}
else
{
GUI.enabled = false;
}
if (GUILayout.Button("Export", GUILayout.ExpandWidth(true), GUILayout.Height(37)))
{
MA_TextureAtlasserProUtils.ExportAtlasModels(curWindow.textureAtlas, curWindow.textureAtlas.exportSettings.modelExportSettings);
MA_TextureAtlasserProUtils.ExportAtlasTextures(curWindow.textureAtlas, curWindow.textureAtlas.exportSettings.textureExportSettings);
}
GUI.enabled = wasEnabled;
GUILayout.EndHorizontal();
}
private void DrawExportAdvancedOptions()
{
bool wasEnabled = GUI.enabled;
if (curWindow.textureAtlas.exportSettings.canModify)
{
GUI.enabled = true;
}
else
{
GUI.enabled = false;
}
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
GUILayout.Label("Models:", EditorStyles.miniBoldLabel);
curWindow.textureAtlas.exportSettings.modelExportSettings.modelFormat = (ModelFormat)EditorGUILayout.EnumPopup("ModelFormat:", curWindow.textureAtlas.exportSettings.modelExportSettings.modelFormat);
curWindow.textureAtlas.exportSettings.modelExportSettings.replaceModel = EditorGUILayout.Toggle("ReplaceModels:", curWindow.textureAtlas.exportSettings.modelExportSettings.replaceModel);
curWindow.textureAtlas.exportSettings.modelExportSettings.uvFlipY = EditorGUILayout.Toggle("UV FlipY:", curWindow.textureAtlas.exportSettings.modelExportSettings.uvFlipY);
curWindow.textureAtlas.exportSettings.modelExportSettings.uvChannel = EditorGUILayout.IntField("UV Channel:", curWindow.textureAtlas.exportSettings.modelExportSettings.uvChannel);
curWindow.textureAtlas.exportSettings.modelExportSettings.uvWrap = EditorGUILayout.Toggle("UV Wrap:", curWindow.textureAtlas.exportSettings.modelExportSettings.uvWrap);
GUILayout.Label("Textures:", EditorStyles.miniBoldLabel);
curWindow.textureAtlas.exportSettings.textureExportSettings.textureFormat = (TextureFormat)EditorGUILayout.EnumPopup("TextureFormat:", curWindow.textureAtlas.exportSettings.textureExportSettings.textureFormat);
curWindow.textureAtlas.exportSettings.textureExportSettings.textureType = (TextureType)EditorGUILayout.EnumPopup("TextureType:", curWindow.textureAtlas.exportSettings.textureExportSettings.textureType);
curWindow.textureAtlas.exportSettings.textureExportSettings.textureScaleMode = (MA_TextureUtils.TextureScaleMode)EditorGUILayout.EnumPopup("TextureScaleMode:", curWindow.textureAtlas.exportSettings.textureExportSettings.textureScaleMode);
EditorGUILayout.EndVertical();
GUI.enabled = wasEnabled;
}
}
}
}
#endif

View File

@ -1,4 +1,5 @@
using System.Collections;
#if UNITY_EDITOR
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
@ -118,4 +119,5 @@ namespace MA_TextureAtlasserPro
isLoaded = true;
}
}
}
}
#endif

View File

@ -0,0 +1 @@
Export settigns are supposed to be here.

View File

@ -0,0 +1,25 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 81466035f9fafc64db33b9e6114d774b, type: 3}
m_Name: MA_DefaultExportSettings
m_EditorClassIdentifier:
canModify: 0
modelExportSettings:
modelFormat: 1
replaceModel: 0
uvFlipY: 1
uvChannel: 0
uvWrap: 1
textureExportSettings:
textureFormat: 1
textureType: 0
textureScaleMode: 0

View File

@ -0,0 +1,25 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 81466035f9fafc64db33b9e6114d774b, type: 3}
m_Name: MA_DefaultSpriteExportSettings
m_EditorClassIdentifier:
canModify: 0
modelExportSettings:
modelFormat: 1
replaceModel: 0
uvFlipY: 1
uvChannel: 0
uvWrap: 1
textureExportSettings:
textureFormat: 1
textureType: 0
textureScaleMode: 0

View File

@ -0,0 +1,24 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 73f5e66553c13034e9b894ef2cc31b66, type: 3}
m_Name: MA_TextureAtlasserProSettings
m_EditorClassIdentifier:
useHotkeys: 1
modifierKey: 1
addQuadHotKey: 113
removeQuadHotKey: 114
duplicateHotKey: 100
zoomInHotKey: 61
zoomOutHotKey: 45
copySelectedQuadData: 1
duplicatedQuadNamePrefix: 'new '
autoFocus: 1

View File

@ -1,6 +1,6 @@
//Maxartz15
//Version 1.0
//https://github.com/maxartz15/MA_EditorUtils
#if UNITY_EDITOR
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
@ -58,4 +58,5 @@ namespace MA_Editor.Grid
Handles.EndGUI();
}
}
}
}
#endif

View File

@ -1,6 +1,9 @@
//Maxartz15
//Version 1.0
//https://github.com/maxartz15/MA_EditorUtils
//References:
//http://martinecker.com/martincodes/unity-editor-window-zooming/
#if UNITY_EDITOR
using UnityEngine;
using MA_Editor;
@ -67,4 +70,5 @@ namespace MA_Editor.RectUtils
return multipliedRect;
}
}
}
}
#endif

View File

@ -1,6 +1,9 @@
//Maxartz15
//Version 1.0
//https://github.com/maxartz15/MA_EditorUtils
//References:
//http://martinecker.com/martincodes/unity-editor-window-zooming/
#if UNITY_EDITOR
using UnityEngine;
using MA_Editor;
using MA_Editor.RectUtils;
@ -36,4 +39,5 @@ namespace MA_Editor.GUILayoutZoom
GUI.BeginGroup(new Rect(0.0f, EditorWindowTabHeight, Screen.width, Screen.height));
}
}
}
}
#endif

View File

@ -1,11 +1,15 @@
//Maxartz15
//Version 1.0
//https://github.com/maxartz15/MA_MeshUtils
//References:
//http://wiki.unity3d.com/index.php?title=ObjExporter
#if UNITY_EDITOR
using System;
using System.IO;
using System.Text;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEditor;
@ -35,7 +39,13 @@ namespace MA_Mesh
public static Mesh MA_DuplicateMesh(Mesh mesh)
{
Mesh newMesh = new Mesh();
Mesh newMesh = new Mesh
{
name = mesh.name,
bounds = mesh.bounds,
colors = mesh.colors,
subMeshCount = mesh.subMeshCount
};
newMesh.SetVertices(new List<Vector3>(mesh.vertices));
for (int i = 0; i < mesh.subMeshCount; i++)
@ -78,27 +88,41 @@ namespace MA_Mesh
return mesh;
}
public static Mesh MA_UVReMap(this Mesh mesh, Vector2 atlasSize, Rect textureRect, int uvChannel = 0, bool flipY = true)
{
List<Vector2> uvs = new List<Vector2>();
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<Vector2> uvs = new List<Vector2>();
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);
//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++)
{
if(flipY)
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)
{
Debug.Log("01" + uvs[i].x);
uvs[i] = new Vector2((uvs[i].x / atlasSize.x * textureRect.width) + (1 / atlasSize.x * textureRect.x), (uvs[i].y / atlasSize.y * textureRect.height) + (1 / atlasSize.y * (atlasSize.y - textureRect.height - textureRect.y)));
Debug.Log("02" + uvs[i].x);
}
else
{
Debug.Log("01" + uvs[i].x);
uvs[i] = new Vector2((uvs[i].x / atlasSize.x * textureRect.width) + (1 / atlasSize.x * textureRect.x), (uvs[i].y / atlasSize.y * textureRect.height) + (1 / atlasSize.y * textureRect.y));
Debug.Log("02" + uvs[i].x);
newX = Wrap(newX, xMax, xMin + xMax);
newY = Wrap(newY, yMax, yMin + yMax);
}
uvs[i] = new Vector2(newX, newY);
}
mesh.SetUVs(uvChannel, uvs);
@ -106,6 +130,14 @@ namespace MA_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)
{
@ -113,7 +145,6 @@ namespace MA_Mesh
int normalOffset = 0;
int uvOffset = 0;
Material material = new Material(Shader.Find("Standard"));
StringBuilder sb = new StringBuilder();
@ -161,9 +192,9 @@ namespace MA_Mesh
}
}
vertexOffset += mesh.vertices.Length;
normalOffset += mesh.normals.Length;
uvOffset += mesh.uv.Length;
//vertexOffset += mesh.vertices.Length;
//normalOffset += mesh.normals.Length;
//uvOffset += mesh.uv.Length;
return sb.ToString();
}
@ -173,15 +204,15 @@ namespace MA_Mesh
using (StreamWriter sw = new StreamWriter(savePath + filename + ".obj"))
{
sw.Write(MeshToString(mesh));
Debug.Log(savePath + filename);
}
}
//End
}
struct ObjMaterial
{
public string name;
public string textureName;
}
}
//struct ObjMaterial
//{
// public string name;
// public string textureName;
//}
}
#endif

View File

@ -1,27 +1,24 @@
//Maxartz15
//Version 1.0
//Part of MA_TextureUtils
//https://github.com/maxartz15/MA_TextureUtils
//https://github.com/maxartz15/MA_TextureUtils
//References:
//http://www.gamasutra.com/blogs/JoshSutphin/20131007/201829/Adding_to_Unitys_BuiltIn_Classes_Using_Extension_Methods.php
//https://forum.unity3d.com/threads/contribution-texture2d-blur-in-c.185694/
//http://orbcreation.com/orbcreation/page.orb?1180
//https://support.unity3d.com/hc/en-us/articles/206486626-How-can-I-get-pixels-from-unreadable-textures-
//https://github.com/maxartz15/MA_TextureAtlasser/commit/9f5240967a51692fa2a17a6b3c8d124dd5dc60f9
#if UNITY_EDITOR
using UnityEngine;
using UnityEditor;
using System.IO;
using System.Collections;
using System.Collections.Generic;
//http://www.gamasutra.com/blogs/JoshSutphin/20131007/201829/Adding_to_Unitys_BuiltIn_Classes_Using_Extension_Methods.php
//https://forum.unity3d.com/threads/contribution-texture2d-blur-in-c.185694/
//http://orbcreation.com/orbcreation/page.orb?1180
//https://support.unity3d.com/hc/en-us/articles/206486626-How-can-I-get-pixels-from-unreadable-textures-
using System;
namespace MA_Texture
{
public static class MA_TextureUtils
{
/// <summary>
/// Some base converters and texture settings setters.
/// </summary>
public static Texture ConvertToReadableTexture(Texture texture)
{
if (texture == null)
@ -49,6 +46,7 @@ namespace MA_Texture
// Copy the pixels from the RenderTexture to the new Texture
myTexture2D.ReadPixels(new Rect(0, 0, tmp.width, tmp.height), 0, 0);
myTexture2D.Apply();
myTexture2D.name = texture.name;
// Reset the active RenderTexture
RenderTexture.active = previous;
@ -73,8 +71,6 @@ namespace MA_Texture
bw.Close();
fs.Close();
Debug.Log("Saved texture: " + texture.name);
AssetDatabase.Refresh();
return texture;
@ -90,80 +86,110 @@ namespace MA_Texture
return texture;
}
#endregion
#endregion
#region Scale
public static Texture2D MA_Scale2D(this Texture2D texture, int newWidth, int newHeight)
#region Scale
public enum TextureScaleMode
{
Bilinear,
Point
}
public static Texture MA_Scale(this Texture texture, int width, int height, TextureScaleMode scaleMode)
{
Texture2D texture2D = new Texture2D(newWidth, newHeight);
float ratioWidth = texture.width / newWidth;
float ratioHeight = texture.height / newHeight;
Texture2D texture2D = (Texture2D)MA_TextureUtils.ConvertToReadableTexture(texture);
for (int x = 0; x < texture.width; x++)
{
for (int y = 0; y < texture.height; y++)
{
Color pixel = texture.GetPixel(x, y);
int posX = Mathf.FloorToInt(x / ratioWidth);
int posY = Mathf.FloorToInt(y / ratioHeight);
texture2D.SetPixel(posX, posY, new Color(pixel.r, pixel.g, pixel.b, pixel.a));
}
}
texture2D.Apply();
texture2D.MA_Scale2D(width, height, scaleMode);
return texture2D;
}
public static Texture MA_Scale(this Texture texture, int newWidth, int newHeight)
{
Texture2D texture2D = (Texture2D)MA_TextureUtils.ConvertToReadableTexture(texture);
texture2D.MA_Scale2D(newWidth, newHeight);
texture = texture2D;
texture = texture2D;
return texture;
}
public static Texture2D MA_Scale22D(this Texture2D texture, float width, float height)
{
float ratioWidth = width / texture.width;
float ratioHeight = height / texture.height;
public static Texture2D MA_Scale2D(this Texture2D texture, int newWidth, int newHeight, TextureScaleMode scaleMode)
{
Color[] curColors = texture.GetPixels();
Color[] newColors = new Color[newWidth * newHeight];
int newWidth = Mathf.RoundToInt(texture.width * ratioWidth);
int newHeight = Mathf.RoundToInt(texture.height * ratioHeight);
switch (scaleMode)
{
case TextureScaleMode.Bilinear:
newColors = MA_BilinearScale(curColors, texture.width, texture.height, newWidth, newHeight);
break;
case TextureScaleMode.Point:
newColors = MA_PointScale(curColors, texture.width, texture.height, newWidth, newHeight);
break;
Texture2D newTexture = new Texture2D(newWidth, newHeight);
}
for (int x = 0; x < texture.width; x++)
{
for (int y = 0; y < texture.height; y++)
{
Color pixel = texture.GetPixel(x, y);
int posX = Mathf.RoundToInt(x * ratioWidth);
int posY = Mathf.RoundToInt(y * ratioHeight);
newTexture.SetPixel(posX, posY, new Color(pixel.r, pixel.g, pixel.b, pixel.a));
}
}
texture.Resize(newWidth, newHeight);
texture.SetPixels(newColors);
texture.Apply();
newTexture.name = texture.name;
return texture;
}
newTexture.Apply();
return newTexture;
}
private static Color[] MA_BilinearScale(Color[] curColors, int curWidth, int curHeight, int newWidth, int newHeight)
{
Color[] newColors = new Color[newWidth * newHeight];
public static Texture MA_Scale2(this Texture texture, float newWidth, float newHeight)
{
Texture2D texture2D = (Texture2D)MA_TextureUtils.ConvertToReadableTexture(texture);
float ratioX = 1.0f / ((float)newWidth / (curWidth - 1));
float ratioY = 1.0f / ((float)newHeight / (curHeight - 1));
texture = texture2D.MA_Scale22D(newWidth, newHeight);
for (int y = 0; y < newHeight; y++)
{
int yFloor = Mathf.FloorToInt(y * ratioY);
var y1 = yFloor * curWidth;
var y2 = (yFloor + 1) * curWidth;
var yw = y * newWidth;
return texture;
}
#endregion
for (int x = 0; x < newWidth; x++)
{
int xFloor = Mathf.FloorToInt(x * ratioX);
var xLerp = x * ratioX - xFloor;
#region combine
public static Texture2D MA_Combine2D(this Texture2D texture, Texture2D combineTexture, int offsetX, int offsetY, bool flipY = true)
newColors[yw + x] = ColorLerpUnclamped(ColorLerpUnclamped(curColors[y1 + xFloor], curColors[y1 + xFloor + 1], xLerp),
ColorLerpUnclamped(curColors[y2 + xFloor], curColors[y2 + xFloor + 1], xLerp),
y * ratioY - yFloor);
}
}
return newColors;
}
private static Color[] MA_PointScale(Color[] curColors, int curWidth, int curHeight, int newWidth, int newHeight)
{
Color[] newColors = new Color[newWidth * newHeight];
float ratioX = ((float)curWidth) / newWidth;
float ratioY = ((float)curHeight) / newHeight;
for (int y = 0; y < newHeight; y++)
{
var thisY = Mathf.RoundToInt((ratioY * y) * curWidth);
var yw = y * newWidth;
for (int x = 0; x < newWidth; x++)
{
newColors[yw + x] = curColors[Mathf.RoundToInt(thisY + ratioX * x)];
}
}
return newColors;
}
private static Color ColorLerpUnclamped(Color c1, Color c2, float value)
{
return new Color(c1.r + (c2.r - c1.r) * value,
c1.g + (c2.g - c1.g) * value,
c1.b + (c2.b - c1.b) * value,
c1.a + (c2.a - c1.a) * value);
}
#endregion
#region combine
public static Texture2D MA_Combine2D(this Texture2D texture, Texture2D combineTexture, int offsetX, int offsetY, bool flipY = true)
{
for (int x = 0; x < combineTexture.width; x++)
{
@ -172,7 +198,7 @@ namespace MA_Texture
//Y is 'flipped' because textures are made from left to right, bottom to top. We want to draw from left to right and top to bottom.
for (int y = combineTexture.height; y > 0; y--)
{
texture.SetPixel(x + offsetX, texture.height - y - offsetY, combineTexture.GetPixel(x, texture.height - y));
texture.SetPixel(x + offsetX, y + (texture.height - offsetY - combineTexture.height), combineTexture.GetPixel(x, y));
}
}
else
@ -192,7 +218,7 @@ namespace MA_Texture
public static Texture MA_Combine(this Texture texture, Texture combineTexture, int offsetX, int offsetY)
{
Texture2D texture2D = (Texture2D)MA_TextureUtils.ConvertToReadableTexture(texture);
Texture2D combineTexture2D = (Texture2D)MA_TextureUtils.ConvertToReadableTexture(texture);
Texture2D combineTexture2D = (Texture2D)MA_TextureUtils.ConvertToReadableTexture(combineTexture);
texture = texture2D.MA_Combine2D(combineTexture2D, offsetX, offsetY);
@ -200,4 +226,5 @@ namespace MA_Texture
}
#endregion
}
}
}
#endif

View File

@ -1,11 +1,21 @@
# MA_TextureAtlasser
Texture atlas creator for Unity
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.
[![Image](https://maxartz15.com/wp-content/uploads/2019/04/MA_TextureAtlas.png)]()
https://youtu.be/PBRKlopkZP0
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
For more information: https://maxartz15.com/ma_textureatlas/
[![Github All Releases](https://img.shields.io/github/downloads/maxartz15/MA_TextureAtlasser/total.svg)]()
For more information: https://maxartz15.com/ma-textureatlasser/