/////////////////////////////////////////////////////////////////////////////// // functions /////////////////////////////////////////////////////////////////////////////// // ------------------------------------------------------------------ // Desc: // ------------------------------------------------------------------ void Init() { if (nameToState == null) { initialized = false; } if (initialized == false) { initialized = true; sprite = GetComponent <exSprite>(); defaultAtlas = sprite.atlas; defaultIndex = sprite.index; nameToState = new Dictionary <string, exSpriteAnimState> (); for (int i = 0; i < animations.Count; ++i) { exSpriteAnimState state = new exSpriteAnimState(animations[i]); nameToState[state.name] = state; } if (defaultAnimation != null) { curAnimation = nameToState[defaultAnimation.name]; } } }
// ------------------------------------------------------------------ /// \param _obj /// Check if the object is valid atlas and open it in atlas editor. // ------------------------------------------------------------------ public void Edit( exAtlas _atlas ) { if ( _atlas == null ) return; curEdit = _atlas; Reset (); Repaint (); }
/////////////////////////////////////////////////////////////////////////////// // functions /////////////////////////////////////////////////////////////////////////////// // ------------------------------------------------------------------ // Desc: // ------------------------------------------------------------------ void UpdateEditObject() { if (lockCurEdit == false || curEdit == null) { exAtlas atlas = Selection.activeObject as exAtlas; if (atlas != null && atlas != curEdit) { Edit(atlas); } } }
// ------------------------------------------------------------------ /// \param _obj /// Check if the object is valid atlas and open it in atlas editor. // ------------------------------------------------------------------ public void Edit(exAtlas _atlas) { if (_atlas == null) { return; } curEdit = _atlas; Reset(); Repaint(); }
// ------------------------------------------------------------------ /// Clear the altas, material and mesh of the sprite, make it empty // ------------------------------------------------------------------ public void Clear() { atlas_ = null; index_ = -1; if (renderer != null) { renderer.sharedMaterial = null; } if (meshFilter) { DestroyImmediate(meshFilter_.sharedMesh, true); meshFilter_.sharedMesh = null; } }
// ------------------------------------------------------------------ /// Clear the altas, material and mesh of the sprite, make it empty // ------------------------------------------------------------------ public void Clear() { atlas_ = null; index_ = -1; if (GetComponent <Renderer>() != null) { GetComponent <Renderer>().sharedMaterial = null; } if (meshFilter) { DestroyImmediate(meshFilter_.sharedMesh, true); meshFilter_.sharedMesh = null; } }
// ------------------------------------------------------------------ /// \param _border the new gui-border /// \param _atlas the new atlas /// \param _index the index of the element in the new atlas /// Set a new picture in an atlas to this sprite // ------------------------------------------------------------------ public void SetBorder(exGUIBorder _border, exAtlas _atlas, int _index) { // pre-check if (_border == null || (_atlas != null && (_atlas.elements == null || _index < 0 || _index >= _atlas.elements.Length))) { Debug.LogWarning("Invalid input in SetBorder."); return; } // if (guiBorder_ != _border) { if (guiBorder_ == null || guiBorder_.border != _border.border) { updateFlags |= UpdateFlags.Vertex; } guiBorder_ = _border; } // if (atlas_ != _atlas) { atlas_ = _atlas; if (atlas_) { GetComponent <Renderer>().sharedMaterial = _atlas.material; } updateFlags |= UpdateFlags.UV; } // if (index_ != _index) { index_ = _index; updateFlags |= UpdateFlags.UV; } }
// ------------------------------------------------------------------ /// \param _path the directory path to save the atlas /// \param _name the name of the atlas /// \return the atlas /// create the atlas in the _path, save it as _name. // ------------------------------------------------------------------ public static exAtlas CreateAtlas(string _path, string _name) { if (new DirectoryInfo(_path).Exists == false) { Debug.LogError("can't create asset, path not found"); return(null); } if (string.IsNullOrEmpty(_name)) { Debug.LogError("can't create asset, the name is empty"); return(null); } string assetPath = Path.Combine(_path, _name + ".asset"); // exAtlas newAtlas = ScriptableObject.CreateInstance <exAtlas>(); AssetDatabase.CreateAsset(newAtlas, assetPath); Selection.activeObject = newAtlas; return(newAtlas); }
/////////////////////////////////////////////////////////////////////////////// // functions /////////////////////////////////////////////////////////////////////////////// // ------------------------------------------------------------------ // Desc: // ------------------------------------------------------------------ void Init() { if (initialized == false) { initialized = true; sprite = GetComponent <exSprite>(); defaultAtlas = sprite.atlas; defaultIndex = sprite.index; nameToState = new Dictionary <string, exSpriteAnimState> (); foreach (exSpriteAnimClip clip in animations) { exSpriteAnimState state = new exSpriteAnimState(clip); nameToState[state.name] = state; } if (defaultAnimation != null) { curAnimation = nameToState[defaultAnimation.name]; } } }
// ------------------------------------------------------------------ // Desc: // ------------------------------------------------------------------ public override void OnInspectorGUI() { // get old trim value serializedObject.Update(); SerializedProperty propTrim = serializedObject.FindProperty("trim"); bool oldTrim = propTrim.boolValue; DrawDefaultInspector(); // process trim property if (propTrim.boolValue != oldTrim) { foreach (Object obj in serializedObject.targetObjects) { exTextureInfo textureInfo = obj as exTextureInfo; if (textureInfo == null) { continue; } Texture2D rawTexture = exEditorUtility.LoadAssetFromGUID <Texture2D> (textureInfo.rawTextureGUID); if (rawTexture == null) { continue; } if (propTrim.boolValue) { Rect trimRect = exTextureUtility.GetTrimTextureRect(rawTexture, textureInfo.trimThreshold, new Rect(0, 0, rawTexture.width, rawTexture.height)); if (trimRect.width <= 0 || trimRect.height <= 0) { Debug.LogWarning("Can't not trim texture " + obj.name + ", empty pixel in it"); trimRect = new Rect(0, 0, rawTexture.width, rawTexture.height); textureInfo.trim = false; } textureInfo.trim_x = (int)trimRect.x; textureInfo.trim_y = (int)trimRect.y; textureInfo.width = (int)trimRect.width; textureInfo.height = (int)trimRect.height; } else { textureInfo.trim_x = 0; textureInfo.trim_y = 0; textureInfo.width = rawTexture.width; textureInfo.height = rawTexture.height; } EditorUtility.SetDirty(textureInfo); } } // if (serializedObject.isEditingMultipleObjects == false) { GUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); // Select if (GUILayout.Button("Select...", GUILayout.Width(60), GUILayout.Height(20))) { exTextureInfo textureInfo = target as exTextureInfo; Texture texture = exEditorUtility.LoadAssetFromGUID <Texture>(textureInfo.rawTextureGUID); EditorGUIUtility.PingObject(texture); } // Atlas if (GUILayout.Button("Atlas...", GUILayout.Width(60), GUILayout.Height(20))) { exAtlasEditor editor = EditorWindow.GetWindow <exAtlasEditor>(); exTextureInfo textureInfo = target as exTextureInfo; exAtlas atlas = exEditorUtility.LoadAssetFromGUID <exAtlas>(textureInfo.rawAtlasGUID); editor.Edit(atlas); } // Edit if (GUILayout.Button("Edit...", GUILayout.Width(60), GUILayout.Height(20))) { exTextureInfoEditor editor = EditorWindow.GetWindow <exTextureInfoEditor>(); exTextureInfo textureInfo = target as exTextureInfo; editor.Edit(textureInfo); } GUILayout.Space(5); GUILayout.EndHorizontal(); } }
// ------------------------------------------------------------------ // Desc: // ------------------------------------------------------------------ public static void Build( exAtlas _atlas, System.Action<float,string> _progress ) { TextureImporter importSettings = null; string atlasAssetsDir = Path.Combine( Path.GetDirectoryName (AssetDatabase.GetAssetPath(_atlas)), _atlas.name ); string atlasTexturePath = Path.Combine( atlasAssetsDir, _atlas.name + ".png" ); // check if create atlas directory _progress( 0.1f, "Checking atlas directory" ); if ( new DirectoryInfo(atlasAssetsDir).Exists == false ) { Directory.CreateDirectory (atlasAssetsDir); AssetDatabase.ImportAsset (atlasAssetsDir); } // destroy last built texture Texture2D atlasTexture = _atlas.texture; if ( atlasTexture ) { AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(atlasTexture)); } // check if create atlas texture _progress( 0.2f, "Checking atlas texture" ); atlasTexture = AssetDatabase.LoadAssetAtPath( atlasTexturePath, typeof(Texture2D) ) as Texture2D; if ( atlasTexture == null || atlasTexture.width != _atlas.width || atlasTexture.height != _atlas.height ) { atlasTexture = new Texture2D( _atlas.width, _atlas.height, TextureFormat.ARGB32, false ); // save texture to png File.WriteAllBytes(atlasTexturePath, atlasTexture.EncodeToPNG()); Object.DestroyImmediate(atlasTexture); AssetDatabase.ImportAsset( atlasTexturePath, ImportAssetOptions.ForceSynchronousImport ); // setup new texture importSettings = TextureImporter.GetAtPath(atlasTexturePath) as TextureImporter; importSettings.maxTextureSize = Mathf.Max( _atlas.width, _atlas.height ); importSettings.textureFormat = TextureImporterFormat.AutomaticTruecolor; importSettings.isReadable = true; importSettings.wrapMode = TextureWrapMode.Clamp; importSettings.mipmapEnabled = false; importSettings.textureType = TextureImporterType.Advanced; importSettings.npotScale = TextureImporterNPOTScale.None; importSettings.textureType = TextureImporterType.Advanced; #if UNITY_4_3 importSettings.spriteImportMode = SpriteImportMode.None; #endif importSettings.textureFormat = TextureImporterFormat.ARGB32; importSettings.ClearPlatformTextureSettings("Web"); importSettings.ClearPlatformTextureSettings("Standalone"); importSettings.ClearPlatformTextureSettings("iPhone"); importSettings.ClearPlatformTextureSettings("Android"); importSettings.ClearPlatformTextureSettings("FlashPlayer"); AssetDatabase.ImportAsset( atlasTexturePath, ImportAssetOptions.ForceSynchronousImport ); atlasTexture = (Texture2D)AssetDatabase.LoadAssetAtPath( atlasTexturePath, typeof(Texture2D) ); } // clean the atlas _progress( 0.3f, "Cleaning atlas texture" ); bool needReimport = false; importSettings = TextureImporter.GetAtPath(atlasTexturePath) as TextureImporter; if ( importSettings.isReadable == false ) { importSettings.isReadable = true; needReimport = true; } if ( needReimport ) { AssetDatabase.ImportAsset( atlasTexturePath, ImportAssetOptions.ForceSynchronousImport ); } Color buildColor = new Color(0.0f, 0.0f, 0.0f, 0.0f); if ( _atlas.customBuildColor ) { buildColor = _atlas.buildColor; } for ( int i = 0; i < _atlas.width; ++i ) { for ( int j = 0; j < _atlas.height; ++j ) { atlasTexture.SetPixel(i, j, buildColor ); } } atlasTexture.Apply(false); string rawAtlasGUID = exEditorUtility.AssetToGUID(_atlas); Color32[] pixels = new Color32[atlasTexture.width * atlasTexture.height]; // fill raw texture-info to atlas _progress( 0.4f, "Filling texture-info to atlas" ); foreach ( exTextureInfo textureInfo in _atlas.textureInfos ) { Texture2D rawTexture = exEditorUtility.LoadAssetFromGUID<Texture2D>(textureInfo.rawTextureGUID); if ( exEditorUtility.IsValidForAtlas(rawTexture) == false ) { exEditorUtility.ImportTextureForAtlas(rawTexture); } bool dirty = false; if ( textureInfo.rawAtlasGUID != rawAtlasGUID ) { textureInfo.rawAtlasGUID = rawAtlasGUID; dirty = true; } if ( textureInfo.texture != atlasTexture ) { textureInfo.texture = atlasTexture; dirty = true; } if ( dirty ) EditorUtility.SetDirty(textureInfo); // copy raw texture into atlas texture if ( textureInfo.isDiced ) { foreach (exTextureInfo.Dice dice in textureInfo.dices) { if (dice.sizeType != exTextureInfo.DiceType.Empty) { exTextureUtility.Fill( ref pixels , atlasTexture.width , rawTexture , textureInfo.name + "[" + dice.offset_x + "]" + "[" + dice.offset_y + "]" , dice.x , dice.y , dice.trim_x , dice.trim_y , dice.width , dice.height , dice.rotated ); } } } else { exTextureUtility.Fill( ref pixels , atlasTexture.width , rawTexture , textureInfo.name , textureInfo.x , textureInfo.y , textureInfo.trim_x , textureInfo.trim_y , textureInfo.width , textureInfo.height , textureInfo.rotated ); } } // fill raw bitmapfont to atlas _progress( 0.6f, "Filling bitmap-font to atlas" ); foreach ( exBitmapFont bitmapFont in _atlas.bitmapFonts ) { Texture2D rawTexture = exEditorUtility.LoadAssetFromGUID<Texture2D>(bitmapFont.rawTextureGUID); if ( exEditorUtility.IsValidForAtlas(rawTexture) == false ) { exEditorUtility.ImportTextureForAtlas(rawTexture); } bool dirty = false; if ( bitmapFont.rawAtlasGUID != rawAtlasGUID ) { bitmapFont.rawAtlasGUID = rawAtlasGUID; dirty = true; } if ( bitmapFont.texture != atlasTexture ) { bitmapFont.texture = atlasTexture; dirty = true; } if ( dirty ) EditorUtility.SetDirty(bitmapFont); foreach ( exBitmapFont.CharInfo charInfo in bitmapFont.charInfos ) { // copy raw texture into atlas texture exTextureUtility.Fill( ref pixels , atlasTexture.width , rawTexture , bitmapFont.name + "@" + charInfo.id , charInfo.x , charInfo.y , charInfo.trim_x , charInfo.trim_y , charInfo.width , charInfo.height , charInfo.rotated ); // DISABLE: character don't need padding bleed { // // apply padding bleed // if ( _atlas.usePaddingBleed ) { // exTextureUtility.ApplyPaddingBleed( atlasTexture, // new Rect( charInfo.x, charInfo.y, charInfo.width, charInfo.height ) ); // } // } DISABLE end } } atlasTexture.SetPixels32(pixels); // _progress( 0.8f, "Bleed the texture" ); ApplyBleed ( _atlas, atlasTexture ); // write new atlas texture to disk _progress( 1.0f, "Importing atlas texture" ); File.WriteAllBytes(atlasTexturePath, atlasTexture.EncodeToPNG()); AssetDatabase.ImportAsset( atlasTexturePath, ImportAssetOptions.ForceSynchronousImport ); // turn-off readable to save memory if ( _atlas.readable == false ) { importSettings = TextureImporter.GetAtPath(atlasTexturePath) as TextureImporter; importSettings.isReadable = false; AssetDatabase.ImportAsset( atlasTexturePath, ImportAssetOptions.ForceSynchronousImport ); } // _atlas.texture = (Texture2D)AssetDatabase.LoadAssetAtPath( atlasTexturePath, typeof(Texture2D) ); _atlas.needRebuild = false; EditorUtility.SetDirty(_atlas); AssetDatabase.SaveAssets(); }
// ------------------------------------------------------------------ /// \param _border the new gui-border /// \param _atlas the new atlas /// \param _index the index of the element in the new atlas /// Set a new picture in an atlas to this sprite // ------------------------------------------------------------------ public void SetBorder( exGUIBorder _border, exAtlas _atlas, int _index ) { // pre-check if ( _border == null || ( _atlas != null && ( _atlas.elements == null || _index < 0 || _index >= _atlas.elements.Length ) ) ) { Debug.LogWarning ( "Invalid input in SetBorder." ); return; } // if ( guiBorder_ != _border ) { if ( guiBorder_ == null || guiBorder_.border != _border.border ) { updateFlags |= UpdateFlags.Vertex; } guiBorder_ = _border; } // if ( atlas_ != _atlas ) { atlas_ = _atlas; if ( atlas_ ) renderer.sharedMaterial = _atlas.material; updateFlags |= UpdateFlags.UV; } // if ( index_ != _index ) { index_ = _index; updateFlags |= UpdateFlags.UV; } }
// ------------------------------------------------------------------ // Desc: // ------------------------------------------------------------------ public override void OnInspectorGUI() { // ======================================================== // Base GUI // ======================================================== base.OnInspectorGUI(); GUILayout.Space(20); // ======================================================== // init values // ======================================================== // bool needRebuild = false; editSprite.spanim = editSprite.GetComponent <exSpriteAnimation>(); // get ElementInfo first Texture2D editTexture = exEditorHelper.LoadAssetFromGUID <Texture2D>(editSprite.textureGUID); // ======================================================== // Texture preview (input) // ======================================================== bool textureChanged = false; GUI.enabled = !inAnimMode; GUILayout.BeginHorizontal(); GUILayout.Space(20); EditorGUIUtility.LookLikeControls(); Texture2D newTexture = (Texture2D)EditorGUILayout.ObjectField(editTexture , typeof(Texture2D) , false , GUILayout.Width(100) , GUILayout.Height(100) ); EditorGUIUtility.LookLikeInspector(); if (newTexture != editTexture) { editTexture = newTexture; editSprite.textureGUID = exEditorHelper.AssetToGUID(editTexture); textureChanged = true; GUI.changed = true; } GUILayout.Space(10); GUILayout.BeginVertical(); GUILayout.Space(90); GUILayout.Label(editTexture ? editTexture.name : "None"); GUILayout.EndVertical(); GUILayout.EndHorizontal(); GUI.enabled = true; // ======================================================== // get atlas element info from atlas database // ======================================================== exAtlas editAtlas = null; int editIndex = -1; exAtlasDB.ElementInfo elInfo = exAtlasDB.GetElementInfo(editSprite.textureGUID); if (elInfo != null) { editAtlas = exEditorHelper.LoadAssetFromGUID <exAtlas>(elInfo.guidAtlas); editIndex = elInfo.indexInAtlas; } bool useAtlas = editAtlas != null && editIndex != -1; // get atlas and index from textureGUID if (!EditorApplication.isPlaying) { // if we don't use atlas and current edit target use atlas, clear it. if (editSprite.useAtlas != useAtlas) { editSprite.Clear(); } // if we use atlas, check if the atlas,index changes if (useAtlas) { if (editAtlas != editSprite.atlas || editIndex != editSprite.index) { editSprite.SetSprite(editAtlas, editIndex); GUI.changed = true; } } // check if we are first time assignment if (useAtlas || editTexture != null) { if (isPrefab == false && editSprite.meshFilter.sharedMesh == null) { needRebuild = true; } } } // ======================================================== // get trimTexture // ======================================================== GUI.enabled = !inAnimMode && !useAtlas; bool newTrimTexture = EditorGUILayout.Toggle("Trim Texture", editSprite.trimTexture); if (!useAtlas && (textureChanged || newTrimTexture != editSprite.trimTexture)) { editSprite.GetComponent <Renderer>().sharedMaterial = exEditorHelper.GetDefaultMaterial(editTexture, editTexture.name); editSprite.trimTexture = newTrimTexture; // get trimUV Rect trimUV = new Rect(0, 0, 1, 1); if (editTexture != null) { if (editSprite.trimTexture) { if (exTextureHelper.IsValidForAtlas(editTexture) == false) { exTextureHelper.ImportTextureForAtlas(editTexture); } trimUV = exTextureHelper.GetTrimTextureRect(editTexture); trimUV = new Rect(trimUV.x / editTexture.width, (editTexture.height - trimUV.height - trimUV.y) / editTexture.height, trimUV.width / editTexture.width, trimUV.height / editTexture.height); } if (editSprite.customSize == false) { editSprite.width = trimUV.width * editTexture.width; editSprite.height = trimUV.height * editTexture.height; } } editSprite.trimUV = trimUV; editSprite.updateFlags |= exPlane.UpdateFlags.UV; editSprite.updateFlags |= exPlane.UpdateFlags.Vertex; } GUI.enabled = true; // ======================================================== // color // ======================================================== editSprite.color = EditorGUILayout.ColorField("Color", editSprite.color); // ======================================================== // atlas & index // ======================================================== GUILayout.BeginHorizontal(); GUI.enabled = false; EditorGUILayout.ObjectField("Atlas" , editSprite.atlas , typeof(exAtlas) , false ); GUI.enabled = true; GUI.enabled = !inAnimMode; if (GUILayout.Button("Edit...", GUILayout.Width(40), GUILayout.Height(15))) { exAtlasEditor editor = exAtlasEditor.NewWindow(); editor.Edit(editSprite.atlas); } GUI.enabled = true; GUILayout.EndHorizontal(); GUI.enabled = false; EditorGUILayout.IntField("Index", editSprite.index); GUI.enabled = true; // ======================================================== // custom size // ======================================================== GUI.enabled = !inAnimMode; editSprite.customSize = EditorGUILayout.Toggle("Custom Size", editSprite.customSize); GUI.enabled = true; // ======================================================== // width & height // ======================================================== ++EditorGUI.indentLevel; GUI.enabled = !inAnimMode && editSprite.customSize; // width float newWidth = EditorGUILayout.FloatField("Width", editSprite.width); if (newWidth != editSprite.width) { if (newWidth < 1.0f) { newWidth = 1.0f; } editSprite.width = newWidth; } // height float newHeight = EditorGUILayout.FloatField("Height", editSprite.height); if (newHeight != editSprite.height) { if (newHeight < 1.0f) { newHeight = 1.0f; } editSprite.height = newHeight; } --EditorGUI.indentLevel; // ======================================================== // Reset to original // ======================================================== GUILayout.BeginHorizontal(); GUILayout.Space(30); if (GUILayout.Button("Reset", GUILayout.Width(50))) { if (useAtlas) { exAtlas.Element el = editAtlas.elements[editIndex]; editSprite.width = el.trimRect.width; editSprite.height = el.trimRect.height; } else if (editTexture) { editSprite.width = editSprite.trimUV.width * editTexture.width; editSprite.height = editSprite.trimUV.height * editTexture.height; } GUI.changed = true; } GUILayout.EndHorizontal(); GUI.enabled = true; // ======================================================== // Rebuild button // ======================================================== GUI.enabled = !inAnimMode; GUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); if (GUILayout.Button("Rebuild...", GUILayout.Height(20))) { needRebuild = true; } GUILayout.EndHorizontal(); GUI.enabled = true; GUILayout.Space(5); // if dirty, build it. if (!EditorApplication.isPlaying && !AnimationUtility.InAnimationMode()) { if (needRebuild) { EditorUtility.ClearProgressBar(); editSprite.Build(editTexture); } else if (GUI.changed) { if (editSprite.meshFilter.sharedMesh != null) { editSprite.UpdateMesh(editSprite.meshFilter.sharedMesh); } EditorUtility.SetDirty(editSprite); } } }
// ------------------------------------------------------------------ /// \param _atlas the new atlas /// \param _index the index of the element in the new atlas /// Set a new picture in an atlas to this sprite // ------------------------------------------------------------------ public void SetSprite( exAtlas _atlas, int _index ) { bool checkSize = false; // pre-check if ( _atlas == null || _atlas.elements == null || _index < 0 || _index >= _atlas.elements.Length ) { Debug.LogWarning ( "Invalid input in SetSprite." ); return; } // if ( atlas_ != _atlas ) { atlas_ = _atlas; renderer.sharedMaterial = _atlas.material; updateFlags |= UpdateFlags.UV; checkSize = true; } // if ( index_ != _index ) { index_ = _index; updateFlags |= UpdateFlags.UV; checkSize = true; } // if ( checkSize && !customSize_ ) { exAtlas.Element el = atlas_.elements[index_]; float newWidth = el.trimRect.width; float newHeight = el.trimRect.height; // float newWidth = el.coords.width * atlas_.texture.width; // float newHeight = el.coords.height * atlas_.texture.height; if ( el.rotated ) { float tmp = newWidth; newWidth = newHeight; newHeight = tmp; } if ( newWidth != width_ || newHeight != height_ ) { width_ = newWidth; height_ = newHeight; updateFlags |= UpdateFlags.Vertex; } } }
/// <summary> /// Change the sprite image from another image in the same (or different atlas), using the specific index /// </summary> /// <param name='sprite'> /// Sprite. exSprite to be changed /// </param> /// <param name='atlas'> /// Atlas. exAtlas (may be the same atlas or a new one) /// </param> /// <param name='index'> /// Index. int (the identifier of the new Sprite) /// </param> private static void ChangeSprite(exSprite sprite, exAtlas atlas, int index) { float width = sprite.width; float height = sprite.height; sprite.SetSprite(atlas,index,false); sprite.height = height; sprite.width = width; }
/////////////////////////////////////////////////////////////////////////////// // functions /////////////////////////////////////////////////////////////////////////////// // ------------------------------------------------------------------ // Desc: // ------------------------------------------------------------------ void Init () { if ( initialized == false ) { initialized = true; sprite = GetComponent<exSprite>(); defaultAtlas = sprite.atlas; defaultIndex = sprite.index; nameToState = new Dictionary<string,exSpriteAnimState> (); foreach ( exSpriteAnimClip clip in animations ) { exSpriteAnimState state = new exSpriteAnimState(clip); nameToState[state.name] = state; } if ( defaultAnimation != null ) curAnimation = nameToState[defaultAnimation.name]; } }
/////////////////////////////////////////////////////////////////////////////// // functions /////////////////////////////////////////////////////////////////////////////// // ------------------------------------------------------------------ // Desc: // ------------------------------------------------------------------ public static List<Element> GetElementList( exAtlas _atlas ) { List<Element> elements = new List<Element>(); foreach ( exTextureInfo info in _atlas.textureInfos ) { if ( info.shouldDiced ) { int editorDiceCount = info.editorDiceXCount * info.editorDiceYCount; for ( int diceIndex = 0; diceIndex < editorDiceCount; ++diceIndex ) { exTextureInfo.Dice dice = info.GetDiceData(diceIndex); Element el = new Element(); el.x = 0; el.y = 0; el.rotated = false; el.textureInfo = info; el.id = info.name + "@" + diceIndex; el.dicedID = diceIndex; el.width = dice.width; el.height = dice.height; elements.Add(el); } } else { Element el = new Element(); el.x = 0; el.y = 0; el.rotated = false; el.textureInfo = info; el.id = info.name; el.width = info.width; el.height = info.height; elements.Add(el); } } foreach ( exBitmapFont bitmapFont in _atlas.bitmapFonts ) { foreach ( exBitmapFont.CharInfo info in bitmapFont.charInfos ) { Element el = new Element(); el.x = 0; el.y = 0; el.rotated = false; el.charInfo = info; el.id = info.id + "@" + bitmapFont.name; el.width = info.width; el.height = info.height; elements.Add(el); } } return elements; }
// ------------------------------------------------------------------ /// \param _atlas the new atlas /// \param _index the index of the element in the new atlas /// Set a new picture in an atlas to this sprite // ------------------------------------------------------------------ public void SetSprite(exAtlas _atlas, int _index) { bool checkVertex = false; bool createMesh = false; // pre-check if (_atlas == null || _atlas.elements == null || _index < 0 || _index >= _atlas.elements.Length) { Debug.LogWarning("Invalid input in SetSprite. atlas = " + (_atlas ? _atlas.name : "null") + ", index = " + _index); return; } // it is possible that the atlas is null and we don't have mesh if (atlas_ == null) { createMesh = true; } // if (atlas_ != _atlas) { atlas_ = _atlas; renderer.sharedMaterial = _atlas.material; updateFlags |= UpdateFlags.UV; checkVertex = true; } // if (index_ != _index) { index_ = _index; updateFlags |= UpdateFlags.UV; checkVertex = true; } // if (checkVertex) { // NOTE: if we use texture offset, it always need to update vertex if (useTextureOffset_) { updateFlags |= UpdateFlags.Vertex; } if (!customSize_) { exAtlas.Element el = atlas_.elements[index_]; float newWidth = el.trimRect.width; float newHeight = el.trimRect.height; // float newWidth = el.coords.width * atlas_.texture.width; // float newHeight = el.coords.height * atlas_.texture.height; if (el.rotated) { float tmp = newWidth; newWidth = newHeight; newHeight = tmp; } if (newWidth != width_ || newHeight != height_) { width_ = newWidth; height_ = newHeight; updateFlags |= UpdateFlags.Vertex; } } } // if (createMesh) { // create mesh ( in editor, this can duplicate mesh to prevent shared mesh for sprite) meshFilter_.mesh = new Mesh(); updateFlags = UpdateFlags.Vertex | UpdateFlags.UV | UpdateFlags.Color | UpdateFlags.Index; // check if update mesh collider MeshCollider meshCollider = collider as MeshCollider; if (meshCollider && meshCollider.sharedMesh == null) { this.UpdateColliderSize(0.2f); } } }
// ------------------------------------------------------------------ // Desc: // ------------------------------------------------------------------ public static void ImportObjects( exAtlas _atlas, Object[] _objects, System.Action<float,string> _progress ) { string atlasAssetsDir = Path.Combine( Path.GetDirectoryName (AssetDatabase.GetAssetPath(_atlas)), _atlas.name ); // check if create atlas directory _progress( 0.1f, "Checking atlas directory" ); if ( new DirectoryInfo(atlasAssetsDir).Exists == false ) { Directory.CreateDirectory (atlasAssetsDir); AssetDatabase.ImportAsset (atlasAssetsDir); } // import textures used for atlas _progress( 0.2f, "Setup texture for atlas" ); try { AssetDatabase.StartAssetEditing(); foreach ( Object o in _objects ) { if ( o is Texture2D ) { exEditorUtility.ImportTextureForAtlas (o as Texture2D); } } } finally { AssetDatabase.StopAssetEditing(); } // bool noToAll = false; for ( int i = 0; i < _objects.Length; ++i ) { Object o = _objects[i]; _progress( 0.2f + (float)i/(float)_objects.Length * 0.8f, "Add element " + o.name ); if ( o is Texture2D ) { Texture2D rawTexture = o as Texture2D; // if the texture already in the atlas, warning and skip it. if ( exAtlasUtility.Exists(_atlas,rawTexture) ) { Debug.LogWarning ( "The texture " + o.name + " already exists in the atlas" ); continue; } bool trimmed = false; Rect trimRect = new Rect ( 0, 0, rawTexture.width, rawTexture.height ); if ( _atlas.trimElements ) { Rect trimResult = exTextureUtility.GetTrimTextureRect( rawTexture, _atlas.trimThreshold, new Rect( 0, 0, rawTexture.width, rawTexture.height ) ); if ( trimResult.width > 0 && trimResult.height > 0 ) { trimmed = true; trimRect = trimResult; } else { Debug.LogWarning ( "Can't not trim texture " + o.name + ", empty pixel in it" ); } } // exTextureInfo textureInfo = exGenericAssetUtility<exTextureInfo>.LoadExistsOrCreate( atlasAssetsDir, rawTexture.name ); int result = 1; if ( noToAll == false && string.IsNullOrEmpty(textureInfo.rawTextureGUID) == false && textureInfo.rawTextureGUID != exEditorUtility.AssetToGUID(rawTexture) ) { result = EditorUtility.DisplayDialogComplex( "Texture Info " + textureInfo.name + " already exists, it is bind to texture " + AssetDatabase.GUIDToAssetPath(textureInfo.rawTextureGUID), "Do you want to bind it with new texture " + AssetDatabase.GetAssetPath(rawTexture), "No", // 0 "Yes", // 1 "No to all" // 2 ); if ( result == 2 ) noToAll = true; } if ( noToAll == false && result == 1 ) { textureInfo.rawAtlasGUID = exEditorUtility.AssetToGUID(_atlas); textureInfo.rawTextureGUID = exEditorUtility.AssetToGUID(rawTexture); textureInfo.name = rawTexture.name; textureInfo.texture = _atlas.texture; textureInfo.rawWidth = rawTexture.width; textureInfo.rawHeight = rawTexture.height; textureInfo.x = 0; textureInfo.y = 0; textureInfo.trim_x = (int)trimRect.x; textureInfo.trim_y = (int)trimRect.y; textureInfo.width = (int)trimRect.width; textureInfo.height = (int)trimRect.height; textureInfo.trim = trimmed; textureInfo.trimThreshold = _atlas.trimThreshold; EditorUtility.SetDirty(textureInfo); } textureInfo.ClearDiceData(); // trim diced data if ( textureInfo.shouldDiced ) { textureInfo.GenerateDiceData(); textureInfo.BeginDiceData(); int editorDiceCount = textureInfo.editorDiceXCount * textureInfo.editorDiceYCount; for ( int diceIndex = 0; diceIndex < editorDiceCount; ++diceIndex ) { exTextureInfo.Dice dice = textureInfo.GetDiceData(diceIndex); Rect trimResult = exTextureUtility.GetTrimTextureRect( rawTexture, textureInfo.trimThreshold, new Rect( dice.trim_x, dice.trim_y, dice.width, dice.height ) ); // dice.offset_x = (int)(trimResult.x - dice.trim_x); dice.offset_y = (int)(trimResult.y - dice.trim_y); dice.width = (int)trimResult.width; dice.height = (int)trimResult.height; textureInfo.SetDiceData( diceIndex, dice ); } textureInfo.EndDiceData(); } if ( _atlas.textureInfos.IndexOf(textureInfo) == -1 ) _atlas.textureInfos.Add(textureInfo); } else { Object rawFontInfo = o; if ( o is exBitmapFont ) { exBitmapFont bitmapFont = o as exBitmapFont; rawFontInfo = exEditorUtility.LoadAssetFromGUID<Object>( bitmapFont.rawFontGUID ); if ( rawFontInfo == null ) { Debug.LogWarning ( "Can't not find raw font info from " + bitmapFont.name ); } } // start parsing font-info if ( rawFontInfo != null && exBitmapFontUtility.IsFontInfo(rawFontInfo) ) { bool doReplace = true; exBitmapFont bitmapFont = exGenericAssetUtility<exBitmapFont>.LoadExistsOrCreate( atlasAssetsDir, rawFontInfo.name ); if ( string.IsNullOrEmpty(bitmapFont.rawFontGUID) == false && bitmapFont.rawFontGUID != exEditorUtility.AssetToGUID(rawFontInfo) ) { doReplace = EditorUtility.DisplayDialog( "BitmapFont " + bitmapFont.name + " already exists, it is bind to font-info " + AssetDatabase.GUIDToAssetPath(bitmapFont.rawFontGUID), "Do you want to bind it with new font-info " + AssetDatabase.GetAssetPath(rawFontInfo), "Yes", "No" ); } if ( doReplace ) { bitmapFont.rawAtlasGUID = exEditorUtility.AssetToGUID(_atlas); if ( exBitmapFontUtility.Parse( bitmapFont, rawFontInfo ) ) { bitmapFont.texture = _atlas.texture; // overwrite the raw texture if ( _atlas.bitmapFonts.IndexOf(bitmapFont) == -1 ) _atlas.bitmapFonts.Add(bitmapFont); } else { AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(bitmapFont)); Debug.LogError ( "Parse Error: " + rawFontInfo.name ); } } } } } _atlas.needLayout = true; _atlas.needRebuild = true; EditorUtility.SetDirty(_atlas); }
// ------------------------------------------------------------------ // Desc: // ------------------------------------------------------------------ public static void Pack( List<Element> _elements, exAtlas.Algorithm _algorithm, int _atlasWidth, int _atlasHeight, int _padding, bool _allowRotate ) { switch ( _algorithm ) { case exAtlas.Algorithm.Basic: BasicPack ( _elements, _atlasWidth, _atlasHeight, _padding, _allowRotate ); break; case exAtlas.Algorithm.Tree: TreePack ( _elements, _atlasWidth, _atlasHeight, _padding, _allowRotate ); break; case exAtlas.Algorithm.MaxRect: MaxRectPack ( _elements, _atlasWidth, _atlasHeight, _padding, _allowRotate ); break; } }
// ------------------------------------------------------------------ // Desc: // ------------------------------------------------------------------ static void ApplyBleed( exAtlas _atlas, Texture2D _atlasTexture ) { // if ( _atlas.useContourBleed ) { Color32[] srcPixels = _atlasTexture.GetPixels32(0); Color32[] result = new Color32[srcPixels.Length]; for ( int i = 0; i < srcPixels.Length; ++i ) { result[i] = srcPixels[i]; } foreach ( exTextureInfo textureInfo in _atlas.textureInfos ) { // copy raw texture into atlas texture if ( textureInfo.isDiced ) { foreach (exTextureInfo.Dice dice in textureInfo.dices) { if (dice.sizeType != exTextureInfo.DiceType.Empty) { exTextureUtility.ApplyContourBleed ( ref result, srcPixels, _atlasTexture.width, new Rect( dice.x, dice.y, dice.rotatedWidth, dice.rotatedHeight ) ); } } } else { exTextureUtility.ApplyContourBleed ( ref result, srcPixels, _atlasTexture.width, new Rect( textureInfo.x, textureInfo.y, textureInfo.rotatedWidth, textureInfo.rotatedHeight ) ); } } foreach ( exBitmapFont bitmapFont in _atlas.bitmapFonts ) { foreach ( exBitmapFont.CharInfo charInfo in bitmapFont.charInfos ) { exTextureUtility.ApplyContourBleed( ref result, srcPixels, _atlasTexture.width, new Rect( charInfo.x, charInfo.y, charInfo.rotatedWidth, charInfo.rotatedHeight ) ); } } _atlasTexture.SetPixels32(result); } // if ( _atlas.usePaddingBleed ) { Color32[] srcPixels = _atlasTexture.GetPixels32(0); Color32[] result = new Color32[srcPixels.Length]; for ( int i = 0; i < srcPixels.Length; ++i ) { result[i] = srcPixels[i]; } foreach ( exTextureInfo textureInfo in _atlas.textureInfos ) { // copy raw texture into atlas texture if ( textureInfo.isDiced ) { foreach (exTextureInfo.Dice dice in textureInfo.dices) { if (dice.sizeType != exTextureInfo.DiceType.Empty) { exTextureUtility.ApplyPaddingBleed ( ref result, srcPixels, _atlasTexture.width, _atlasTexture.height, new Rect( dice.x, dice.y, dice.rotatedWidth, dice.rotatedHeight ) ); } } } else { exTextureUtility.ApplyPaddingBleed ( ref result, srcPixels, _atlasTexture.width, _atlasTexture.height, new Rect( textureInfo.x, textureInfo.y, textureInfo.rotatedWidth, textureInfo.rotatedHeight ) ); } } foreach ( exBitmapFont bitmapFont in _atlas.bitmapFonts ) { foreach ( exBitmapFont.CharInfo charInfo in bitmapFont.charInfos ) { exTextureUtility.ApplyPaddingBleed( ref result, srcPixels, _atlasTexture.width, _atlasTexture.height, new Rect( charInfo.x, charInfo.y, charInfo.rotatedWidth, charInfo.rotatedHeight ) ); } } _atlasTexture.SetPixels32(result); } }
// ------------------------------------------------------------------ // Desc: // ------------------------------------------------------------------ public static void Sync( exAtlas _atlas, System.Action<float,string> _progress ) { string atlasAssetsDir = Path.Combine( Path.GetDirectoryName (AssetDatabase.GetAssetPath(_atlas)), _atlas.name ); string rawAtlasGUID = exEditorUtility.AssetToGUID(_atlas); // check if create atlas directory _progress( 0.1f, "Checking atlas directory" ); if ( new DirectoryInfo(atlasAssetsDir).Exists == false ) { Directory.CreateDirectory (atlasAssetsDir); AssetDatabase.ImportAsset (atlasAssetsDir); } // texture info _progress( 0.4f, "Syncing texture infos" ); AssetDatabase.StartAssetEditing(); for ( int i = 0; i < _atlas.textureInfos.Count; ++i ) { // check textureInfo itself exTextureInfo textureInfo = _atlas.textureInfos[i]; string textureInfoPath = AssetDatabase.GetAssetPath(textureInfo); if ( textureInfo == null ) { _atlas.textureInfos.RemoveAt(i); AssetDatabase.DeleteAsset ( textureInfoPath ); --i; continue; } // check raw-texture string rawTexturePath = AssetDatabase.GUIDToAssetPath(textureInfo.rawTextureGUID); string rawTextureName = Path.GetFileNameWithoutExtension(rawTexturePath); Texture2D rawTexture = (Texture2D)AssetDatabase.LoadAssetAtPath( rawTexturePath, typeof(Texture2D) ); if ( rawTexture == null ) { _atlas.textureInfos.RemoveAt(i); AssetDatabase.DeleteAsset ( textureInfoPath ); --i; continue; } // check if texture info same with raw-texture string expectPath = Path.Combine( atlasAssetsDir, rawTextureName + ".asset" ); expectPath = expectPath.Replace("\\", "/"); if ( textureInfoPath != expectPath ) { bool doMove = true; FileInfo fileInfo = new FileInfo(expectPath); if ( fileInfo.Exists ) { doMove = EditorUtility.DisplayDialog( "Texture Info " + rawTextureName + " already exists", "Do you want to replace it with new texture infor?", "Yes", "No" ); } if ( doMove ) { AssetDatabase.DeleteAsset ( expectPath ); AssetDatabase.MoveAsset ( textureInfoPath, expectPath ); } } // Rect trimRect = new Rect ( 0, 0, rawTexture.width, rawTexture.height ); if ( textureInfo.trim ) { trimRect = exTextureUtility.GetTrimTextureRect( rawTexture, textureInfo.trimThreshold, new Rect(0, 0, rawTexture.width, rawTexture.height) ); } textureInfo.rawAtlasGUID = exEditorUtility.AssetToGUID(_atlas); textureInfo.name = rawTexture.name; textureInfo.rawWidth = rawTexture.width; textureInfo.rawHeight = rawTexture.height; textureInfo.trim_x = (int)trimRect.x; textureInfo.trim_y = (int)trimRect.y; textureInfo.width = (int)trimRect.width; textureInfo.height = (int)trimRect.height; textureInfo.ClearDiceData(); // trim diced data if ( textureInfo.shouldDiced ) { textureInfo.GenerateDiceData(); textureInfo.BeginDiceData(); int editorDiceCount = textureInfo.editorDiceXCount * textureInfo.editorDiceYCount; for ( int diceIndex = 0; diceIndex < editorDiceCount; ++diceIndex ) { exTextureInfo.Dice dice = textureInfo.GetDiceData(diceIndex); Rect trimResult = exTextureUtility.GetTrimTextureRect( rawTexture, textureInfo.trimThreshold, new Rect( dice.trim_x, dice.trim_y, dice.width, dice.height ) ); // dice.offset_x = (int)(trimResult.x - dice.trim_x); dice.offset_y = (int)(trimResult.y - dice.trim_y); dice.width = (int)trimResult.width; dice.height = (int)trimResult.height; textureInfo.SetDiceData( diceIndex, dice ); } textureInfo.EndDiceData(); } } // bitmapfont _progress( 0.6f, "Syncing bitmap fonts" ); for ( int i = 0; i < _atlas.bitmapFonts.Count; ++i ) { // check bitmapfont exBitmapFont bitmapFont = _atlas.bitmapFonts[i]; string bitmapFontPath = AssetDatabase.GetAssetPath(bitmapFont); if ( bitmapFont == null ) { _atlas.bitmapFonts.RemoveAt(i); AssetDatabase.DeleteAsset ( bitmapFontPath ); --i; continue; } // check raw-fontinfo string rawFontPath = AssetDatabase.GUIDToAssetPath(bitmapFont.rawFontGUID); string rawFontName = Path.GetFileNameWithoutExtension(rawFontPath); FileInfo rawFontFileInfo = new FileInfo(rawFontPath); if ( rawFontFileInfo.Exists == false ) { _atlas.textureInfos.RemoveAt(i); AssetDatabase.DeleteAsset ( bitmapFontPath ); --i; continue; } // check if bitmapfont same with raw-fontinfo string expectPath = Path.Combine( atlasAssetsDir, rawFontName + ".asset" ); expectPath = expectPath.Replace("\\", "/"); if ( bitmapFontPath != expectPath ) { bool doMove = true; FileInfo fileInfo = new FileInfo(expectPath); if ( fileInfo.Exists ) { doMove = EditorUtility.DisplayDialog( "Texture Info " + rawFontName + " already exists", "Do you want to replace it with new texture infor?", "Yes", "No" ); } if ( doMove ) { AssetDatabase.DeleteAsset ( expectPath ); AssetDatabase.MoveAsset ( bitmapFontPath, expectPath ); } } bitmapFont.rawAtlasGUID = rawAtlasGUID; } AssetDatabase.StopAssetEditing(); // atlas texture _progress( 0.8f, "Syncing atlas texture" ); string atlasTexturePath = AssetDatabase.GetAssetPath(_atlas.texture); string expectAtlasTexturePath = Path.Combine( atlasAssetsDir, _atlas.name + ".png" ); expectAtlasTexturePath = expectAtlasTexturePath.Replace("\\", "/"); if ( _atlas.texture != null && atlasTexturePath != expectAtlasTexturePath ) { bool doMove = true; FileInfo fileInfo = new FileInfo(expectAtlasTexturePath); if ( fileInfo.Exists ) { doMove = EditorUtility.DisplayDialog( "Atlas Texture " + _atlas.name + " already exists", "Do you want to replace it with new atlas texture?", "Yes", "No" ); } if ( doMove ) { AssetDatabase.MoveAsset ( atlasTexturePath, expectAtlasTexturePath ); AssetDatabase.ImportAsset ( expectAtlasTexturePath ); } } }
// ------------------------------------------------------------------ // Desc: // ------------------------------------------------------------------ public static bool Exists( exAtlas _atlas, Texture2D _texture ) { string guid = exEditorUtility.AssetToGUID(_texture); foreach ( exTextureInfo info in _atlas.textureInfos ) { if ( info.rawTextureGUID == guid ) { return true; } } return false; }
/////////////////////////////////////////////////////////////////////////////// // functions /////////////////////////////////////////////////////////////////////////////// // ------------------------------------------------------------------ // Desc: // ------------------------------------------------------------------ void Init() { if ( nameToState == null ) { initialized = false; } if ( initialized == false ) { initialized = true; sprite = GetComponent<exSprite>(); defaultAtlas = sprite.atlas; defaultIndex = sprite.index; nameToState = new Dictionary<string,exSpriteAnimState> (); for ( int i = 0; i < animations.Count; ++i ) { exSpriteAnimState state = new exSpriteAnimState(animations[i]); nameToState[state.name] = state; } if ( defaultAnimation != null ) curAnimation = nameToState[defaultAnimation.name]; } }
// ------------------------------------------------------------------ /// update the default sprite if we dynamically change it in the game // ------------------------------------------------------------------ public void UpdateDefaultSprite(exAtlas _atlas, int _index) { defaultAtlas = _atlas; defaultIndex = _index; }
// ------------------------------------------------------------------ /// update the default sprite if we dynamically change it in the game // ------------------------------------------------------------------ public void UpdateDefaultSprite ( exAtlas _atlas, int _index ) { defaultAtlas = _atlas; defaultIndex = _index; }
// ------------------------------------------------------------------ // Desc: // ------------------------------------------------------------------ public static bool Exists( exAtlas _atlas, exTextureInfo _textureInfo ) { return _atlas.textureInfos.IndexOf(_textureInfo) != -1; }
// ------------------------------------------------------------------ /// Clear the altas, material and mesh of the sprite, make it empty // ------------------------------------------------------------------ public void Clear() { atlas_ = null; index_ = -1; if ( renderer != null ) renderer.sharedMaterial = null; if ( meshFilter == null ) meshFilter = GetComponent<MeshFilter>(); if ( meshFilter != null ) meshFilter.sharedMesh = null; }
// ------------------------------------------------------------------ /// \param _atlasInfo the atlas info /// \param _noImport if true, ex2D will not import the texture to fit for atlas /// build the atlas info to atlas // ------------------------------------------------------------------ public static void Build(exAtlasInfo _atlasInfo, bool _noImport = false) { exAtlas atlas = _atlasInfo.atlas; Texture2D texture = _atlasInfo.texture; Material material = _atlasInfo.material; // check if the atlas info is valid for build if (atlas == null) { Debug.LogError("Failed to build atlas info " + _atlasInfo.name + ", the atlas is missing!"); return; } if (texture == null) { Debug.LogError("Failed to build atlas info " + _atlasInfo.name + ", the texture is missing!"); return; } if (material == null) { Debug.LogError("Failed to build atlas info " + _atlasInfo.name + ", the material is missing!"); return; } // if (_atlasInfo.needLayout) { _atlasInfo.LayoutElements(); _atlasInfo.needLayout = false; } // create temp texture Color32 buildColor = new Color(0.0f, 0.0f, 0.0f, 0.0f); if (_atlasInfo.useBuildColor) { buildColor = new Color(_atlasInfo.buildColor.r, _atlasInfo.buildColor.g, _atlasInfo.buildColor.b, 0.0f); } string path = AssetDatabase.GetAssetPath(texture); TextureImporter importer = TextureImporter.GetAtPath(path) as TextureImporter; // TextureImporterSettings textureImporterSettings = new TextureImporterSettings(); // importer.ReadTextureSettings(textureImporterSettings); // textureImporterSettings.readable = true; // importer.SetTextureSettings(textureImporterSettings); importer.wrapMode = TextureWrapMode.Clamp; importer.isReadable = true; AssetDatabase.ImportAsset(path); Color32[] colors = new Color32[_atlasInfo.width * _atlasInfo.height]; for (int i = 0; i < _atlasInfo.width * _atlasInfo.height; ++i) { colors[i] = buildColor; } texture.SetPixels32(colors); try { EditorUtility.DisplayProgressBar("Building Atlas " + _atlasInfo.name, "Building Atlas...", 0.1f); // build atlas texture _atlasInfo.elements.Sort(exAtlasInfo.CompareByName); FillAtlasTexture(texture, _atlasInfo, _noImport); EditorUtility.DisplayProgressBar("Building Atlas " + _atlasInfo.name, "Import Atlas", 0.9f); // write to disk byte[] pngData = texture.EncodeToPNG(); if (pngData != null) { File.WriteAllBytes(path, pngData); } // now we finish atlas texture filling, we should turn off Read/Write settings, that will save memory a lot! TextureImporter importSettings = TextureImporter.GetAtPath(path) as TextureImporter; importSettings.wrapMode = TextureWrapMode.Clamp; importSettings.isReadable = _atlasInfo.readable; AssetDatabase.ImportAsset(path); // atlas.elements = new exAtlas.Element[_atlasInfo.elements.Count]; for (int i = 0; i < _atlasInfo.elements.Count; ++i) { exAtlasInfo.Element el = _atlasInfo.elements[i]; exAtlas.Element el2 = new exAtlas.Element(); int coord_x = el.coord[0]; int coord_y = el.atlasInfo.height - el.coord[1] - (int)el.Height(); float xStart = (float)coord_x / (float)el.atlasInfo.width; float yStart = (float)coord_y / (float)el.atlasInfo.height; float xEnd = (float)(coord_x + el.Width()) / (float)el.atlasInfo.width; float yEnd = (float)(coord_y + el.Height()) / (float)el.atlasInfo.height; el2.name = el.texture.name; el2.coords = new Rect(xStart, yStart, xEnd - xStart, yEnd - yStart); el2.rotated = el.rotated; el2.originalWidth = el.texture.width; el2.originalHeight = el.texture.height; el2.trimRect = el.trimRect; atlas.elements[i] = el2; // update the index in exAtlasDB if (el.isFontElement == false) { exAtlasDB.UpdateElementInfo(el, i); } } atlas.texture = texture; atlas.material = material; EditorUtility.SetDirty(atlas); EditorUtility.ClearProgressBar(); } catch (System.Exception) { EditorUtility.ClearProgressBar(); throw; } // save the needRebuild setting _atlasInfo.needRebuild = false; EditorUtility.SetDirty(_atlasInfo); }
// ------------------------------------------------------------------ // Desc: // ------------------------------------------------------------------ void OnGUI() { EditorGUI.indentLevel = 0; if (curEdit == null) { GUILayout.Space(10); GUILayout.Label("Please select an Atlas Info"); // DISABLE: this.ShowNotification( new GUIContent("Please select an Atlas Info")); return; } // ======================================================== // toolbar // ======================================================== GUILayout.BeginHorizontal(EditorStyles.toolbar); GUILayout.FlexibleSpace(); // ======================================================== // Select // ======================================================== GUI.enabled = selectedElements.Count != 0; if (GUILayout.Button("Select In Project...", EditorStyles.toolbarButton)) { List <Object> selects = new List <Object>(curEdit.elements.Count); foreach (exAtlasInfo.Element el in selectedElements) { if (selects.IndexOf(el.texture) == -1) { selects.Add(el.texture); } } if (selects.Count != 0) { selectIdx = (selectIdx + 1) % selects.Count; Selection.objects = selects.ToArray(); EditorGUIUtility.PingObject(Selection.objects[selectIdx]); } } GUI.enabled = true; GUILayout.Space(5); // ======================================================== // zoom in/out slider // ======================================================== GUILayout.Label("Zoom"); GUILayout.Space(5); curEdit.scale = GUILayout.HorizontalSlider(curEdit.scale, 0.1f, 2.0f, GUILayout.MaxWidth(150)); GUILayout.Space(5); curEdit.scale = EditorGUILayout.FloatField(curEdit.scale, EditorStyles.toolbarTextField, GUILayout.Width(50)); curEdit.scale = Mathf.Clamp(curEdit.scale, 0.1f, 2.0f); // ======================================================== // Build // ======================================================== GUI.enabled = curEdit.needRebuild; if (GUILayout.Button("Build", EditorStyles.toolbarButton, GUILayout.Width(80))) { // build atlas info to atals exAtlasInfoUtility.Build(curEdit); // build sprite animclip that used this atlasInfo exAtlasInfoUtility.BuildSpAnimClipsFromRebuildList(curEdit); // update scene sprites List <string> rebuildAtlasInfos = new List <string>(); rebuildAtlasInfos.Add(exEditorHelper.AssetToGUID(curEdit)); exSceneHelper.UpdateSprites(rebuildAtlasInfos); // NOTE: without this you will got leaks message EditorUtility.UnloadUnusedAssets(); } GUI.enabled = true; // ======================================================== // Help // ======================================================== if (GUILayout.Button(exEditorHelper.HelpTexture(), EditorStyles.toolbarButton)) { Help.BrowseURL("http://www.ex-dev.com/ex2d/wiki/doku.php?id=manual:atlas_editor"); } GUILayout.EndHorizontal(); // ======================================================== // scroll view // ======================================================== float toolbarHeight = EditorStyles.toolbar.CalcHeight(new GUIContent(""), 0); scrollPos = EditorGUILayout.BeginScrollView(scrollPos, GUILayout.Width(position.width), GUILayout.Height(position.height - toolbarHeight)); Rect lastRect = new Rect(10, 0, 1, 1); GUILayout.Space(5); // DISABLE { // // draw label // GUILayout.Label ( AssetDatabase.GetAssetPath(curEdit) ); // } DISABLE end // ======================================================== // atlas info // ======================================================== Object newAtlasInfo = EditorGUILayout.ObjectField("Atlas Info" , curEdit , typeof(exAtlasInfo) , false , GUILayout.Width(300) ); if (newAtlasInfo != curEdit) { Selection.activeObject = newAtlasInfo; } // ======================================================== // settings area // ======================================================== GUILayout.BeginHorizontal(); GUILayout.BeginVertical(GUILayout.MaxWidth(200)); // ======================================================== // canvas // ======================================================== curEdit.foldCanvas = EditorGUILayout.Foldout(curEdit.foldCanvas, "Canvas"); if (curEdit.foldCanvas) { GUILayout.BeginHorizontal(); GUILayout.Space(20); GUILayout.BeginVertical(); // width and height int width = curEdit.width; int height = curEdit.height; WidthAndHeightField(ref width, ref height); // Check if we need to Reset width & height if (width != curEdit.width || height != curEdit.height) { curEdit.width = width; curEdit.height = height; if (curEdit.texture) { // NOTE: if we don't write data to disk, all changes will go back. string path = AssetDatabase.GetAssetPath(curEdit.texture); exTextureHelper.SetReadable(curEdit.texture, true); curEdit.texture.Resize(width, height); curEdit.ClearAtlasTexture(); // NOTE: we can not write back directly since the texture format problem Texture2D tex = new Texture2D(width, height, TextureFormat.ARGB32, false); for (int i = 0; i < width; ++i) { for (int j = 0; j < height; ++j) { tex.SetPixel(i, j, new Color(1.0f, 1.0f, 1.0f, 0.0f)); } } tex.Apply(false); byte[] pngData = tex.EncodeToPNG(); if (pngData != null) { File.WriteAllBytes(path, pngData); } Object.DestroyImmediate(tex); TextureImporter importSettings = TextureImporter.GetAtPath(path) as TextureImporter; importSettings.maxTextureSize = Mathf.Max(width, height); importSettings.wrapMode = TextureWrapMode.Clamp; importSettings.isReadable = curEdit.readable; AssetDatabase.ImportAsset(path); } curEdit.needRebuild = true; } curEdit.bgColor = EditorGUILayout.ColorField("Bg Color", curEdit.bgColor); curEdit.showCheckerboard = EditorGUILayout.Toggle("Show Checkerboard", curEdit.showCheckerboard); GUILayout.EndVertical(); GUILayout.EndHorizontal(); } GUILayout.Space(20); // ======================================================== // layout // ======================================================== curEdit.foldLayout = EditorGUILayout.Foldout(curEdit.foldLayout, "Layout"); if (curEdit.foldLayout) { GUILayout.BeginHorizontal(); GUILayout.Space(20); GUILayout.BeginVertical(); // algorithm curEdit.algorithm = (exAtlasInfo.Algorithm)EditorGUILayout.EnumPopup("Algorithm", curEdit.algorithm); // sortBy curEdit.sortBy = (exAtlasInfo.SortBy)EditorGUILayout.EnumPopup("Sort By", curEdit.sortBy); // sortOrder curEdit.sortOrder = (exAtlasInfo.SortOrder)EditorGUILayout.EnumPopup("Sort Order", curEdit.sortOrder); // padding curEdit.paddingMode = (exAtlasInfo.PaddingMode)EditorGUILayout.EnumPopup("Padding", curEdit.paddingMode); GUILayout.BeginHorizontal(); GUILayout.Space(20); GUI.enabled = (curEdit.paddingMode == exAtlasInfo.PaddingMode.Custom); curEdit.customPadding = Math.Max(EditorGUILayout.IntField("Pixels", curEdit.actualPadding), 0); // Clamp to 0 GUI.enabled = true; GUILayout.EndHorizontal(); // TODO: have bug, just disable it { // allow rotate GUI.enabled = false; curEdit.allowRotate = false; curEdit.allowRotate = EditorGUILayout.Toggle("Allow Rotate", curEdit.allowRotate); GUI.enabled = true; // } TODO end if (GUILayout.Button("Apply")) { try { EditorUtility.DisplayProgressBar("Layout Elements...", "Layout Elements...", 0.5f); // register undo Undo.RegisterUndo(curEdit, "Apply.LayoutElements"); curEdit.LayoutElements(); EditorUtility.ClearProgressBar(); } catch (System.Exception) { EditorUtility.ClearProgressBar(); throw; } } // GUI.enabled = true; GUILayout.EndVertical(); GUILayout.EndHorizontal(); } GUILayout.Space(20); // ======================================================== // Element // ======================================================== curEdit.foldElement = EditorGUILayout.Foldout(curEdit.foldElement, "Element"); if (curEdit.foldElement) { GUILayout.BeginHorizontal(); GUILayout.Space(20); GUILayout.BeginVertical(); // sprite background color curEdit.elementBgColor = EditorGUILayout.ColorField("Bg Color", curEdit.elementBgColor); curEdit.elementSelectColor = EditorGUILayout.ColorField("Select Color", curEdit.elementSelectColor); GUILayout.EndVertical(); GUILayout.EndHorizontal(); } GUILayout.Space(40); // ======================================================== // atlas texture and material // ======================================================== GUILayout.BeginHorizontal(); GUILayout.Space(10); GUILayout.BeginVertical(); GUI.enabled = false; string assetPath = AssetDatabase.GetAssetPath(curEdit); string dir = Path.GetDirectoryName(assetPath); // ======================================================== // texture // ======================================================== if (curEdit.texture) { curEdit.texture = (Texture2D)EditorGUILayout.ObjectField("Texture" , curEdit.texture , typeof(Texture2D) , false , GUILayout.Width(100) , GUILayout.Height(100) ); } else { GUI.enabled = true; if (GUILayout.Button("Create Texture...")) { // create texture Texture2D tex = new Texture2D(curEdit.width, curEdit.height, TextureFormat.ARGB32, false); for (int i = 0; i < curEdit.width; ++i) { for (int j = 0; j < curEdit.height; ++j) { tex.SetPixel(i, j, new Color(1.0f, 1.0f, 1.0f, 0.0f)); } } tex.Apply(false); // save texture to png string atlasTexturePath = Path.Combine(dir, curEdit.atlasName + ".png"); byte[] pngData = tex.EncodeToPNG(); if (pngData != null) { File.WriteAllBytes(atlasTexturePath, pngData); } Object.DestroyImmediate(tex); // import texture AssetDatabase.ImportAsset(atlasTexturePath); TextureImporter importSettings = TextureImporter.GetAtPath(atlasTexturePath) as TextureImporter; importSettings.maxTextureSize = Mathf.Max(curEdit.width, curEdit.height); importSettings.textureFormat = TextureImporterFormat.AutomaticTruecolor; importSettings.isReadable = true; importSettings.wrapMode = TextureWrapMode.Clamp; importSettings.mipmapEnabled = false; importSettings.textureType = TextureImporterType.Default; importSettings.npotScale = TextureImporterNPOTScale.None; AssetDatabase.ImportAsset(atlasTexturePath); curEdit.texture = (Texture2D)AssetDatabase.LoadAssetAtPath(atlasTexturePath, typeof(Texture2D)); if (curEdit.material) { curEdit.material.mainTexture = curEdit.texture; } EditorUtility.SetDirty(curEdit); } GUI.enabled = false; } // GUILayout.Space(5); // ======================================================== // material // ======================================================== if (curEdit.material) { curEdit.material = (Material)EditorGUILayout.ObjectField("Material" , curEdit.material , typeof(Material) , false ); } else { GUI.enabled = true; if (GUILayout.Button("Create Material...")) { Material newMaterial = new Material(Shader.Find("ex2D/Alpha Blended")); AssetDatabase.CreateAsset(newMaterial, Path.Combine(dir, curEdit.atlasName + ".mat")); curEdit.material = newMaterial; curEdit.material.mainTexture = curEdit.texture; EditorUtility.SetDirty(curEdit); } GUI.enabled = false; } // GUILayout.Space(5); // ======================================================== // atlas // ======================================================== if (curEdit.atlas) { curEdit.atlas = (exAtlas)EditorGUILayout.ObjectField("Atlas" , curEdit.atlas , typeof(exAtlas) , false ); } else { GUI.enabled = true; if (GUILayout.Button("Create Atlas...")) { exAtlas newAtlas = exAtlasInfoUtility.CreateAtlas(dir, curEdit.atlasName); curEdit.atlas = newAtlas; EditorUtility.SetDirty(curEdit); } GUI.enabled = false; } GUI.enabled = true; // GUILayout.Space(5); // ======================================================== // build color // ======================================================== GUILayout.BeginHorizontal(); bool newUseBuildColor = GUILayout.Toggle(curEdit.useBuildColor, "Use Build Color"); if (newUseBuildColor != curEdit.useBuildColor) { curEdit.useBuildColor = newUseBuildColor; curEdit.needRebuild = true; GUI.changed = true; } GUI.enabled = curEdit.useBuildColor; Color newBuildColor = EditorGUILayout.ColorField(curEdit.buildColor); if (newBuildColor != curEdit.buildColor) { curEdit.buildColor = newBuildColor; curEdit.needRebuild = true; GUI.changed = true; } GUI.enabled = true; GUILayout.EndHorizontal(); // ======================================================== // contour bleed // ======================================================== GUI.enabled = !curEdit.useBuildColor; GUILayout.BeginHorizontal(); bool newUseContourBleed = GUILayout.Toggle(curEdit.useContourBleed, new GUIContent("Use Contour Bleed", "Prevents artifacts around the silhouette of artwork due to bilinear filtering (requires Build Color to be turned off)")) && !curEdit.useBuildColor; if (newUseContourBleed != curEdit.useContourBleed) { curEdit.useContourBleed = newUseContourBleed; curEdit.needRebuild = true; GUI.changed = true; } GUILayout.EndHorizontal(); GUI.enabled = true; // ======================================================== // padding bleed // ======================================================== GUI.enabled = (curEdit.paddingMode == exAtlasInfo.PaddingMode.Auto) || (curEdit.actualPadding >= 2); GUILayout.BeginHorizontal(); bool newUsePaddingBleed = GUILayout.Toggle(curEdit.usePaddingBleed, new GUIContent("Use Padding Bleed", "Prevents artifacts and seams around the outer bounds of a texture due to bilinear filtering (requires at least Padding of 2)")) && GUI.enabled; if (newUsePaddingBleed != curEdit.usePaddingBleed) { curEdit.usePaddingBleed = newUsePaddingBleed; curEdit.needRebuild = true; GUI.changed = true; } GUILayout.EndHorizontal(); GUI.enabled = true; // ======================================================== // trim elements // ======================================================== bool newTrimElements = GUILayout.Toggle(curEdit.trimElements, "Trimmed Elements"); if (newTrimElements != curEdit.trimElements) { curEdit.trimElements = newTrimElements; foreach (exAtlasInfo.Element el in curEdit.elements) { curEdit.UpdateElement(el.texture, newTrimElements); } curEdit.needRebuild = true; GUI.changed = true; } // ======================================================== // readable // ======================================================== bool newReadable = GUILayout.Toggle(curEdit.readable, "Read/Write Enabled"); if (newReadable != curEdit.readable) { curEdit.readable = newReadable; GUI.changed = true; exTextureHelper.SetReadable(curEdit.texture, curEdit.readable); } // ======================================================== // bitmap fonts // ======================================================== GUILayout.Space(20); GUILayout.Label("Atlas Fonts"); for (int i = 0; i < curEdit.bitmapFonts.Count; ++i) { GUILayout.BeginHorizontal(); exBitmapFont bmfont = curEdit.bitmapFonts[i]; EditorGUILayout.ObjectField(bmfont , typeof(exBitmapFont) , false ); if (GUILayout.Button("Delete", GUILayout.MaxWidth(80))) { curEdit.RemoveBitmapFont(bmfont); AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(bmfont)); --i; } GUILayout.EndHorizontal(); } GUILayout.EndVertical(); GUILayout.EndHorizontal(); GUILayout.EndVertical(); // ======================================================== // space // ======================================================== GUILayout.Space(40); lastRect = GUILayoutUtility.GetLastRect(); // ======================================================== // atlas area // ======================================================== GUILayout.BeginVertical(); GUILayout.Space(10); // exAtlas Border and Background lastRect = GUILayoutUtility.GetLastRect(); int borderSize = 1; atlasInfoRect = new Rect(lastRect.xMax + borderSize, lastRect.yMax + borderSize, curEdit.width * curEdit.scale, curEdit.height * curEdit.scale); AtlasInfoField(atlasInfoRect, borderSize, curEdit); GUILayout.EndVertical(); GUILayout.EndHorizontal(); // ======================================================== // draw select rect // ======================================================== if (inRectSelectState && (selectRect.width != 0.0f || selectRect.height != 0.0f)) { exEditorHelper.DrawRect(selectRect, new Color(0.0f, 0.5f, 1.0f, 0.2f), new Color(0.0f, 0.5f, 1.0f, 1.0f)); } // ======================================================== Event e = Event.current; // ======================================================== // mouse down if (e.type == EventType.MouseDown && e.button == 0 && e.clickCount == 1) { GUIUtility.keyboardControl = -1; // remove any keyboard control mouseDownPos = e.mousePosition; inRectSelectState = true; UpdateSelectRect(); ConfirmRectSelection(); Repaint(); e.Use(); } // rect select if (inRectSelectState) { if (e.type == EventType.MouseDrag) { UpdateSelectRect(); ConfirmRectSelection(); Repaint(); e.Use(); } else if (e.type == EventType.MouseUp && e.button == 0) { inRectSelectState = false; ConfirmRectSelection(); Repaint(); e.Use(); } } // dragging selected if (inDraggingElementState) { if (e.type == EventType.MouseDrag) { MoveSelections(e.delta / curEdit.scale); Repaint(); e.Use(); } else if (e.type == EventType.MouseUp && e.button == 0) { if (curEdit.needUpdateAnimClips) { foreach (exAtlasInfo.Element el in selectedElements) { curEdit.AddSpriteAnimClipForRebuilding(el); } curEdit.needUpdateAnimClips = false; } inDraggingElementState = false; accDeltaMove = Vector2.zero; e.Use(); } } // key events if (e.isKey) { if (e.type == EventType.KeyDown) { if (e.keyCode == KeyCode.Backspace || e.keyCode == KeyCode.Delete) { RemoveSelectedElements(); Repaint(); e.Use(); } } } EditorGUILayout.EndScrollView(); // ======================================================== // do imports // ======================================================== if (doImport) { doImport = false; ImportObjects(); Selection.activeObject = oldSelActiveObject; Selection.objects = oldSelObjects.ToArray(); oldSelObjects.Clear(); oldSelActiveObject = null; Repaint(); } // if (GUI.changed) { EditorUtility.SetDirty(curEdit); } }
// ------------------------------------------------------------------ /// \param _path the directory path to save the atlas info /// \param _name the name of the atlas info /// \param _width the width of the atlas texture /// \param _height the height of the atlas texture /// \return the atlas info /// create the atlas info in the _path, save it as _name. // ------------------------------------------------------------------ public static exAtlasInfo CreateAtlasInfo(string _path, string _name, int _width, int _height) { try { // create atlas info EditorUtility.DisplayProgressBar("Creating Atlas...", "Creating Atlas Asset...", 0.1f); exAtlasInfo newAtlasInfo = exAtlasInfo.Create(_path, _name + " - EditorInfo"); newAtlasInfo.width = _width; newAtlasInfo.height = _height; // create texture EditorUtility.DisplayProgressBar("Creating Atlas...", "Creating Atlas Texture...", 0.2f); Texture2D tex = new Texture2D(newAtlasInfo.width, newAtlasInfo.height, TextureFormat.ARGB32, false); Color32 buildColor = new Color(newAtlasInfo.buildColor.r, newAtlasInfo.buildColor.g, newAtlasInfo.buildColor.b, 0.0f); Color32[] colors = new Color32[newAtlasInfo.width * newAtlasInfo.height]; for (int i = 0; i < newAtlasInfo.width * newAtlasInfo.height; ++i) { colors[i] = buildColor; } tex.SetPixels32(colors); tex.Apply(false); // save texture to png EditorUtility.DisplayProgressBar("Creating Atlas...", "Saving Atlas Texture as PNG file...", 0.3f); string atlasTexturePath = Path.Combine(_path, _name + ".png"); byte[] pngData = tex.EncodeToPNG(); if (pngData != null) { File.WriteAllBytes(atlasTexturePath, pngData); } Object.DestroyImmediate(tex); AssetDatabase.ImportAsset(atlasTexturePath); // import texture EditorUtility.DisplayProgressBar("Creating Atlas...", "Import Texture " + atlasTexturePath + "...", 0.5f); TextureImporter importSettings = TextureImporter.GetAtPath(atlasTexturePath) as TextureImporter; importSettings.maxTextureSize = Mathf.Max(newAtlasInfo.width, newAtlasInfo.height); importSettings.textureFormat = TextureImporterFormat.AutomaticTruecolor; importSettings.wrapMode = TextureWrapMode.Clamp; // atlases should always be clamped, which allows to remove padding // around atlas and free up some pixel space importSettings.isReadable = false; importSettings.mipmapEnabled = false; importSettings.textureType = TextureImporterType.Advanced; importSettings.npotScale = TextureImporterNPOTScale.None; AssetDatabase.ImportAsset(atlasTexturePath); // create default material EditorUtility.DisplayProgressBar("Creating Atlas...", "Create New Material...", 0.7f); Material newMaterial = new Material(Shader.Find("ex2D/Alpha Blended")); AssetDatabase.CreateAsset(newMaterial, Path.Combine(_path, _name + ".mat")); // setup atlas info EditorUtility.DisplayProgressBar("Creating Atlas...", "Setup New Atlas Asset...", 0.9f); newAtlasInfo.atlasName = _name; newAtlasInfo.texture = (Texture2D)AssetDatabase.LoadAssetAtPath(atlasTexturePath, typeof(Texture2D)); newAtlasInfo.material = newMaterial; newAtlasInfo.material.mainTexture = newAtlasInfo.texture; // create new atlas and setup it for both atlas info and atlas asset exAtlas newAtlas = CreateAtlas(_path, _name); newAtlas.texture = newAtlasInfo.texture; newAtlas.material = newAtlasInfo.material; newAtlasInfo.atlas = newAtlas; // EditorUtility.SetDirty(newAtlasInfo); EditorUtility.UnloadUnusedAssets(); EditorUtility.ClearProgressBar(); // Selection.activeObject = newAtlasInfo; EditorGUIUtility.PingObject(newAtlasInfo); return(newAtlasInfo); } catch (System.Exception) { EditorUtility.ClearProgressBar(); throw; } }
// ------------------------------------------------------------------ /// Clear the altas, material and mesh of the sprite, make it empty // ------------------------------------------------------------------ public void Clear() { atlas_ = null; index_ = -1; guiBorder_ = null; if ( renderer != null ) renderer.sharedMaterial = null; if ( meshFilter ) { DestroyImmediate( meshFilter_.sharedMesh, true ); meshFilter_.sharedMesh = null; } }
// ------------------------------------------------------------------ /// \param _atlas the new atlas /// \param _index the index of the element in the new atlas /// \param _changeDefaultAnimSprite if this is true, the default animation sprite will be changed so when we use stopAction = defaultSprite it will change to this new one /// Set a new picture in an atlas to this sprite // ------------------------------------------------------------------ public void SetSprite( exAtlas _atlas, int _index, bool _changeDefaultAnimSprite = false ) { bool checkVertex = false; bool createMesh = false; // pre-check if ( _atlas == null || _atlas.elements == null || _index < 0 || _index >= _atlas.elements.Length ) { Debug.LogWarning ( "Invalid input in SetSprite. atlas = " + (_atlas ? _atlas.name : "null") + ", index = " + _index ); return; } // it is possible that the atlas is null and we don't have mesh if ( atlas_ == null ) { createMesh = true; } // if ( atlas_ != _atlas ) { atlas_ = _atlas; renderer.sharedMaterial = _atlas.material; updateFlags |= UpdateFlags.UV; checkVertex = true; } // if ( index_ != _index ) { index_ = _index; updateFlags |= UpdateFlags.UV; checkVertex = true; } // if ( checkVertex ) { // NOTE: if we use texture offset, it always need to update vertex if ( useTextureOffset_ ) { updateFlags |= UpdateFlags.Vertex; } if ( !customSize_ ) { exAtlas.Element el = atlas_.elements[index_]; float newWidth = el.trimRect.width; float newHeight = el.trimRect.height; // float newWidth = el.coords.width * atlas_.texture.width; // float newHeight = el.coords.height * atlas_.texture.height; if ( el.rotated ) { float tmp = newWidth; newWidth = newHeight; newHeight = tmp; } if ( newWidth != width_ || newHeight != height_ ) { width_ = newWidth; height_ = newHeight; updateFlags |= UpdateFlags.Vertex; } } } // if ( createMesh ) { if ( meshFilter ) { // create mesh ( in editor, this can duplicate mesh to prevent shared mesh for sprite) meshFilter_.mesh = new Mesh(); meshFilter_.sharedMesh.hideFlags = HideFlags.DontSave; updateFlags = UpdateFlags.Vertex | UpdateFlags.UV | UpdateFlags.Color | UpdateFlags.Index; // check if update mesh collider MeshCollider meshCollider = collider as MeshCollider; if ( meshCollider && meshCollider.sharedMesh == null ) { this.UpdateColliderSize(0.2f); } } } // if ( _changeDefaultAnimSprite && spanim ) { spanim.UpdateDefaultSprite ( _atlas, _index ); } }
// ------------------------------------------------------------------ // Desc: // ------------------------------------------------------------------ public override void OnInspectorGUI() { // ======================================================== // Base GUI // ======================================================== base.OnInspectorGUI(); GUILayout.Space(20); // ======================================================== // init values // ======================================================== // bool needRebuild = false; // ======================================================== // exGUIBorder object filed // ======================================================== bool borderChanged = false; EditorGUI.indentLevel = 1; GUILayout.BeginHorizontal(); GUI.enabled = !inAnimMode; exGUIBorder newGUIBorder = (exGUIBorder)EditorGUILayout.ObjectField("GUI Border" , editSpriteBorder.guiBorder , typeof(exGUIBorder) , false ); if (newGUIBorder != editSpriteBorder.guiBorder) { borderChanged = true; } if (GUILayout.Button("Edit...", GUILayout.Width(40), GUILayout.Height(15))) { exGUIBorderEditor editor = exGUIBorderEditor.NewWindow(); editor.Edit(editSpriteBorder.guiBorder); } GUI.enabled = true; GUILayout.EndHorizontal(); GUILayout.Space(5); // get edit texture Texture2D editTexture = null; if (newGUIBorder) { editTexture = exEditorHelper.LoadAssetFromGUID <Texture2D>(newGUIBorder.textureGUID); // ======================================================== // border preview // ======================================================== Rect lastRect = GUILayoutUtility.GetLastRect(); GUILayout.BeginHorizontal(); GUILayout.Space(30); lastRect = GUILayoutUtility.GetLastRect(); Rect previewRect = new Rect(lastRect.xMax, lastRect.yMax, Mathf.Max(100, newGUIBorder.border.horizontal), Mathf.Max(100, newGUIBorder.border.vertical)); exGUIBorderEditor.TexturePreviewField(previewRect, newGUIBorder, editTexture); GUILayout.Space(10); lastRect = GUILayoutUtility.GetLastRect(); previewRect = new Rect(lastRect.x, lastRect.yMax, Mathf.Max(100, newGUIBorder.border.horizontal), Mathf.Max(100, newGUIBorder.border.vertical)); exGUIBorderEditor.BorderPreviewField(previewRect, newGUIBorder, editTexture); if (GUILayout.Button("Select...", GUILayout.Width(60), GUILayout.Height(15))) { EditorGUIUtility.PingObject(editTexture); } GUILayout.EndHorizontal(); GUILayout.Space(5); } // ======================================================== // get atlas element info from atlas database // ======================================================== exAtlas editAtlas = null; int editIndex = -1; exAtlasDB.ElementInfo elInfo = null; if (newGUIBorder) { elInfo = exAtlasDB.GetElementInfo(newGUIBorder.textureGUID); } if (elInfo != null) { editAtlas = exEditorHelper.LoadAssetFromGUID <exAtlas>(elInfo.guidAtlas); editIndex = elInfo.indexInAtlas; } bool useAtlas = editAtlas != null && editIndex != -1; // get atlas and index from textureGUID if (!EditorApplication.isPlaying) { // if we use atlas, check if the atlas,index changes if (useAtlas) { if (editAtlas != editSpriteBorder.atlas || editIndex != editSpriteBorder.index) { borderChanged = true; } } // if we don't use atlas and current edit target use atlas, clear it. else { if (editSpriteBorder.useAtlas) { borderChanged = true; } } // check if we are first time assignment if (useAtlas || editTexture != null) { if (isPrefab == false && editSpriteBorder.meshFilter.sharedMesh == null) { needRebuild = true; } } } // set border if (borderChanged) { // if (newGUIBorder == null) { editSpriteBorder.Clear(); } else { editSpriteBorder.SetBorder(newGUIBorder, editAtlas, editIndex); if (editSpriteBorder.useAtlas == false) { editSpriteBorder.GetComponent <Renderer>().sharedMaterial = exEditorHelper.GetDefaultMaterial(editTexture, editTexture.name); editSpriteBorder.updateFlags |= exPlane.UpdateFlags.UV; } } GUI.changed = true; } // ======================================================== // color // ======================================================== editSpriteBorder.color = EditorGUILayout.ColorField("Color", editSpriteBorder.color); // ======================================================== // atlas & index // ======================================================== GUILayout.BeginHorizontal(); GUI.enabled = false; EditorGUILayout.ObjectField("Atlas" , editSpriteBorder.atlas , typeof(exAtlas) , false ); GUI.enabled = true; GUI.enabled = !inAnimMode; if (GUILayout.Button("Edit...", GUILayout.Width(40), GUILayout.Height(15))) { exAtlasEditor editor = exAtlasEditor.NewWindow(); editor.Edit(editSpriteBorder.atlas); } GUI.enabled = true; GUILayout.EndHorizontal(); GUI.enabled = false; EditorGUILayout.IntField("Index", editSpriteBorder.index); GUI.enabled = true; // ======================================================== // width & height // ======================================================== GUI.enabled = !inAnimMode; // width float newWidth = EditorGUILayout.FloatField("Width", editSpriteBorder.width); if (newWidth != editSpriteBorder.width) { if (newWidth < 1.0f) { newWidth = 1.0f; } editSpriteBorder.width = newWidth; } // height float newHeight = EditorGUILayout.FloatField("Height", editSpriteBorder.height); if (newHeight != editSpriteBorder.height) { if (newHeight < 1.0f) { newHeight = 1.0f; } editSpriteBorder.height = newHeight; } GUI.enabled = true; // ======================================================== // Rebuild button // ======================================================== GUI.enabled = !inAnimMode; GUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); if (GUILayout.Button("Rebuild...", GUILayout.Height(20))) { needRebuild = true; } GUILayout.EndHorizontal(); GUI.enabled = true; GUILayout.Space(5); // if dirty, build it. if (!EditorApplication.isPlaying && !AnimationUtility.InAnimationMode()) { if (needRebuild) { EditorUtility.ClearProgressBar(); editSpriteBorder.Build(editTexture); } else if (GUI.changed) { if (editSpriteBorder.meshFilter.sharedMesh != null) { editSpriteBorder.UpdateMesh(editSpriteBorder.meshFilter.sharedMesh); } EditorUtility.SetDirty(editSpriteBorder); } } }
// ------------------------------------------------------------------ // Desc: // ------------------------------------------------------------------ public static void Sort( List<Element> _elements, exAtlas.SortBy _sortBy, exAtlas.SortOrder _sortOrder, exAtlas.Algorithm _algorithm, bool _allowRotate ) { // exAtlas.SortBy mySortBy = _sortBy; exAtlas.SortOrder mySortOrder = _sortOrder; if ( mySortBy == exAtlas.SortBy.UseBest ) { switch ( _algorithm ) { case exAtlas.Algorithm.Basic: mySortBy = exAtlas.SortBy.Height; break; case exAtlas.Algorithm.Tree: mySortBy = exAtlas.SortBy.Area; break; // TODO { // case exAtlas.Algorithm.MaxRect: // mySortBy = exAtlas.SortBy.Area; // break; // } TODO end default: mySortBy = exAtlas.SortBy.Height; break; } } if ( mySortOrder == exAtlas.SortOrder.UseBest ) { mySortOrder = exAtlas.SortOrder.Descending; } // sort by switch ( mySortBy ) { case exAtlas.SortBy.Width: if ( _allowRotate ) _elements.Sort( CompareByRotateWidth ); else _elements.Sort( CompareByWidth ); break; case exAtlas.SortBy.Height: if ( _allowRotate ) _elements.Sort( CompareByRotateHeight ); else _elements.Sort( CompareByHeight ); break; case exAtlas.SortBy.Area: _elements.Sort( CompareByArea ); break; case exAtlas.SortBy.Name: _elements.Sort( CompareByName ); break; } // sort order if ( mySortOrder == exAtlas.SortOrder.Descending ) { _elements.Reverse(); } }