static void Load() { int l = LayerMask.NameToLayer("UI"); if (l == -1) { l = LayerMask.NameToLayer("GUI"); } if (l == -1) { l = 31; } mLoaded = true; mPartial = EditorPrefs.GetString("NGUI Partial"); mFontName = EditorPrefs.GetString("NGUI Font Name"); mAtlasName = EditorPrefs.GetString("NGUI Atlas Name"); mFontData = GetObject("NGUI Font Asset") as TextAsset; mFontTexture = GetObject("NGUI Font Texture") as Texture2D; mFont = GetObject("NGUI Font") as NGUIFont; mAtlas = GetObject("NGUI Atlas") as NGUIAtlas; mAtlasPadding = EditorPrefs.GetInt("NGUI Atlas Padding", 1); mAtlasTrimming = EditorPrefs.GetBool("NGUI Atlas Trimming", true); mUnityPacking = EditorPrefs.GetBool("NGUI Unity Packing", true); mForceSquare = EditorPrefs.GetBool("NGUI Force Square Atlas", true); mPivot = (NGUIWidget.Pivot)EditorPrefs.GetInt("NGUI Pivot", (int)mPivot); mLayer = EditorPrefs.GetInt("NGUI Layer", l); mDynFont = GetObject("NGUI DynFont") as Font; mDynFontSize = EditorPrefs.GetInt("NGUI DynFontSize", 16); mDynFontStyle = (FontStyle)EditorPrefs.GetInt("NGUI DynFontStyle", (int)FontStyle.Normal); LoadColor(); }
private void ConvertToSprite() { spriteList = new List <UISprite>(); foreach (UITexture tex in targetObj.GetComponentsInChildren <UITexture>(true)) { if (tex.mainTexture == null) { continue; } TexSetter setter = tex.GetComponent <TexSetter>(); TexLoader loader = tex.GetComponent <TexLoader>(); if (setter != null && setter.textures.Count == 1) { if (!AssetBundlePath.inst.IsCdnAsset(loader.Target.mainTexture)) { setter.DestroyEx(); loader.DestroyEx(); } } if (loader != null) { continue; } NGUIAtlas atlas = atlasMap.Get(tex.mainTexture.name); if (atlas != null) { var s = tex.ConvertToSprite(); s.atlas = atlas; EditorUtil.SetDirty(s.atlas as Object); spriteList.Add(s); } } }
/// <summary> /// Convenience function -- mark all widgets using the sprite as changed. /// </summary> void MarkSpriteAsDirty() { if (mSprite == null) { return; } NGUISprite[] sprites = NGUITools.FindActive <NGUISprite>(); foreach (NGUISprite sp in sprites) { if (sp.spriteName == mSprite.name) { sp.atlas = null; sp.atlas = mAtlas; EditorUtility.SetDirty(sp); } } NGUILabel[] labels = NGUITools.FindActive <NGUILabel>(); foreach (NGUILabel lbl in labels) { if (lbl.font != null && NGUIAtlas.CheckIfRelated(lbl.font.atlas, mAtlas) && lbl.font.UsesSprite(mSprite.name)) { NGUIFont font = lbl.font; lbl.font = null; lbl.font = font; EditorUtility.SetDirty(lbl); } } }
/// <summary> /// Replace the sprites within the atlas. /// </summary> static void ReplaceSprites(NGUIAtlas atlas, List <SpriteEntry> sprites) { // Get the list of sprites we'll be updating List <NGUIAtlas.Sprite> spriteList = atlas.spriteList; List <NGUIAtlas.Sprite> kept = new List <NGUIAtlas.Sprite>(); // The atlas must be in pixels atlas.coordinates = NGUIAtlas.Coordinates.Pixels; // Run through all the textures we added and add them as sprites to the atlas for (int i = 0; i < sprites.Count; ++i) { SpriteEntry se = sprites[i]; NGUIAtlas.Sprite sprite = AddSprite(spriteList, se); kept.Add(sprite); } // Remove unused sprites for (int i = spriteList.Count; i > 0;) { NGUIAtlas.Sprite sp = spriteList[--i]; if (!kept.Contains(sp)) { spriteList.RemoveAt(i); } } atlas.MarkAsDirty(); }
/// <summary> /// Update the sprite atlas, keeping only the sprites that are on the specified list. /// </summary> static void UpdateAtlas(NGUIAtlas atlas, List <SpriteEntry> sprites) { if (sprites.Count > 0) { // Combine all sprites into a single texture and save it if (UpdateTexture(atlas, sprites)) { // Replace the sprites within the atlas ReplaceSprites(atlas, sprites); // Release the temporary textures ReleaseSprites(sprites); } else { return; } } else { atlas.spriteList.Clear(); string path = NGUIEditorTools.GetSaveableTexturePath(atlas); atlas.spriteMaterial.mainTexture = null; if (!string.IsNullOrEmpty(path)) { AssetDatabase.DeleteAsset(path); } } atlas.MarkAsDirty(); Debug.Log("The atlas has been updated. Don't forget to save the scene to write the changes!"); }
/// <summary> /// Show the selection wizard. /// </summary> public static void Show(NGUIAtlas atlas, NGUISprite selectedSprite) { SpriteSelector comp = ScriptableWizard.DisplayWizard<SpriteSelector>("Select a Sprite"); comp.mAtlas = atlas; comp.mSprite = selectedSprite; comp.mCallback = null; }
public GrayAtlas(NGUIAtlas a) { this.src = a; this.gray = a.Clone(src.spriteMaterial.shader.name); this.gray.spriteMaterial.SetFloat("_GreyStrength", 1); this.gray.name = a.name; }
/// <summary> /// Duplicate the specified sprite. /// </summary> static public SpriteEntry DuplicateSprite(NGUIAtlas atlas, string spriteName) { if (atlas == null || atlas.texture == null) { return(null); } UISpriteData sd = atlas.GetSprite(spriteName); if (sd == null) { return(null); } Texture2D tex = NGUIEditorTools.ImportTexture(atlas.texture, true, true, false); SpriteEntry se = ExtractSprite(sd, tex); if (se != null) { se.name = se.name + " (Copy)"; List <UIAtlasMaker.SpriteEntry> sprites = new List <UIAtlasMaker.SpriteEntry>(); UIAtlasMaker.ExtractSprites(atlas, sprites); sprites.Add(se); UIAtlasMaker.UpdateAtlas(atlas, sprites); se.Release(); } else { NGUIEditorTools.ImportTexture(atlas.texture, false, false, !atlas.premultipliedAlpha); } return(se); }
public static bool HasGrayAtlas(NGUIAtlas a) { if (inst == null) { return(false); } return(inst.HasGray(a)); }
/// <summary> /// Show the selection wizard. /// </summary> public static void Show(NGUIAtlas atlas, NGUISprite selectedSprite) { SpriteSelector comp = ScriptableWizard.DisplayWizard <SpriteSelector>("Select a Sprite"); comp.mAtlas = atlas; comp.mSprite = selectedSprite; comp.mCallback = null; }
/// <summary> /// Helper function that determines whether the two atlases are related. /// </summary> static public bool CheckIfRelated(NGUIAtlas a, NGUIAtlas b) { if (a == null || b == null) { return(false); } return(a == b || a.References(b) || b.References(a)); }
private void OnSelectAtlasForSprite(Object obj) { if (obj == null) { return; } atlas4Sprite = obj as NGUIAtlas; }
/// <summary> /// Show the selection wizard. /// </summary> public static void Show(NGUIAtlas atlas, string selectedSprite, Callback callback) { SpriteSelector comp = ScriptableWizard.DisplayWizard<SpriteSelector>("Select a Sprite"); comp.mAtlas = atlas; comp.mSprite = null; comp.mName = selectedSprite; comp.mCallback = callback; }
/// <summary> /// Show the selection wizard. /// </summary> public static void Show(NGUIAtlas atlas, string selectedSprite, Callback callback) { SpriteSelector comp = ScriptableWizard.DisplayWizard <SpriteSelector>("Select a Sprite"); comp.mAtlas = atlas; comp.mSprite = null; comp.mName = selectedSprite; comp.mCallback = callback; }
public static GrayAtlas GetGrayAtlas(NGUIAtlas a) { if (inst == null) { var go = new GameObject("GrayAtlasPool", typeof(GrayAtlasPool)); inst = go.GetComponent <GrayAtlasPool>(); } return(inst.GetGray(a)); }
/// <summary> /// Add a sprite appropriate for the specified atlas sprite. /// It will be sliced if the sprite has an inner rect, and a regular sprite otherwise. /// </summary> static public NGUISprite AddSprite(GameObject go, NGUIAtlas atlas, string spriteName) { NGUIAtlas.Sprite sp = (atlas != null) ? atlas.GetSprite(spriteName) : null; NGUISprite sprite = AddWidget <NGUISprite>(go); sprite.type = (sp == null || sp.inner == sp.outer) ? NGUISprite.Type.Simple : NGUISprite.Type.Sliced; sprite.atlas = atlas; sprite.spriteName = spriteName; return(sprite); }
public GrayAtlas GetGray(NGUIAtlas a) { GrayAtlas ga = pool.Get(a.name); if (ga == null) { ga = new GrayAtlas(a); pool[a.name] = ga; } return(ga); }
/// <summary> /// Add the specified texture to the atlas, or update an existing one. /// </summary> static public void AddOrUpdate(NGUIAtlas atlas, Texture2D tex) { if (atlas != null && tex != null) { List <Texture> textures = new List <Texture>(); textures.Add(tex); List <SpriteEntry> sprites = CreateSprites(textures); ExtractSprites(atlas, sprites); UpdateAtlas(atlas, sprites); } }
/// <summary> /// Add the specified texture to the atlas, or update an existing one. /// </summary> public static void AddOrUpdate(NGUIAtlas atlas, Texture2D tex) { if (atlas != null && tex != null) { List<Texture> textures = new List<Texture>(); textures.Add(tex); List<SpriteEntry> sprites = CreateSprites(textures); ExtractSprites(atlas, sprites); UpdateAtlas(atlas, sprites); } }
/// <summary> /// Draw a sprite selection field. /// </summary> static public void SpriteField(string fieldName, NGUIAtlas atlas, string spriteName, SpriteSelector.Callback callback, params GUILayoutOption[] options) { GUILayout.BeginHorizontal(); GUILayout.Label(fieldName, GUILayout.Width(76f)); if (GUILayout.Button(spriteName, "MiniPullDown", options)) { SpriteSelector.Show(atlas, spriteName, callback); } GUILayout.EndHorizontal(); }
/// <summary> /// Helper function that determines whether the atlas uses the specified one, taking replacements into account. /// </summary> bool References(NGUIAtlas atlas) { if (atlas == null) { return(false); } if (atlas == this) { return(true); } return((mReplacement != null) ? mReplacement.References(atlas) : false); }
private void ChangeAtlas(GameObject obj, List <NGUIAtlas> filtered, NGUIAtlas changeAtlas) { foreach (UISprite s in obj.GetComponentsInChildren <UISprite>(true)) { if (s.spriteName == searchSpriteName && changeAtlas != s.atlas && filtered.Contains(s.atlas as NGUIAtlas)) { Debug.LogFormat("{0} ({1}): {2} -> {3}", s.transform.GetScenePath(), s.spriteName, s.atlas.name(), changeAtlas.name()); s.atlas = changeAtlas; EditorUtil.SetDirty(s); } } }
/// <summary> /// Validate this symbol, given the specified atlas. /// </summary> public bool Validate(NGUIAtlas atlas) { if (atlas == null) { return(false); } #if UNITY_EDITOR if (!Application.isPlaying || !mIsValid) #else if (!mIsValid) #endif { if (string.IsNullOrEmpty(spriteName)) { return(false); } mSprite = (atlas != null) ? atlas.GetSprite(spriteName) : null; if (mSprite != null) { Texture tex = atlas.texture; if (tex == null) { mSprite = null; } else { Rect outer = mSprite.outer; mUV = outer; if (atlas.coordinates == NGUIAtlas.Coordinates.Pixels) { mUV = NGUIMath.ConvertToTexCoords(mUV, tex.width, tex.height); } else { outer = NGUIMath.ConvertToPixels(outer, tex.width, tex.height, true); } mOffsetX = Mathf.RoundToInt(mSprite.paddingLeft * outer.width); mOffsetY = Mathf.RoundToInt(mSprite.paddingTop * outer.width); mWidth = Mathf.RoundToInt(outer.width); mHeight = Mathf.RoundToInt(outer.height); mAdvance = Mathf.RoundToInt(outer.width + (mSprite.paddingRight + mSprite.paddingLeft) * outer.width); mIsValid = true; } } } return(mSprite != null); }
/// <summary> /// Convenience function that displays a list of sprites and returns the selected value. /// </summary> static public void AdvancedSpriteField(NGUIAtlas atlas, string spriteName, SpriteSelector.Callback callback, bool editable, params GUILayoutOption[] options) { // Give the user a warning if there are no sprites in the atlas if (atlas.spriteList.Count == 0) { EditorGUILayout.HelpBox("No sprites found", MessageType.Warning); return; } // Sprite selection drop-down list GUILayout.BeginHorizontal(); { if (GUILayout.Button("Sprite", "DropDownButton", GUILayout.Width(76f))) { SpriteSelector.Show(atlas, spriteName, callback); } if (editable) { string sn = GUILayout.TextField(spriteName); if (sn != spriteName) { NGUIAtlas.Sprite sp = atlas.GetSprite(spriteName); if (sp != null) { NGUIEditorTools.RegisterUndo("Edit Sprite Name", atlas); sp.name = sn; spriteName = sn; } } } else { GUILayout.BeginHorizontal(); GUILayout.Label(spriteName, "HelpBox", GUILayout.Height(18f)); GUILayout.Space(18f); GUILayout.EndHorizontal(); if (GUILayout.Button("Edit", GUILayout.Width(40f))) { EditorPrefs.SetString("NGUI Selected Sprite", spriteName); Select(atlas.gameObject); } } } GUILayout.EndHorizontal(); }
/// <summary> /// Draw a simple sprite selection button. /// </summary> static public bool SimpleSpriteField(NGUIAtlas atlas, string spriteName, SpriteSelector.Callback callback, params GUILayoutOption[] options) { if (atlas.GetSprite(spriteName) == null) { spriteName = ""; } if (GUILayout.Button(spriteName, "DropDown", options)) { SpriteSelector.Show(atlas, spriteName, callback); return(true); } return(false); }
public static NGUIAtlas Clone(this INGUIAtlas a, string shaderName) { NGUIAtlas b = Object.Instantiate(a.origin()); Object.DontDestroyOnLoad(b); if (b.replacement != null) { b.replacement = Object.Instantiate(b.origin()); Object.DontDestroyOnLoad(b.origin()); } b.spriteMaterial = Object.Instantiate(b.spriteMaterial); Object.DontDestroyOnLoad(b.spriteMaterial); b.spriteMaterial.shader = Shader.Find(shaderName); return(b); }
/// <summary> /// Replacement atlas selection callback. /// </summary> void OnSelectAtlas(MonoBehaviour obj) { if (mReplacement != obj) { // Undo doesn't work correctly in this case... so I won't bother. //NGUIEditorTools.RegisterUndo("Atlas Change"); //NGUIEditorTools.RegisterUndo("Atlas Change", mAtlas); mAtlas.replacement = obj as NGUIAtlas; mReplacement = mAtlas.replacement; UnityEditor.EditorUtility.SetDirty(mAtlas); if (mReplacement == null) { mType = AtlasType.Normal; } } }
private void OnSelectAtlas(Object obj) { if (obj == null) { return; } NGUIAtlas old = atlasToAdd; atlasToAdd = obj as NGUIAtlas; if (atlasToAdd != old) { if (atlasToAdd != null) { if (!atlasRefs.Contains(atlasToAdd)) { atlasRefs.Add(atlasToAdd); SaveAtlasRefs(); } } } CreateAtlasMap(); }
/// <summary> /// Draw a sprite selection field. /// </summary> static public void SpriteField(string fieldName, string caption, NGUIAtlas atlas, string spriteName, SpriteSelector.Callback callback) { GUILayout.BeginHorizontal(); GUILayout.Label(fieldName, GUILayout.Width(76f)); if (atlas.GetSprite(spriteName) == null) { spriteName = ""; } if (GUILayout.Button(spriteName, "MiniPullDown", GUILayout.Width(120f))) { SpriteSelector.Show(atlas, spriteName, callback); } if (!string.IsNullOrEmpty(caption)) { GUILayout.Space(20f); GUILayout.Label(caption); } GUILayout.EndHorizontal(); }
/// <summary> /// Figures out the saveable filename for the texture of the specified atlas. /// </summary> static public string GetSaveableTexturePath(NGUIAtlas atlas) { // Path where the texture atlas will be saved string path = ""; // If the atlas already has a texture, overwrite its texture if (atlas.texture != null) { path = AssetDatabase.GetAssetPath(atlas.texture.GetInstanceID()); if (!string.IsNullOrEmpty(path)) { int dot = path.LastIndexOf('.'); return(path.Substring(0, dot) + ".png"); } } // No texture to use -- figure out a name using the atlas path = AssetDatabase.GetAssetPath(atlas.GetInstanceID()); path = string.IsNullOrEmpty(path) ? "Assets/" + atlas.name + ".png" : path.Replace(".prefab", ".png"); return(path); }
private void CreateAtlasMap() { HashSet <string> dup = new HashSet <string>(); atlasMap = new Dictionary <string, NGUIAtlas>(); foreach (NGUIAtlas a in atlasRefs) { foreach (UISpriteData sprite in a.spriteList) { NGUIAtlas dupAtlas = atlasMap.Get(sprite.name); if (dupAtlas != null) { dup.Add(sprite.name); } else { atlasMap[sprite.name] = a; } } } dupSprites = new List <string>(dup); dupSprites.Sort(); }
public override void DoLocalize(Localize cmp, string mainTranslation, string secondaryTranslation) { if (mTarget.spriteName == mainTranslation) { return; } //--[ Localize Atlas ]---------- UIAtlas newAtlas = cmp.GetSecondaryTranslatedObj <UIAtlas>(ref mainTranslation, ref secondaryTranslation); bool bChanged = false; if (newAtlas != null && ((mTarget.atlas as UIAtlas) != newAtlas)) { mTarget.atlas = newAtlas; bChanged = true; } if (newAtlas == null) { NGUIAtlas newNGUIAtlas = cmp.GetSecondaryTranslatedObj <NGUIAtlas>(ref mainTranslation, ref secondaryTranslation); if (newAtlas != null && ((mTarget.atlas as NGUIAtlas) != newAtlas)) { mTarget.atlas = newAtlas; bChanged = true; } } if (mTarget.spriteName != mainTranslation && mTarget.atlas.GetSprite(mainTranslation) != null) { mTarget.spriteName = mainTranslation; bChanged = true; } if (bChanged) { mTarget.MakePixelPerfect(); } }
/// <summary> /// Combine all sprites into a single texture and save it to disk. /// </summary> static bool UpdateTexture(NGUIAtlas atlas, List <SpriteEntry> sprites) { // Get the texture for the atlas Texture2D tex = atlas.texture as Texture2D; string oldPath = (tex != null) ? AssetDatabase.GetAssetPath(tex.GetInstanceID()) : ""; string newPath = NGUIEditorTools.GetSaveableTexturePath(atlas); // Clear the read-only flag in texture file attributes if (System.IO.File.Exists(newPath)) { System.IO.FileAttributes newPathAttrs = System.IO.File.GetAttributes(newPath); newPathAttrs &= ~System.IO.FileAttributes.ReadOnly; System.IO.File.SetAttributes(newPath, newPathAttrs); } bool newTexture = (tex == null || oldPath != newPath); if (newTexture) { // Create a new texture for the atlas tex = new Texture2D(1, 1, TextureFormat.ARGB32, false); } else { // Make the atlas readable so we can save it tex = NGUIEditorTools.ImportTexture(oldPath, true, false); } // Pack the sprites into this texture if (PackTextures(tex, sprites)) { byte[] bytes = tex.EncodeToPNG(); System.IO.File.WriteAllBytes(newPath, bytes); bytes = null; // Load the texture we just saved as a Texture2D AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); tex = NGUIEditorTools.ImportTexture(newPath, false, true); // Update the atlas texture if (newTexture) { if (tex == null) { Debug.LogError("Failed to load the created atlas saved as " + newPath); } else { atlas.spriteMaterial.mainTexture = tex; } AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); } return(true); } else { if (!newTexture) { NGUIEditorTools.ImportTexture(oldPath, false, true); } //Debug.LogError("Operation canceled: The selected sprites can't fit into the atlas.\n" + // "Keep large sprites outside the atlas (use NGUITexture), and/or use multiple atlases instead."); EditorUtility.DisplayDialog("Operation Canceled", "The selected sprites can't fit into the atlas.\n" + "Keep large sprites outside the atlas (use NGUITexture), and/or use multiple atlases instead", "OK"); return(false); } }
static void Load() { int l = LayerMask.NameToLayer("UI"); if (l == -1) l = LayerMask.NameToLayer("GUI"); if (l == -1) l = 31; mLoaded = true; mPartial = EditorPrefs.GetString("NGUI Partial"); mFontName = EditorPrefs.GetString("NGUI Font Name"); mAtlasName = EditorPrefs.GetString("NGUI Atlas Name"); mFontData = GetObject("NGUI Font Asset") as TextAsset; mFontTexture = GetObject("NGUI Font Texture") as Texture2D; mFont = GetObject("NGUI Font") as NGUIFont; mAtlas = GetObject("NGUI Atlas") as NGUIAtlas; mAtlasPadding = EditorPrefs.GetInt("NGUI Atlas Padding", 1); mAtlasTrimming = EditorPrefs.GetBool("NGUI Atlas Trimming", true); mUnityPacking = EditorPrefs.GetBool("NGUI Unity Packing", true); mForceSquare = EditorPrefs.GetBool("NGUI Force Square Atlas", true); mPivot = (NGUIWidget.Pivot)EditorPrefs.GetInt("NGUI Pivot", (int)mPivot); mLayer = EditorPrefs.GetInt("NGUI Layer", l); mDynFont = GetObject("NGUI DynFont") as Font; mDynFontSize = EditorPrefs.GetInt("NGUI DynFontSize", 16); mDynFontStyle = (FontStyle)EditorPrefs.GetInt("NGUI DynFontStyle", (int)FontStyle.Normal); LoadColor(); }
/// <summary> /// Update the sprite atlas, keeping only the sprites that are on the specified list. /// </summary> static void UpdateAtlas(NGUIAtlas atlas, List<SpriteEntry> sprites) { if (sprites.Count > 0) { // Combine all sprites into a single texture and save it if (UpdateTexture(atlas, sprites)) { // Replace the sprites within the atlas ReplaceSprites(atlas, sprites); // Release the temporary textures ReleaseSprites(sprites); } else return; } else { atlas.spriteList.Clear(); string path = NGUIEditorTools.GetSaveableTexturePath(atlas); atlas.spriteMaterial.mainTexture = null; if (!string.IsNullOrEmpty(path)) AssetDatabase.DeleteAsset(path); } atlas.MarkAsDirty(); Debug.Log("The atlas has been updated. Don't forget to save the scene to write the changes!"); }
/// <summary> /// Helper function that determines whether the atlas uses the specified one, taking replacements into account. /// </summary> bool References(NGUIAtlas atlas) { if (atlas == null) return false; if (atlas == this) return true; return (mReplacement != null) ? mReplacement.References(atlas) : false; }
/// <summary> /// Replace the sprites within the atlas. /// </summary> static void ReplaceSprites(NGUIAtlas atlas, List<SpriteEntry> sprites) { // Get the list of sprites we'll be updating List<NGUIAtlas.Sprite> spriteList = atlas.spriteList; List<NGUIAtlas.Sprite> kept = new List<NGUIAtlas.Sprite>(); // The atlas must be in pixels atlas.coordinates = NGUIAtlas.Coordinates.Pixels; // Run through all the textures we added and add them as sprites to the atlas for (int i = 0; i < sprites.Count; ++i) { SpriteEntry se = sprites[i]; NGUIAtlas.Sprite sprite = AddSprite(spriteList, se); kept.Add(sprite); } // Remove unused sprites for (int i = spriteList.Count; i > 0; ) { NGUIAtlas.Sprite sp = spriteList[--i]; if (!kept.Contains(sp)) spriteList.RemoveAt(i); } atlas.MarkAsDirty(); }
/// <summary> /// Draw the inspector widget. /// </summary> public override void OnInspectorGUI() { EditorGUIUtility.LookLikeControls(80f); mAtlas = target as NGUIAtlas; NGUIEditorTools.DrawSeparator(); if (mAtlas.replacement != null) { mType = AtlasType.Reference; mReplacement = mAtlas.replacement; } AtlasType after = (AtlasType)EditorGUILayout.EnumPopup("Atlas Type", mType); if (mType != after) { if (after == AtlasType.Normal) { OnSelectAtlas(null); } else { mType = AtlasType.Reference; } } if (mType == AtlasType.Reference) { ComponentSelector.Draw<NGUIAtlas>(mAtlas.replacement, OnSelectAtlas); NGUIEditorTools.DrawSeparator(); EditorGUILayout.HelpBox("You can have one atlas simply point to " + "another one. This is useful if you want to be " + "able to quickly replace the contents of one " + "atlas with another one, for example for " + "swapping an SD atlas with an HD one, or " + "replacing an English atlas with a Chinese " + "one. All the sprites referencing this atlas " + "will update their references to the new one.", MessageType.Info); if (mReplacement != mAtlas && mAtlas.replacement != mReplacement) { NGUIEditorTools.RegisterUndo("Atlas Change", mAtlas); mAtlas.replacement = mReplacement; UnityEditor.EditorUtility.SetDirty(mAtlas); } return; } if (!mConfirmDelete) { NGUIEditorTools.DrawSeparator(); Material mat = EditorGUILayout.ObjectField("Material", mAtlas.spriteMaterial, typeof(Material), false) as Material; if (mAtlas.spriteMaterial != mat) { NGUIEditorTools.RegisterUndo("Atlas Change", mAtlas); mAtlas.spriteMaterial = mat; // Ensure that this atlas has valid import settings if (mAtlas.texture != null) NGUIEditorTools.ImportTexture(mAtlas.texture, false, false); mAtlas.MarkAsDirty(); mConfirmDelete = false; } if (mat != null) { TextAsset ta = EditorGUILayout.ObjectField("TP Import", null, typeof(TextAsset), false) as TextAsset; if (ta != null) { // Ensure that this atlas has valid import settings if (mAtlas.texture != null) NGUIEditorTools.ImportTexture(mAtlas.texture, false, false); NGUIEditorTools.RegisterUndo("Import Sprites", mAtlas); NGUIJson.LoadSpriteData(mAtlas, ta); if (mSprite != null) mSprite = mAtlas.GetSprite(mSprite.name); mAtlas.MarkAsDirty(); } NGUIAtlas.Coordinates coords = (NGUIAtlas.Coordinates)EditorGUILayout.EnumPopup("Coordinates", mAtlas.coordinates); if (coords != mAtlas.coordinates) { NGUIEditorTools.RegisterUndo("Atlas Change", mAtlas); mAtlas.coordinates = coords; mConfirmDelete = false; } float pixelSize = EditorGUILayout.FloatField("Pixel Size", mAtlas.pixelSize, GUILayout.Width(120f)); if (pixelSize != mAtlas.pixelSize) { NGUIEditorTools.RegisterUndo("Atlas Change", mAtlas); mAtlas.pixelSize = pixelSize; mConfirmDelete = false; } } } if (mAtlas.spriteMaterial != null) { Color blue = new Color(0f, 0.7f, 1f, 1f); Color green = new Color(0.4f, 1f, 0f, 1f); if (mConfirmDelete) { if (mSprite != null) { // Show the confirmation dialog NGUIEditorTools.DrawSeparator(); GUILayout.Label("Are you sure you want to delete '" + mSprite.name + "'?"); NGUIEditorTools.DrawSeparator(); GUILayout.BeginHorizontal(); { GUI.backgroundColor = Color.green; if (GUILayout.Button("Cancel")) mConfirmDelete = false; GUI.backgroundColor = Color.red; if (GUILayout.Button("Delete")) { NGUIEditorTools.RegisterUndo("Delete Sprite", mAtlas); mAtlas.spriteList.Remove(mSprite); mConfirmDelete = false; } GUI.backgroundColor = Color.white; } GUILayout.EndHorizontal(); } else mConfirmDelete = false; } else { if (mSprite == null && mAtlas.spriteList.Count > 0) { string spriteName = EditorPrefs.GetString("NGUI Selected Sprite"); if (!string.IsNullOrEmpty(spriteName)) mSprite = mAtlas.GetSprite(spriteName); if (mSprite == null) mSprite = mAtlas.spriteList[0]; } if (!mConfirmDelete && mSprite != null) { NGUIEditorTools.DrawSeparator(); NGUIEditorTools.AdvancedSpriteField(mAtlas, mSprite.name, SelectSprite, true); if (mSprite == null) return; Texture2D tex = mAtlas.spriteMaterial.mainTexture as Texture2D; if (tex != null) { Rect inner = mSprite.inner; Rect outer = mSprite.outer; if (mAtlas.coordinates == NGUIAtlas.Coordinates.Pixels) { GUI.backgroundColor = green; outer = NGUIEditorTools.IntRect("Dimensions", mSprite.outer); Vector4 border = new Vector4( mSprite.inner.xMin - mSprite.outer.xMin, mSprite.inner.yMin - mSprite.outer.yMin, mSprite.outer.xMax - mSprite.inner.xMax, mSprite.outer.yMax - mSprite.inner.yMax); GUI.backgroundColor = blue; border = NGUIEditorTools.IntPadding("Border", border); GUI.backgroundColor = Color.white; inner.xMin = mSprite.outer.xMin + border.x; inner.yMin = mSprite.outer.yMin + border.y; inner.xMax = mSprite.outer.xMax - border.z; inner.yMax = mSprite.outer.yMax - border.w; } else { // Draw the inner and outer rectangle dimensions GUI.backgroundColor = green; outer = EditorGUILayout.RectField("Outer Rect", mSprite.outer); GUI.backgroundColor = blue; inner = EditorGUILayout.RectField("Inner Rect", mSprite.inner); GUI.backgroundColor = Color.white; } if (outer.xMax < outer.xMin) outer.xMax = outer.xMin; if (outer.yMax < outer.yMin) outer.yMax = outer.yMin; if (outer != mSprite.outer) { float x = outer.xMin - mSprite.outer.xMin; float y = outer.yMin - mSprite.outer.yMin; inner.x += x; inner.y += y; } // Sanity checks to ensure that the inner rect is always inside the outer inner.xMin = Mathf.Clamp(inner.xMin, outer.xMin, outer.xMax); inner.xMax = Mathf.Clamp(inner.xMax, outer.xMin, outer.xMax); inner.yMin = Mathf.Clamp(inner.yMin, outer.yMin, outer.yMax); inner.yMax = Mathf.Clamp(inner.yMax, outer.yMin, outer.yMax); bool changed = false; if (mSprite.inner != inner || mSprite.outer != outer) { NGUIEditorTools.RegisterUndo("Atlas Change", mAtlas); mSprite.inner = inner; mSprite.outer = outer; MarkSpriteAsDirty(); changed = true; } EditorGUILayout.Separator(); if (mAtlas.coordinates == NGUIAtlas.Coordinates.Pixels) { int left = Mathf.RoundToInt(mSprite.paddingLeft * mSprite.outer.width); int right = Mathf.RoundToInt(mSprite.paddingRight * mSprite.outer.width); int top = Mathf.RoundToInt(mSprite.paddingTop * mSprite.outer.height); int bottom = Mathf.RoundToInt(mSprite.paddingBottom * mSprite.outer.height); NGUIEditorTools.IntVector a = NGUIEditorTools.IntPair("Padding", "Left", "Top", left, top); NGUIEditorTools.IntVector b = NGUIEditorTools.IntPair(null, "Right", "Bottom", right, bottom); if (changed || a.x != left || a.y != top || b.x != right || b.y != bottom) { NGUIEditorTools.RegisterUndo("Atlas Change", mAtlas); mSprite.paddingLeft = a.x / mSprite.outer.width; mSprite.paddingTop = a.y / mSprite.outer.height; mSprite.paddingRight = b.x / mSprite.outer.width; mSprite.paddingBottom = b.y / mSprite.outer.height; MarkSpriteAsDirty(); } } else { // Create a button that can make the coordinates pixel-perfect on click GUILayout.BeginHorizontal(); { GUILayout.Label("Correction", GUILayout.Width(75f)); Rect corrected0 = outer; Rect corrected1 = inner; if (mAtlas.coordinates == NGUIAtlas.Coordinates.Pixels) { corrected0 = NGUIMath.MakePixelPerfect(corrected0); corrected1 = NGUIMath.MakePixelPerfect(corrected1); } else { corrected0 = NGUIMath.MakePixelPerfect(corrected0, tex.width, tex.height); corrected1 = NGUIMath.MakePixelPerfect(corrected1, tex.width, tex.height); } if (corrected0 == mSprite.outer && corrected1 == mSprite.inner) { GUI.color = Color.grey; GUILayout.Button("Make Pixel-Perfect"); GUI.color = Color.white; } else if (GUILayout.Button("Make Pixel-Perfect")) { outer = corrected0; inner = corrected1; GUI.changed = true; } } GUILayout.EndHorizontal(); } } // This functionality is no longer used. It became obsolete when the Atlas Maker was added. /*NGUIEditorTools.DrawSeparator(); GUILayout.BeginHorizontal(); { EditorGUILayout.PrefixLabel("Add/Delete"); if (GUILayout.Button("Clone Sprite")) { NGUIEditorTools.RegisterUndo("Add Sprite", mAtlas); NGUIAtlas.Sprite newSprite = new NGUIAtlas.Sprite(); if (mSprite != null) { newSprite.name = "Copy of " + mSprite.name; newSprite.outer = mSprite.outer; newSprite.inner = mSprite.inner; } else { newSprite.name = "New Sprite"; } mAtlas.spriteList.Add(newSprite); mSprite = newSprite; } // Show the delete button GUI.backgroundColor = Color.red; if (mSprite != null && GUILayout.Button("Delete", GUILayout.Width(55f))) { mConfirmDelete = true; } GUI.backgroundColor = Color.white; } GUILayout.EndHorizontal();*/ if (NGUIEditorTools.previousSelection != null) { NGUIEditorTools.DrawSeparator(); GUI.backgroundColor = Color.green; if (GUILayout.Button("<< Return to " + NGUIEditorTools.previousSelection.name)) { NGUIEditorTools.SelectPrevious(); } GUI.backgroundColor = Color.white; } } } } }
/// <summary> /// Extract sprites from the atlas, adding them to the list. /// </summary> static void ExtractSprites(NGUIAtlas atlas, List<SpriteEntry> sprites) { // Make the atlas texture readable Texture2D atlasTex = NGUIEditorTools.ImportTexture(atlas.texture, true, false); if (atlasTex != null) { atlas.coordinates = NGUIAtlas.Coordinates.Pixels; Color32[] oldPixels = null; int oldWidth = atlasTex.width; int oldHeight = atlasTex.height; List<NGUIAtlas.Sprite> list = atlas.spriteList; foreach (NGUIAtlas.Sprite asp in list) { bool found = false; foreach (SpriteEntry se in sprites) { if (asp.name == se.tex.name) { found = true; break; } } if (!found) { // Read the atlas if (oldPixels == null) oldPixels = atlasTex.GetPixels32(); Rect rect = asp.outer; rect.xMin = Mathf.Clamp(rect.xMin, 0f, oldWidth); rect.yMin = Mathf.Clamp(rect.yMin, 0f, oldHeight); rect.xMax = Mathf.Clamp(rect.xMax, 0f, oldWidth); rect.yMax = Mathf.Clamp(rect.yMax, 0f, oldHeight); int newWidth = Mathf.RoundToInt(rect.width); int newHeight = Mathf.RoundToInt(rect.height); if (newWidth == 0 || newHeight == 0) continue; Color32[] newPixels = new Color32[newWidth * newHeight]; int xmin = Mathf.RoundToInt(rect.x); int ymin = Mathf.RoundToInt(oldHeight - rect.yMax); for (int y = 0; y < newHeight; ++y) { for (int x = 0; x < newWidth; ++x) { int newIndex = y * newWidth + x; int oldIndex = (ymin + y) * oldWidth + (xmin + x); newPixels[newIndex] = oldPixels[oldIndex]; } } // Create a new sprite SpriteEntry sprite = new SpriteEntry(); sprite.temporaryTexture = true; sprite.tex = new Texture2D(newWidth, newHeight); sprite.tex.name = asp.name; sprite.rect = new Rect(0f, 0f, newWidth, newHeight); sprite.tex.SetPixels32(newPixels); sprite.tex.Apply(); // Min/max coordinates are in pixels sprite.minX = Mathf.RoundToInt(asp.paddingLeft * newWidth); sprite.maxX = Mathf.RoundToInt(asp.paddingRight * newWidth); sprite.minY = Mathf.RoundToInt(asp.paddingBottom * newHeight); sprite.maxY = Mathf.RoundToInt(asp.paddingTop * newHeight); sprites.Add(sprite); } } } // The atlas no longer needs to be readable NGUIEditorTools.ImportTexture(atlas.texture, false, false); }
/// <summary> /// Set the atlas sprite directly. /// </summary> protected void SetAtlasSprite(NGUIAtlas.Sprite sp) { mChanged = true; mSpriteSet = true; if (sp != null) { mSprite = sp; mSpriteName = mSprite.name; } else { mSpriteName = (mSprite != null) ? mSprite.name : ""; mSprite = sp; } }
/// <summary> /// Combine all sprites into a single texture and save it to disk. /// </summary> static bool UpdateTexture(NGUIAtlas atlas, List<SpriteEntry> sprites) { // Get the texture for the atlas Texture2D tex = atlas.texture as Texture2D; string oldPath = (tex != null) ? AssetDatabase.GetAssetPath(tex.GetInstanceID()) : ""; string newPath = NGUIEditorTools.GetSaveableTexturePath(atlas); // Clear the read-only flag in texture file attributes if (System.IO.File.Exists(newPath)) { System.IO.FileAttributes newPathAttrs = System.IO.File.GetAttributes(newPath); newPathAttrs &= ~System.IO.FileAttributes.ReadOnly; System.IO.File.SetAttributes(newPath, newPathAttrs); } bool newTexture = (tex == null || oldPath != newPath); if (newTexture) { // Create a new texture for the atlas tex = new Texture2D(1, 1, TextureFormat.ARGB32, false); } else { // Make the atlas readable so we can save it tex = NGUIEditorTools.ImportTexture(oldPath, true, false); } // Pack the sprites into this texture if (PackTextures(tex, sprites)) { byte[] bytes = tex.EncodeToPNG(); System.IO.File.WriteAllBytes(newPath, bytes); bytes = null; // Load the texture we just saved as a Texture2D AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); tex = NGUIEditorTools.ImportTexture(newPath, false, true); // Update the atlas texture if (newTexture) { if (tex == null) Debug.LogError("Failed to load the created atlas saved as " + newPath); else atlas.spriteMaterial.mainTexture = tex; AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); } return true; } else { if (!newTexture) NGUIEditorTools.ImportTexture(oldPath, false, true); //Debug.LogError("Operation canceled: The selected sprites can't fit into the atlas.\n" + // "Keep large sprites outside the atlas (use NGUITexture), and/or use multiple atlases instead."); EditorUtility.DisplayDialog("Operation Canceled", "The selected sprites can't fit into the atlas.\n" + "Keep large sprites outside the atlas (use NGUITexture), and/or use multiple atlases instead", "OK"); return false; } }
/// <summary> /// Replacement atlas selection callback. /// </summary> void OnSelectAtlas(MonoBehaviour obj) { if (mReplacement != obj) { // Undo doesn't work correctly in this case... so I won't bother. //NGUIEditorTools.RegisterUndo("Atlas Change"); //NGUIEditorTools.RegisterUndo("Atlas Change", mAtlas); mAtlas.replacement = obj as NGUIAtlas; mReplacement = mAtlas.replacement; UnityEditor.EditorUtility.SetDirty(mAtlas); if (mReplacement == null) mType = AtlasType.Normal; } }
/// <summary> /// Helper function that determines whether the two atlases are related. /// </summary> public static bool CheckIfRelated(NGUIAtlas a, NGUIAtlas b) { if (a == null || b == null) return false; return a == b || a.References(b) || b.References(a); }
/// <summary> /// Validate this symbol, given the specified atlas. /// </summary> public bool Validate(NGUIAtlas atlas) { if (atlas == null) return false; #if UNITY_EDITOR if (!Application.isPlaying || !mIsValid) #else if (!mIsValid) #endif { if (string.IsNullOrEmpty(spriteName)) return false; mSprite = (atlas != null) ? atlas.GetSprite(spriteName) : null; if (mSprite != null) { Texture tex = atlas.texture; if (tex == null) { mSprite = null; } else { Rect outer = mSprite.outer; mUV = outer; if (atlas.coordinates == NGUIAtlas.Coordinates.Pixels) { mUV = NGUIMath.ConvertToTexCoords(mUV, tex.width, tex.height); } else { outer = NGUIMath.ConvertToPixels(outer, tex.width, tex.height, true); } mOffsetX = Mathf.RoundToInt(mSprite.paddingLeft * outer.width); mOffsetY = Mathf.RoundToInt(mSprite.paddingTop * outer.width); mWidth = Mathf.RoundToInt(outer.width); mHeight = Mathf.RoundToInt(outer.height); mAdvance = Mathf.RoundToInt(outer.width + (mSprite.paddingRight + mSprite.paddingLeft) * outer.width); mIsValid = true; } } } return (mSprite != null); }