/// <summary> /// Add a new sprite to the atlas, given the texture it's coming from and the packed rect within the atlas. /// </summary> static UIAtlas.Sprite AddSprite(List<UIAtlas.Sprite> sprites, SpriteEntry se) { UIAtlas.Sprite sprite = null; // See if this sprite already exists foreach (UIAtlas.Sprite sp in sprites) { Debug.Log(se.tex.name + " " + sp.name); if (sp.name == se.tex.name) { sprite = sp; break; } } if (sprite != null) { float x0 = sprite.inner.xMin - sprite.outer.xMin; float y0 = sprite.inner.yMin - sprite.outer.yMin; float x1 = sprite.outer.xMax - sprite.inner.xMax; float y1 = sprite.outer.yMax - sprite.inner.yMax; sprite.outer = se.rect; sprite.inner = se.rect; sprite.inner.xMin = Mathf.Max(sprite.inner.xMin + x0, sprite.outer.xMin); sprite.inner.yMin = Mathf.Max(sprite.inner.yMin + y0, sprite.outer.yMin); sprite.inner.xMax = Mathf.Min(sprite.inner.xMax - x1, sprite.outer.xMax); sprite.inner.yMax = Mathf.Min(sprite.inner.yMax - y1, sprite.outer.yMax); } else { sprite = new UIAtlas.Sprite(); sprite.name = se.tex.name; sprite.outer = se.rect; sprite.inner = se.rect; sprites.Add(sprite); } float width = Mathf.Max(1f, sprite.outer.width); float height = Mathf.Max(1f, sprite.outer.height); // Sprite's padding values are relative to width and height sprite.paddingLeft = se.minX / width; sprite.paddingRight = se.maxX / width; sprite.paddingTop = se.maxY / height; sprite.paddingBottom = se.minY / height; return sprite; }
/// <summary> /// Validate this symbol, given the specified atlas. /// </summary> public bool Validate (UIAtlas 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 == UIAtlas.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> /// Retrieve the atlas sprite referenced by the spriteName field. /// </summary> public UIAtlas.Sprite GetAtlasSprite() { if (!mSpriteSet) mSprite = null; if (mSprite == null && mAtlas != null) { if (!string.IsNullOrEmpty(mSpriteName)) { UIAtlas.Sprite sp = mAtlas.GetSprite(mSpriteName); if (sp == null) return null; SetAtlasSprite(sp); } if (mSprite == null && mAtlas.spriteList.Count > 0) { UIAtlas.Sprite sp = mAtlas.spriteList[0]; if (sp == null) return null; SetAtlasSprite(sp); if (mSprite == null) { Debug.LogError(mAtlas.name + " seems to have a null sprite!"); return null; } mSpriteName = mSprite.name; } // If the sprite has been set, update the UVs if (mSprite != null) UpdateUVs(true); } return mSprite; }
/// <summary> /// Set the atlas sprite directly. /// </summary> protected void SetAtlasSprite(UIAtlas.Sprite sp) { mChanged = true; mSpriteSet = true; if (sp != null) { mSprite = sp; mSpriteName = mSprite.name; } else { mSpriteName = (mSprite != null) ? mSprite.name : ""; mSprite = sp; } }
/// <summary> /// Draw the inspector widget. /// </summary> public override void OnInspectorGUI() { EditorGUIUtility.LookLikeControls(80f); mAtlas = target as UIAtlas; 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<UIAtlas>(mAtlas.replacement, OnSelectAtlas); NGUIEditorTools.DrawSeparator(); GUILayout.Label("You can have one atlas simply point to\n" + "another one. This is useful if you want to be\n" + "able to quickly replace the contents of one\n" + "atlas with another one, for example for\n" + "swapping an SD atlas with an HD one, or\n" + "replacing an English atlas with a Chinese\n" + "one. All the sprites referencing this atlas\n" + "will update their references to the new one."); 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(); } UIAtlas.Coordinates coords = (UIAtlas.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); 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]; } GUI.backgroundColor = Color.green; GUILayout.BeginHorizontal(); { EditorGUILayout.PrefixLabel("Add/Delete"); if (GUILayout.Button("New Sprite")) { NGUIEditorTools.RegisterUndo("Add Sprite", mAtlas); UIAtlas.Sprite newSprite = new UIAtlas.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 (!mConfirmDelete && mSprite != null) { NGUIEditorTools.DrawSeparator(); string spriteName = UISpriteInspector.SpriteField(mAtlas, mSprite.name); if (spriteName != mSprite.name) { mSprite = mAtlas.GetSprite(spriteName); EditorPrefs.SetString("NGUI Selected Sprite", spriteName); } if (mSprite == null) return; Texture2D tex = mAtlas.spriteMaterial.mainTexture as Texture2D; if (tex != null) { Rect inner = mSprite.inner; Rect outer = mSprite.outer; string name = EditorGUILayout.TextField("Edit Name", mSprite.name); if (mSprite.name != name && !string.IsNullOrEmpty(name)) { bool found = false; foreach (UIAtlas.Sprite sp in mAtlas.spriteList) { if (sp.name == name) { found = true; break; } } if (!found) { NGUIEditorTools.RegisterUndo("Edit Sprite Name", mAtlas); mSprite.name = name; } } if (mAtlas.coordinates == UIAtlas.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); EditorGUILayout.Separator(); // Padding is mainly meant to be used by the 'trimmed' feature of TexturePacker if (mAtlas.coordinates == UIAtlas.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 (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.width; mSprite.paddingRight = b.x / mSprite.outer.height; 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 == UIAtlas.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(); } GUILayout.BeginHorizontal(); { mView = (View)EditorGUILayout.EnumPopup("Show", mView); GUILayout.Label("Shader", GUILayout.Width(45f)); if (mUseShader != EditorGUILayout.Toggle(mUseShader, GUILayout.Width(20f))) { mUseShader = !mUseShader; if (mUseShader && mView == View.Sprite) { // TODO: Remove this when Unity fixes the bug with DrawPreviewTexture not being affected by BeginGroup Debug.LogWarning("There is a bug in Unity that prevents the texture from getting clipped properly.\n" + "Until it's fixed by Unity, your texture may spill onto the rest of the Unity's GUI while using this mode."); } } } GUILayout.EndHorizontal(); if (mSprite.outer != outer || mSprite.inner != inner) { NGUIEditorTools.RegisterUndo("Atlas Change", mAtlas); mSprite.outer = outer; mSprite.inner = inner; mConfirmDelete = false; MarkSpriteAsDirty(); } Rect uv0 = outer; Rect uv1 = inner; if (mAtlas.coordinates == UIAtlas.Coordinates.Pixels) { uv0 = NGUIMath.ConvertToTexCoords(uv0, tex.width, tex.height); uv1 = NGUIMath.ConvertToTexCoords(uv1, tex.width, tex.height); } // Draw the atlas EditorGUILayout.Separator(); Material m = mUseShader ? mAtlas.spriteMaterial : null; Rect rect = (mView == View.Atlas) ? NGUIEditorTools.DrawAtlas(tex, m) : NGUIEditorTools.DrawSprite(tex, uv0, m); // Draw the sprite outline NGUIEditorTools.DrawOutline(rect, uv0, uv1); EditorGUILayout.Separator(); } } } } }
/// <summary> /// Refresh all labels that use this font. /// </summary> public void MarkAsDirty() { mSprite = null; UILabel[] labels = NGUITools.FindActive<UILabel>(); foreach (UILabel lbl in labels) { if (lbl.enabled && lbl.gameObject.active && CheckIfRelated(this, lbl.font)) { UIFont fnt = lbl.font; lbl.font = null; lbl.font = fnt; } } }
/// <summary> /// Ensure that the sprite has been initialized properly. /// This is necessary because the order of execution is unreliable. /// Sometimes the sprite's functions may be called prior to Start(). /// </summary> protected void Init() { if (mAtlas != null) { if (material == null) material = mAtlas.spriteMaterial; if (sprite == null) sprite = string.IsNullOrEmpty(mSpriteName) ? null : mAtlas.GetSprite(mSpriteName); } }
/// <summary> /// Progress bar creation function. /// </summary> void CreateSlider(GameObject go, bool slider) { if (UISettings.atlas != null) { GUILayout.BeginHorizontal(); string bg = UISpriteInspector.SpriteField(UISettings.atlas, "Background", mSliderBG, GUILayout.Width(200f)); GUILayout.Space(20f); GUILayout.Label("Sprite for the background (empty bar)"); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); string fg = UISpriteInspector.SpriteField(UISettings.atlas, "Foreground", mSliderFG, GUILayout.Width(200f)); GUILayout.Space(20f); GUILayout.Label("Sprite for the foreground (full bar)"); GUILayout.EndHorizontal(); string tb = mSliderTB; if (slider) { GUILayout.BeginHorizontal(); tb = UISpriteInspector.SpriteField(UISettings.atlas, "Thumb", mSliderTB, GUILayout.Width(200f)); GUILayout.Space(20f); GUILayout.Label("Sprite for the thumb indicator"); GUILayout.EndHorizontal(); } if (mSliderBG != bg || mSliderFG != fg || mSliderTB != tb) { mSliderBG = bg; mSliderFG = fg; mSliderTB = tb; Save(); } } if (ShouldCreate(go, UISettings.atlas != null)) { int depth = NGUITools.CalculateNextDepth(go); go = NGUITools.AddChild(go); go.name = slider ? "Slider" : "Progress Bar"; // Background sprite UIAtlas.Sprite bgs = UISettings.atlas.GetSprite(mSliderBG); UISprite back = (bgs.inner == bgs.outer) ? (UISprite)NGUITools.AddWidget <UISprite>(go) : (UISprite)NGUITools.AddWidget <UISlicedSprite>(go); back.name = "Background"; back.depth = depth; back.pivot = UIWidget.Pivot.Left; back.atlas = UISettings.atlas; back.spriteName = mSliderBG; back.transform.localScale = new Vector3(200f, 30f, 1f); back.MakePixelPerfect(); // Fireground sprite UIAtlas.Sprite fgs = UISettings.atlas.GetSprite(mSliderFG); UISprite front = (fgs.inner == fgs.outer) ? (UISprite)NGUITools.AddWidget <UIFilledSprite>(go) : (UISprite)NGUITools.AddWidget <UISlicedSprite>(go); front.name = "Foreground"; front.pivot = UIWidget.Pivot.Left; front.atlas = UISettings.atlas; front.spriteName = mSliderFG; front.transform.localScale = new Vector3(200f, 30f, 1f); front.MakePixelPerfect(); // Add a collider if (slider) { NGUITools.AddWidgetCollider(go); } // Add the slider script UISlider uiSlider = go.AddComponent <UISlider>(); uiSlider.foreground = front.transform; uiSlider.fullSize = front.transform.localScale; // Thumb sprite if (slider) { UIAtlas.Sprite tbs = UISettings.atlas.GetSprite(mSliderTB); UISprite thb = (tbs.inner == tbs.outer) ? (UISprite)NGUITools.AddWidget <UISprite>(go) : (UISprite)NGUITools.AddWidget <UISlicedSprite>(go); thb.name = "Thumb"; thb.atlas = UISettings.atlas; thb.spriteName = mSliderTB; thb.transform.localPosition = new Vector3(200f, 0f, 0f); thb.transform.localScale = new Vector3(20f, 40f, 1f); thb.MakePixelPerfect(); NGUITools.AddWidgetCollider(thb.gameObject); thb.gameObject.AddComponent <UIButtonColor>(); thb.gameObject.AddComponent <UIButtonScale>(); uiSlider.thumb = thb.transform; } uiSlider.sliderValue = 0.75f; // Select the slider Selection.activeGameObject = go; } }
/// <summary> /// Sprite selection callback. /// </summary> void SelectSprite(string spriteName) { mSprite = mAtlas.GetSprite(spriteName); EditorPrefs.SetString("NGUI Selected Sprite", spriteName); Repaint(); }
/// <summary> /// Create a UIAtlas on runtime from a list of Texture2Ds /// </summary> public static UIAtlas CreateAtlas(string atlasName, GameObject parent, List<Texture2D> textures, List<string> names) { Logger.Debug(TAG, "Generating UIAtlas: {0}", atlasName); // Pack textures int maxSize = SystemInfo.maxTextureSize; Texture2D atlasTexture = new Texture2D(maxSize, maxSize); Rect[] rects = atlasTexture.PackTextures(textures.ToArray(), 0, maxSize); // Create new empty GameObject with UIAtlas component UIAtlas atlas = NGUITools.AddChild<UIAtlas>(parent); atlas.name = atlasName; // Set material atlas.coordinates = UIAtlas.Coordinates.TexCoords; atlas.spriteMaterial = new Material(Shader.Find("Unlit/Transparent Colored")); atlas.spriteMaterial.mainTexture = atlasTexture; // Add sprites for (int i = 0; i < rects.Length; i++) { UIAtlas.Sprite sprite = new UIAtlas.Sprite(); sprite.inner = rects[i]; sprite.outer = rects[i]; sprite.name = names[i]; atlas.spriteList.Add(sprite); } // Return reference to the UIAtlas script return atlas; }
/// <summary> /// Draw the inspector widget. /// </summary> public override void OnInspectorGUI() { EditorGUIUtility.LookLikeControls(80f); mAtlas = target as UIAtlas; NGUIEditorTools.DrawSeparator(); if (mAtlas.replacement != null) { mType = AtlasType.Reference; mReplacement = mAtlas.replacement as UIAtlas; } 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 <UIAtlas>(mAtlas.replacement as UIAtlas, OnSelectAtlas); NGUIEditorTools.DrawSeparator(); GUILayout.Label("You can have one atlas simply point to\n" + "another one. This is useful if you want to be\n" + "able to quickly replace the contents of one\n" + "atlas with another one, for example for\n" + "swapping an SD atlas with an HD one, or\n" + "replacing an English atlas with a Chinese\n" + "one. All the sprites referencing this atlas\n" + "will update their references to the new one."); 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(); } UIAtlas.Coordinates coords = (UIAtlas.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); 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]; } } GUI.backgroundColor = Color.green; GUILayout.BeginHorizontal(); { EditorGUILayout.PrefixLabel("Add/Delete"); if (GUILayout.Button("New Sprite")) { NGUIEditorTools.RegisterUndo("Add Sprite", mAtlas); UIAtlas.Sprite newSprite = new UIAtlas.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 (!mConfirmDelete && mSprite != null) { NGUIEditorTools.DrawSeparator(); string spriteName = UISpriteInspector.SpriteField(mAtlas, mSprite.name); if (spriteName != mSprite.name) { mSprite = mAtlas.GetSprite(spriteName); EditorPrefs.SetString("NGUI Selected Sprite", spriteName); } if (mSprite == null) { return; } Texture2D tex = mAtlas.spriteMaterial.mainTexture as Texture2D; if (tex != null) { Rect inner = mSprite.inner; Rect outer = mSprite.outer; string name = EditorGUILayout.TextField("Edit Name", mSprite.name); if (mSprite.name != name && !string.IsNullOrEmpty(name)) { bool found = false; foreach (UIAtlas.Sprite sp in mAtlas.spriteList) { if (sp.name == name) { found = true; break; } } if (!found) { NGUIEditorTools.RegisterUndo("Edit Sprite Name", mAtlas); mSprite.name = name; } } if (mAtlas.coordinates == UIAtlas.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); EditorGUILayout.Separator(); // Padding is mainly meant to be used by the 'trimmed' feature of TexturePacker if (mAtlas.coordinates == UIAtlas.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 (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.width; mSprite.paddingRight = b.x / mSprite.outer.height; 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 == UIAtlas.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(); } GUILayout.BeginHorizontal(); { mView = (View)EditorGUILayout.EnumPopup("Show", mView); GUILayout.Label("Shader", GUILayout.Width(45f)); if (mUseShader != EditorGUILayout.Toggle(mUseShader, GUILayout.Width(20f))) { mUseShader = !mUseShader; if (mUseShader && mView == View.Sprite) { // TODO: Remove this when Unity fixes the bug with DrawPreviewTexture not being affected by BeginGroup Debug.LogWarning("There is a bug in Unity that prevents the texture from getting clipped properly.\n" + "Until it's fixed by Unity, your texture may spill onto the rest of the Unity's GUI while using this mode."); } } } GUILayout.EndHorizontal(); if (mSprite.outer != outer || mSprite.inner != inner) { NGUIEditorTools.RegisterUndo("Atlas Change", mAtlas); mSprite.outer = outer; mSprite.inner = inner; mConfirmDelete = false; MarkSpriteAsDirty(); } Rect uv0 = outer; Rect uv1 = inner; if (mAtlas.coordinates == UIAtlas.Coordinates.Pixels) { uv0 = NGUIMath.ConvertToTexCoords(uv0, tex.width, tex.height); uv1 = NGUIMath.ConvertToTexCoords(uv1, tex.width, tex.height); } // Draw the atlas EditorGUILayout.Separator(); Material m = mUseShader ? mAtlas.spriteMaterial : null; Rect rect = (mView == View.Atlas) ? NGUIEditorTools.DrawAtlas(tex, m) : NGUIEditorTools.DrawSprite(tex, uv0, m); // Draw the sprite outline NGUIEditorTools.DrawOutline(rect, uv0, uv1); EditorGUILayout.Separator(); } } } } }
private void OnClick() { if (mChild == null && atlas != null && font != null && items.Count > 0) { mLabelList.Clear(); handleEvents = true; if (mPanel == null) { mPanel = UIPanel.Find(base.transform, createIfMissing: true); } Transform transform = base.transform; Bounds bounds = NGUIMath.CalculateRelativeWidgetBounds(transform.parent, transform); mChild = new GameObject("Drop-down List"); mChild.layer = base.gameObject.layer; Transform transform2 = mChild.transform; transform2.parent = transform.parent; transform2.localPosition = bounds.min; transform2.localRotation = Quaternion.identity; transform2.localScale = Vector3.one; mBackground = NGUITools.AddSprite(mChild, atlas, backgroundSprite); mBackground.pivot = UIWidget.Pivot.TopLeft; mBackground.depth = NGUITools.CalculateNextDepth(mPanel.gameObject); mBackground.color = backgroundColor; Vector4 border = mBackground.border; mBgBorder = border.y; mBackground.cachedTransform.localPosition = new Vector3(0f, border.y, 0f); mHighlight = NGUITools.AddSprite(mChild, atlas, highlightSprite); mHighlight.pivot = UIWidget.Pivot.TopLeft; mHighlight.color = highlightColor; UIAtlas.Sprite atlasSprite = mHighlight.GetAtlasSprite(); if (atlasSprite == null) { return; } float num = atlasSprite.inner.yMin - atlasSprite.outer.yMin; float num2 = (float)font.size * font.pixelSize * textScale; float num3 = 0f; float num4 = 0f - padding.y; List <UILabel> list = new List <UILabel>(); int i = 0; for (int count = items.Count; i < count; i++) { string text = items[i]; UILabel uILabel = NGUITools.AddWidget <UILabel>(mChild); uILabel.pivot = UIWidget.Pivot.TopLeft; uILabel.font = font; uILabel.text = ((!isLocalized || !(Localization.instance != null)) ? text : Localization.instance.Get(text)); uILabel.color = textColor; uILabel.cachedTransform.localPosition = new Vector3(border.x + padding.x, num4, -1f); uILabel.MakePixelPerfect(); if (textScale != 1f) { Vector3 localScale = uILabel.cachedTransform.localScale; uILabel.cachedTransform.localScale = localScale * textScale; } list.Add(uILabel); num4 -= num2; num4 -= padding.y; float a = num3; Vector2 relativeSize = uILabel.relativeSize; num3 = Mathf.Max(a, relativeSize.x * num2); UIEventListener uIEventListener = UIEventListener.Get(uILabel.gameObject); uIEventListener.onHover = OnItemHover; uIEventListener.onPress = OnItemPress; uIEventListener.parameter = text; if (mSelectedItem == text) { Highlight(uILabel, instant: true); } mLabelList.Add(uILabel); } float a2 = num3; Vector3 size = bounds.size; num3 = Mathf.Max(a2, size.x - (border.x + padding.x) * 2f); Vector3 center = new Vector3(num3 * 0.5f / num2, -0.5f, 0f); Vector3 size2 = new Vector3(num3 / num2, (num2 + padding.y) / num2, 1f); int j = 0; for (int count2 = list.Count; j < count2; j++) { UILabel uILabel2 = list[j]; BoxCollider boxCollider = NGUITools.AddWidgetCollider(uILabel2.gameObject); Vector3 center2 = boxCollider.center; center.z = center2.z; boxCollider.center = center; boxCollider.size = size2; } num3 += (border.x + padding.x) * 2f; num4 -= border.y; mBackground.cachedTransform.localScale = new Vector3(num3, 0f - num4 + border.y, 1f); mHighlight.cachedTransform.localScale = new Vector3(num3 - (border.x + padding.x) * 2f + (atlasSprite.inner.xMin - atlasSprite.outer.xMin) * 2f, num2 + num * 2f, 1f); bool flag = position == Position.Above; if (position == Position.Auto) { UICamera uICamera = UICamera.FindCameraForLayer(base.gameObject.layer); if (uICamera != null) { Vector3 vector = uICamera.cachedCamera.WorldToViewportPoint(transform.position); flag = (vector.y < 0.5f); } } if (isAnimated) { float bottom = num4 + num2; Animate(mHighlight, flag, bottom); int k = 0; for (int count3 = list.Count; k < count3; k++) { Animate(list[k], flag, bottom); } AnimateColor(mBackground); AnimateScale(mBackground, flag, bottom); } if (flag) { Vector3 min = bounds.min; float x = min.x; Vector3 max = bounds.max; float y = max.y - num4 - border.y; Vector3 min2 = bounds.min; transform2.localPosition = new Vector3(x, y, min2.z); } } else { OnSelect(isSelected: false); } }
/// <summary> /// Draw the inspector widget. /// </summary> public override void OnInspectorGUI() { EditorGUIUtility.LookLikeControls(80f); InvDatabase db = target as InvDatabase; NGUIEditorTools.DrawSeparator(); InvBaseItem item = null; if (db.items == null || db.items.Count == 0) { mIndex = 0; } else { mIndex = Mathf.Clamp(mIndex, 0, db.items.Count - 1); item = db.items[mIndex]; } if (mConfirmDelete) { // Show the confirmation dialog GUILayout.Label("Are you sure you want to delete '" + item.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 Inventory Item", db); db.items.RemoveAt(mIndex); mConfirmDelete = false; } GUI.backgroundColor = Color.white; } GUILayout.EndHorizontal(); } else { // Database icon atlas UIAtlas atlas = EditorGUILayout.ObjectField("Icon Atlas", db.iconAtlas, typeof(UIAtlas), false) as UIAtlas; if (atlas != db.iconAtlas) { NGUIEditorTools.RegisterUndo("Databse Atlas change", db); db.iconAtlas = atlas; foreach (InvBaseItem i in db.items) { i.iconAtlas = atlas; } } // Database ID int dbID = EditorGUILayout.IntField("Database ID", db.databaseID); if (dbID != db.databaseID) { NGUIEditorTools.RegisterUndo("Database ID change", db); db.databaseID = dbID; } // "New" button GUI.backgroundColor = Color.green; if (GUILayout.Button("New Item")) { NGUIEditorTools.RegisterUndo("Add Inventory Item", db); InvBaseItem bi = new InvBaseItem(); bi.iconAtlas = db.iconAtlas; bi.id16 = (db.items.Count > 0) ? db.items[db.items.Count - 1].id16 + 1 : 0; db.items.Add(bi); mIndex = db.items.Count - 1; if (item != null) { bi.name = "Copy of " + item.name; bi.description = item.description; bi.slot = item.slot; bi.color = item.color; bi.iconName = item.iconName; bi.attachment = item.attachment; bi.minItemLevel = item.minItemLevel; bi.maxItemLevel = item.maxItemLevel; foreach (InvStat stat in item.stats) { InvStat copy = new InvStat(); copy.id = stat.id; copy.amount = stat.amount; copy.modifier = stat.modifier; bi.stats.Add(copy); } } else { bi.name = "New Item"; bi.description = "Item Description"; } item = bi; } GUI.backgroundColor = Color.white; if (item != null) { NGUIEditorTools.DrawSeparator(); // Navigation section GUILayout.BeginHorizontal(); { if (mIndex == 0) { GUI.color = Color.grey; } if (GUILayout.Button("<<")) { mConfirmDelete = false; --mIndex; } GUI.color = Color.white; mIndex = EditorGUILayout.IntField(mIndex + 1, GUILayout.Width(40f)) - 1; GUILayout.Label("/ " + db.items.Count, GUILayout.Width(40f)); if (mIndex + 1 == db.items.Count) { GUI.color = Color.grey; } if (GUILayout.Button(">>")) { mConfirmDelete = false; ++mIndex; } GUI.color = Color.white; } GUILayout.EndHorizontal(); NGUIEditorTools.DrawSeparator(); // Item name and delete item button GUILayout.BeginHorizontal(); { string itemName = EditorGUILayout.TextField("Item Name", item.name); GUI.backgroundColor = Color.red; if (GUILayout.Button("Delete", GUILayout.Width(55f))) { mConfirmDelete = true; } GUI.backgroundColor = Color.white; if (!itemName.Equals(item.name)) { NGUIEditorTools.RegisterUndo("Rename Item", db); item.name = itemName; } } GUILayout.EndHorizontal(); string itemDesc = GUILayout.TextArea(item.description, 200, GUILayout.Height(100f)); InvBaseItem.Slot slot = (InvBaseItem.Slot)EditorGUILayout.EnumPopup("Slot", item.slot); string iconName = ""; float iconSize = 64f; bool drawIcon = false; float extraSpace = 0f; if (item.iconAtlas != null) { BetterList <string> sprites = item.iconAtlas.GetListOfSprites(); sprites.Insert(0, "<None>"); int index = 0; string spriteName = (item.iconName != null) ? item.iconName : sprites[0]; // We need to find the sprite in order to have it selected if (!string.IsNullOrEmpty(spriteName)) { for (int i = 1; i < sprites.size; ++i) { if (spriteName.Equals(sprites[i], System.StringComparison.OrdinalIgnoreCase)) { index = i; break; } } } // Draw the sprite selection popup index = EditorGUILayout.Popup("Icon", index, sprites.ToArray()); UIAtlas.Sprite sprite = (index > 0) ? item.iconAtlas.GetSprite(sprites[index]) : null; if (sprite != null) { iconName = sprite.name; Material mat = item.iconAtlas.spriteMaterial; if (mat != null) { Texture2D tex = mat.mainTexture as Texture2D; if (tex != null) { drawIcon = true; Rect rect = sprite.outer; if (item.iconAtlas.coordinates == UIAtlas.Coordinates.Pixels) { rect = NGUIMath.ConvertToTexCoords(rect, tex.width, tex.height); } GUILayout.Space(4f); GUILayout.BeginHorizontal(); { GUILayout.Space(Screen.width - iconSize); DrawSprite(tex, rect, null, false); } GUILayout.EndHorizontal(); extraSpace = iconSize * (float)sprite.outer.height / sprite.outer.width; } } } } // Item level range GUILayout.BeginHorizontal(); GUILayout.Label("Level Range", GUILayout.Width(77f)); int min = EditorGUILayout.IntField(item.minItemLevel, GUILayout.MinWidth(40f)); int max = EditorGUILayout.IntField(item.maxItemLevel, GUILayout.MinWidth(40f)); if (drawIcon) { GUILayout.Space(iconSize); } GUILayout.EndHorizontal(); // Game Object attachment field, left of the icon GUILayout.BeginHorizontal(); GameObject go = (GameObject)EditorGUILayout.ObjectField("Attachment", item.attachment, typeof(GameObject), false); if (drawIcon) { GUILayout.Space(iconSize); } GUILayout.EndHorizontal(); // Color tint field, left of the icon GUILayout.BeginHorizontal(); Color color = EditorGUILayout.ColorField("Color", item.color); if (drawIcon) { GUILayout.Space(iconSize); } GUILayout.EndHorizontal(); // Calculate the extra spacing necessary for the icon to show up properly and not overlap anything if (drawIcon) { extraSpace = Mathf.Max(0f, extraSpace - 60f); GUILayout.Space(extraSpace); } // Item stats NGUIEditorTools.DrawSeparator(); if (item.stats != null) { for (int i = 0; i < item.stats.Count; ++i) { InvStat stat = item.stats[i]; GUILayout.BeginHorizontal(); { InvStat.Identifier iden = (InvStat.Identifier)EditorGUILayout.EnumPopup(stat.id, GUILayout.Width(80f)); // Color the field red if it's negative, green if it's positive if (stat.amount > 0) { GUI.backgroundColor = Color.green; } else if (stat.amount < 0) { GUI.backgroundColor = Color.red; } int amount = EditorGUILayout.IntField(stat.amount, GUILayout.Width(40f)); GUI.backgroundColor = Color.white; InvStat.Modifier mod = (InvStat.Modifier)EditorGUILayout.EnumPopup(stat.modifier); GUI.backgroundColor = Color.red; if (GUILayout.Button("X", GUILayout.Width(20f))) { NGUIEditorTools.RegisterUndo("Delete Item Stat", db); item.stats.RemoveAt(i); --i; } else if (iden != stat.id || amount != stat.amount || mod != stat.modifier) { NGUIEditorTools.RegisterUndo("Item Stats", db); stat.id = iden; stat.amount = amount; stat.modifier = mod; } GUI.backgroundColor = Color.white; } GUILayout.EndHorizontal(); } } if (GUILayout.Button("Add Stat", GUILayout.Width(80f))) { NGUIEditorTools.RegisterUndo("Add Item Stat", db); InvStat stat = new InvStat(); stat.id = InvStat.Identifier.Armor; item.stats.Add(stat); } // Save all values if (!itemDesc.Equals(item.description) || slot != item.slot || go != item.attachment || color != item.color || min != item.minItemLevel || max != item.maxItemLevel || !iconName.Equals(item.iconName)) { NGUIEditorTools.RegisterUndo("Item Properties", db); item.description = itemDesc; item.slot = slot; item.attachment = go; item.color = color; item.iconName = iconName; item.minItemLevel = min; item.maxItemLevel = max; } } } }
/// <summary> /// Display the drop-down list when the game object gets clicked on. /// </summary> void OnClick() { if (enabled && NGUITools.GetActive(gameObject) && mChild == null && atlas != null && font != null && items.Count > 0) { mLabelList.Clear(); // Disable the navigation script handleEvents = true; // Automatically locate the panel responsible for this object if (mPanel == null) { mPanel = UIPanel.Find(transform, true); } // Calculate the dimensions of the object triggering the popup list so we can position it below it Transform myTrans = transform; Bounds bounds = NGUIMath.CalculateRelativeWidgetBounds(myTrans.parent, myTrans); // Create the root object for the list mChild = new GameObject("Drop-down List"); mChild.layer = gameObject.layer; Transform t = mChild.transform; t.parent = myTrans.parent; t.localPosition = bounds.min; t.localRotation = Quaternion.identity; t.localScale = Vector3.one; // Add a sprite for the background mBackground = NGUITools.AddSprite(mChild, atlas, backgroundSprite); mBackground.pivot = UIWidget.Pivot.TopLeft; mBackground.depth = NGUITools.CalculateNextDepth(mPanel.gameObject); mBackground.color = backgroundColor; // We need to know the size of the background sprite for padding purposes Vector4 bgPadding = mBackground.border; mBgBorder = bgPadding.y; mBackground.cachedTransform.localPosition = new Vector3(0f, bgPadding.y, 0f); // Add a sprite used for the selection mHighlight = NGUITools.AddSprite(mChild, atlas, highlightSprite); mHighlight.pivot = UIWidget.Pivot.TopLeft; mHighlight.color = highlightColor; UIAtlas.Sprite hlsp = mHighlight.GetAtlasSprite(); if (hlsp == null) { return; } float hlspHeight = hlsp.inner.yMin - hlsp.outer.yMin; float fontScale = font.size * font.pixelSize * textScale; float x = 0f, y = -padding.y; List <UILabel> labels = new List <UILabel>(); // Run through all items and create labels for each one for (int i = 0, imax = items.Count; i < imax; ++i) { string s = items[i]; UILabel lbl = NGUITools.AddWidget <UILabel>(mChild); lbl.pivot = UIWidget.Pivot.TopLeft; lbl.font = font; lbl.text = (isLocalized && Localization.instance != null) ? Localization.instance.Get(s) : s; lbl.color = textColor; lbl.cachedTransform.localPosition = new Vector3(bgPadding.x + padding.x, y, -1f); lbl.MakePixelPerfect(); if (textScale != 1f) { Vector3 scale = lbl.cachedTransform.localScale; lbl.cachedTransform.localScale = scale * textScale; } labels.Add(lbl); y -= fontScale; y -= padding.y; x = Mathf.Max(x, lbl.relativeSize.x * fontScale); // Add an event listener UIEventListener listener = UIEventListener.Get(lbl.gameObject); listener.onHover = OnItemHover; listener.onPress = OnItemPress; listener.parameter = s; // Move the selection here if this is the right label if (mSelectedItem == s) { Highlight(lbl, true); } // Add this label to the list mLabelList.Add(lbl); } // The triggering widget's width should be the minimum allowed width x = Mathf.Max(x, bounds.size.x - (bgPadding.x + padding.x) * 2f); Vector3 bcCenter = new Vector3((x * 0.5f) / fontScale, -0.5f, 0f); Vector3 bcSize = new Vector3(x / fontScale, (fontScale + padding.y) / fontScale, 1f); // Run through all labels and add colliders for (int i = 0, imax = labels.Count; i < imax; ++i) { UILabel lbl = labels[i]; BoxCollider bc = NGUITools.AddWidgetCollider(lbl.gameObject); bcCenter.z = bc.center.z; bc.center = bcCenter; bc.size = bcSize; } x += (bgPadding.x + padding.x) * 2f; y -= bgPadding.y; // Scale the background sprite to envelop the entire set of items mBackground.cachedTransform.localScale = new Vector3(x, -y + bgPadding.y, 1f); // Scale the highlight sprite to envelop a single item float scaleFactor = 2f * atlas.pixelSize; mHighlight.cachedTransform.localScale = new Vector3( x - (bgPadding.x + padding.x) * 2f + (hlsp.inner.xMin - hlsp.outer.xMin) * scaleFactor, fontScale + hlspHeight * scaleFactor, 1f); bool placeAbove = (position == Position.Above); if (position == Position.Auto) { UICamera cam = UICamera.FindCameraForLayer(gameObject.layer); if (cam != null) { Vector3 viewPos = cam.cachedCamera.WorldToViewportPoint(myTrans.position); placeAbove = (viewPos.y < 0.5f); } } // If the list should be animated, let's animate it by expanding it if (isAnimated) { float bottom = y + fontScale; Animate(mHighlight, placeAbove, bottom); for (int i = 0, imax = labels.Count; i < imax; ++i) { Animate(labels[i], placeAbove, bottom); } AnimateColor(mBackground); AnimateScale(mBackground, placeAbove, bottom); } // If we need to place the popup list above the item, we need to reposition everything by the size of the list if (placeAbove) { t.localPosition = new Vector3(bounds.min.x, bounds.max.y - y - bgPadding.y, bounds.min.z); } } else { OnSelect(false); } }
/// <summary> /// Draw the custom wizard. /// </summary> void OnGUI() { EditorGUIUtility.LookLikeControls(80f); if (mAtlas == null) { GUILayout.Label("No Atlas selected.", "LODLevelNotifyText"); } else { bool close = false; GUILayout.Label(mAtlas.name + " Sprites", "LODLevelNotifyText"); NGUIEditorTools.DrawSeparator(); GUILayout.BeginHorizontal(); GUILayout.Space(84f); string before = NGUISettings.partialSprite; string after = EditorGUILayout.TextField("", before, "SearchTextField"); NGUISettings.partialSprite = after; if (GUILayout.Button("", "SearchCancelButton", GUILayout.Width(18f))) { NGUISettings.partialSprite = ""; GUIUtility.keyboardControl = 0; } GUILayout.Space(84f); GUILayout.EndHorizontal(); Texture2D tex = mAtlas.texture as Texture2D; if (tex == null) { GUILayout.Label("The atlas doesn't have a texture to work with"); return; } BetterList <string> sprites = mAtlas.GetListOfSprites(NGUISettings.partialSprite); float size = 80f; float padded = size + 10f; int columns = Mathf.FloorToInt(Screen.width / padded); if (columns < 1) { columns = 1; } int offset = 0; Rect rect = new Rect(10f, 0, size, size); GUILayout.Space(10f); mPos = GUILayout.BeginScrollView(mPos); while (offset < sprites.size) { GUILayout.BeginHorizontal(); { int col = 0; rect.x = 10f; for (; offset < sprites.size; ++offset) { UIAtlas.Sprite sprite = mAtlas.GetSprite(sprites[offset]); if (sprite == null) { continue; } // Button comes first if (GUI.Button(rect, "")) { float delta = Time.realtimeSinceStartup - mClickTime; mClickTime = Time.realtimeSinceStartup; if (spriteName != sprite.name) { if (mSprite != null) { NGUIEditorTools.RegisterUndo("Atlas Selection", mSprite); mSprite.spriteName = sprite.name; mSprite.MakePixelPerfect(); EditorUtility.SetDirty(mSprite.gameObject); } else if (mCallback != null) { mName = sprite.name; mCallback(sprite.name); } } else if (delta < 0.5f) { close = true; } } if (Event.current.type == EventType.Repaint) { // On top of the button we have a checkboard grid NGUIEditorTools.DrawTiledTexture(rect, NGUIEditorTools.backdropTexture); Rect uv = sprite.outer; if (mAtlas.coordinates == UIAtlas.Coordinates.Pixels) { uv = NGUIMath.ConvertToTexCoords(uv, tex.width, tex.height); } // Calculate the texture's scale that's needed to display the sprite in the clipped area float scaleX = rect.width / uv.width; float scaleY = rect.height / uv.height; // Stretch the sprite so that it will appear proper float aspect = (scaleY / scaleX) / ((float)tex.height / tex.width); Rect clipRect = rect; if (aspect != 1f) { if (aspect < 1f) { // The sprite is taller than it is wider float padding = size * (1f - aspect) * 0.5f; clipRect.xMin += padding; clipRect.xMax -= padding; } else { // The sprite is wider than it is taller float padding = size * (1f - 1f / aspect) * 0.5f; clipRect.yMin += padding; clipRect.yMax -= padding; } } GUI.DrawTextureWithTexCoords(clipRect, tex, uv); // Draw the selection if (spriteName == sprite.name) { NGUIEditorTools.DrawOutline(rect, new Color(0.4f, 1f, 0f, 1f)); } } if (++col >= columns) { ++offset; break; } rect.x += padded; } } GUILayout.EndHorizontal(); GUILayout.Space(padded); rect.y += padded; } GUILayout.EndScrollView(); if (close) { Close(); } } }
/// <summary> /// Parse the specified JSon file, loading sprite information for the specified atlas. /// </summary> public static void LoadSpriteData(UIAtlas atlas, TextAsset asset) { if (asset == null || atlas == null) { return; } string jsonString = asset.text; Hashtable decodedHash = jsonDecode(jsonString) as Hashtable; if (decodedHash == null) { Debug.LogWarning("Unable to parse Json file: " + asset.name); return; } atlas.coordinates = UIAtlas.Coordinates.Pixels; List <UIAtlas.Sprite> oldSprites = atlas.spriteList; atlas.spriteList = new List <UIAtlas.Sprite>(); Hashtable frames = (Hashtable)decodedHash["frames"]; foreach (System.Collections.DictionaryEntry item in frames) { UIAtlas.Sprite newSprite = new UIAtlas.Sprite(); newSprite.name = item.Key.ToString(); bool exists = false; // Check to see if this sprite exists foreach (UIAtlas.Sprite oldSprite in oldSprites) { if (oldSprite.name.Equals(newSprite.name, StringComparison.OrdinalIgnoreCase)) { exists = true; break; } } // Get rid of the extension if the sprite doesn't exist // The extension is kept for backwards compatibility so it's still possible to update older atlases. if (!exists) { newSprite.name = newSprite.name.Replace(".png", ""); newSprite.name = newSprite.name.Replace(".tga", ""); } // Extract the info we need from the TexturePacker json file, mainly uvRect and size Hashtable table = (Hashtable)item.Value; Hashtable frame = (Hashtable)table["frame"]; int frameX = int.Parse(frame["x"].ToString()); int frameY = int.Parse(frame["y"].ToString()); int frameW = int.Parse(frame["w"].ToString()); int frameH = int.Parse(frame["h"].ToString()); // Read the rotation value newSprite.rotated = (bool)table["rotated"]; // Fill in the proper values if (newSprite.rotated) { newSprite.outer = new Rect(frameX, frameY, frameH, frameW); newSprite.inner = new Rect(frameX, frameY, frameH, frameW); } else { newSprite.outer = new Rect(frameX, frameY, frameW, frameH); newSprite.inner = new Rect(frameX, frameY, frameW, frameH); } // Support for trimmed sprites Hashtable sourceSize = (Hashtable)table["sourceSize"]; Hashtable spriteSize = (Hashtable)table["spriteSourceSize"]; if (spriteSize != null && sourceSize != null) { // TODO: Account for rotated sprites if (frameW > 0) { float spriteX = int.Parse(spriteSize["x"].ToString()); float spriteW = int.Parse(spriteSize["w"].ToString()); float sourceW = int.Parse(sourceSize["w"].ToString()); newSprite.paddingLeft = spriteX / frameW; newSprite.paddingRight = (sourceW - (spriteX + spriteW)) / frameW; } if (frameH > 0) { float spriteY = int.Parse(spriteSize["y"].ToString()); float spriteH = int.Parse(spriteSize["h"].ToString()); float sourceH = int.Parse(sourceSize["h"].ToString()); newSprite.paddingTop = spriteY / frameH; newSprite.paddingBottom = (sourceH - (spriteY + spriteH)) / frameH; } } // If the sprite was present before, see if we can copy its inner rect foreach (UIAtlas.Sprite oldSprite in oldSprites) { if (oldSprite.name.Equals(newSprite.name, StringComparison.OrdinalIgnoreCase)) { CopyInnerRect(oldSprite, newSprite); } } // Add this new sprite atlas.spriteList.Add(newSprite); } // Sort imported sprites alphabetically atlas.spriteList.Sort(CompareSprites); Debug.Log("Imported " + atlas.spriteList.Count + " sprites"); // Unload the asset asset = null; Resources.UnloadUnusedAssets(); }
/// <summary> /// Draw the inspector widget. /// </summary> public override void OnInspectorGUI() { EditorGUIUtility.LookLikeControls(80f); mAtlas = target as UIAtlas; 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 <UIAtlas>(mAtlas.replacement, OnSelectAtlas); NGUIEditorTools.DrawSeparator(); GUILayout.Label("You can have one atlas simply point to\n" + "another one. This is useful if you want to be\n" + "able to quickly replace the contents of one\n" + "atlas with another one, for example for\n" + "swapping an SD atlas with an HD one, or\n" + "replacing an English atlas with a Chinese\n" + "one. All the sprites referencing this atlas\n" + "will update their references to the new one."); 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(); } UIAtlas.Coordinates coords = (UIAtlas.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 == UIAtlas.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 == UIAtlas.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.width; mSprite.paddingRight = b.x / mSprite.outer.height; 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 == UIAtlas.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(); } } NGUIEditorTools.DrawSeparator(); GUILayout.BeginHorizontal(); { EditorGUILayout.PrefixLabel("Add/Delete"); if (GUILayout.Button("Clone Sprite")) { NGUIEditorTools.RegisterUndo("Add Sprite", mAtlas); UIAtlas.Sprite newSprite = new UIAtlas.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> /// Validate this symbol, given the specified atlas. /// </summary> public bool Validate(UIAtlas atlas) { if (atlas == null) return false; #if UNITY_EDITOR if (!Application.isPlaying || mSprite == null) #else if (mSprite == null) #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 inner = mSprite.inner; Rect outer = mSprite.outer; mUV = outer; if (atlas.coordinates == UIAtlas.Coordinates.Pixels) { mUV = NGUIMath.ConvertToTexCoords(mUV, tex.width, tex.height); } else { inner = NGUIMath.ConvertToPixels(inner, tex.width, tex.height, true); outer = NGUIMath.ConvertToPixels(outer, tex.width, tex.height, true); } mOffsetX = Mathf.RoundToInt(outer.x - inner.x); mOffsetY = Mathf.RoundToInt(outer.y - inner.y); mOuterWidth = Mathf.RoundToInt(outer.width); mOuterHeight = Mathf.RoundToInt(outer.height); mInnerWidth = Mathf.RoundToInt(inner.width); } } } return (mSprite != null); }
/// <summary> /// Parse the specified JSon file, loading sprite information for the specified atlas. /// </summary> public static void LoadSpriteData (UIAtlas atlas, TextAsset asset) { if (asset == null || atlas == null) return; string jsonString = asset.text; Hashtable decodedHash = jsonDecode(jsonString) as Hashtable; if (decodedHash == null) { Debug.LogWarning("Unable to parse Json file: " + asset.name); return; } atlas.coordinates = UIAtlas.Coordinates.Pixels; List<UIAtlas.Sprite> oldSprites = atlas.spriteList; atlas.spriteList = new List<UIAtlas.Sprite>(); Hashtable frames = (Hashtable)decodedHash["frames"]; foreach (System.Collections.DictionaryEntry item in frames) { UIAtlas.Sprite newSprite = new UIAtlas.Sprite(); newSprite.name = item.Key.ToString(); bool exists = false; // Check to see if this sprite exists foreach (UIAtlas.Sprite oldSprite in oldSprites) { if (oldSprite.name.Equals(newSprite.name, StringComparison.OrdinalIgnoreCase)) { exists = true; break; } } // Get rid of the extension if the sprite doesn't exist // The extension is kept for backwards compatibility so it's still possible to update older atlases. if (!exists) { newSprite.name = newSprite.name.Replace(".png", ""); newSprite.name = newSprite.name.Replace(".tga", ""); } // Extract the info we need from the TexturePacker json file, mainly uvRect and size Hashtable table = (Hashtable)item.Value; Hashtable frame = (Hashtable)table["frame"]; int frameX = int.Parse(frame["x"].ToString()); int frameY = int.Parse(frame["y"].ToString()); int frameW = int.Parse(frame["w"].ToString()); int frameH = int.Parse(frame["h"].ToString()); // Read the rotation value newSprite.rotated = (bool)table["rotated"]; // Fill in the proper values if (newSprite.rotated) { newSprite.outer = new Rect(frameX, frameY, frameH, frameW); newSprite.inner = new Rect(frameX, frameY, frameH, frameW); } else { newSprite.outer = new Rect(frameX, frameY, frameW, frameH); newSprite.inner = new Rect(frameX, frameY, frameW, frameH); } // Support for trimmed sprites Hashtable sourceSize = (Hashtable)table["sourceSize"]; Hashtable spriteSize = (Hashtable)table["spriteSourceSize"]; if (spriteSize != null && sourceSize != null) { // TODO: Account for rotated sprites if (frameW > 0) { float spriteX = int.Parse(spriteSize["x"].ToString()); float spriteW = int.Parse(spriteSize["w"].ToString()); float sourceW = int.Parse(sourceSize["w"].ToString()); newSprite.paddingLeft = spriteX / frameW; newSprite.paddingRight = (sourceW - (spriteX + spriteW)) / frameW; } if (frameH > 0) { float spriteY = int.Parse(spriteSize["y"].ToString()); float spriteH = int.Parse(spriteSize["h"].ToString()); float sourceH = int.Parse(sourceSize["h"].ToString()); newSprite.paddingTop = spriteY / frameH; newSprite.paddingBottom = (sourceH - (spriteY + spriteH)) / frameH; } } // If the sprite was present before, see if we can copy its inner rect foreach (UIAtlas.Sprite oldSprite in oldSprites) { if (oldSprite.name.Equals(newSprite.name, StringComparison.OrdinalIgnoreCase)) { CopyInnerRect(oldSprite, newSprite); } } // Add this new sprite atlas.spriteList.Add(newSprite); } // Sort imported sprites alphabetically atlas.spriteList.Sort(CompareSprites); Debug.Log("Imported " + atlas.spriteList.Count + " sprites"); // Unload the asset asset = null; Resources.UnloadUnusedAssets(); }
public override bool OnUpdate() { if (this.mLastName == this.mSpriteName) { this.UpdateUVs(false); return false; } this.mSprite = null; base.ChangedAuto(); this.mLastName = this.mSpriteName; this.UpdateUVs(false); return true; }
/// <summary> /// Sprite selection callback. /// </summary> void SelectSprite (string spriteName) { mSprite = mAtlas.GetSprite(spriteName); EditorPrefs.SetString("NGUI Selected Sprite", spriteName); Repaint(); }
/// <summary> /// Progress bar creation function. /// </summary> void CreateSlider(GameObject go, bool slider) { if (NGUISettings.atlas != null) { NGUIEditorTools.SpriteField("Empty", "Sprite for the background (empty bar)", NGUISettings.atlas, mSliderBG, OnSliderBG); NGUIEditorTools.SpriteField("Full", "Sprite for the foreground (full bar)", NGUISettings.atlas, mSliderFG, OnSliderFG); if (slider) { NGUIEditorTools.SpriteField("Thumb", "Sprite for the thumb indicator", NGUISettings.atlas, mSliderTB, OnSliderTB); } } if (ShouldCreate(go, NGUISettings.atlas != null)) { int depth = NGUITools.CalculateNextDepth(go); go = NGUITools.AddChild(go); go.name = slider ? "Slider" : "Progress Bar"; // Background sprite UIAtlas.Sprite bgs = NGUISettings.atlas.GetSprite(mSliderBG); UISprite back = (UISprite)NGUITools.AddWidget <UISprite>(go); back.type = (bgs.inner == bgs.outer) ? UISprite.Type.Simple : UISprite.Type.Sliced; back.name = "Background"; back.depth = depth; back.pivot = UIWidget.Pivot.Left; back.atlas = NGUISettings.atlas; back.spriteName = mSliderBG; back.transform.localScale = new Vector3(200f, 30f, 1f); back.transform.localPosition = Vector3.zero; back.MakePixelPerfect(); // Foreground sprite UIAtlas.Sprite fgs = NGUISettings.atlas.GetSprite(mSliderFG); UISprite front = NGUITools.AddWidget <UISprite>(go); front.type = (fgs.inner == fgs.outer) ? UISprite.Type.Filled : UISprite.Type.Sliced; front.name = "Foreground"; front.pivot = UIWidget.Pivot.Left; front.atlas = NGUISettings.atlas; front.spriteName = mSliderFG; front.transform.localScale = new Vector3(200f, 30f, 1f); front.transform.localPosition = Vector3.zero; front.MakePixelPerfect(); // Add a collider if (slider) { NGUITools.AddWidgetCollider(go); } // Add the slider script UISlider uiSlider = go.AddComponent <UISlider>(); uiSlider.foreground = front.transform; // Thumb sprite if (slider) { UIAtlas.Sprite tbs = NGUISettings.atlas.GetSprite(mSliderTB); UISprite thb = NGUITools.AddWidget <UISprite>(go); thb.type = (tbs.inner == tbs.outer) ? UISprite.Type.Simple : UISprite.Type.Sliced; thb.name = "Thumb"; thb.atlas = NGUISettings.atlas; thb.spriteName = mSliderTB; thb.transform.localPosition = new Vector3(200f, 0f, 0f); thb.transform.localScale = new Vector3(20f, 40f, 1f); thb.MakePixelPerfect(); NGUITools.AddWidgetCollider(thb.gameObject); thb.gameObject.AddComponent <UIButtonColor>(); thb.gameObject.AddComponent <UIButtonScale>(); uiSlider.thumb = thb.transform; } uiSlider.sliderValue = 1f; // Select the slider Selection.activeGameObject = go; } }
/// <summary> /// Button creation function. /// </summary> void CreateImageButton(GameObject go) { if (UISettings.atlas != null) { GUILayout.BeginHorizontal(); string bg = UISpriteInspector.SpriteField(UISettings.atlas, "Normal", mImage0, GUILayout.Width(200f)); GUILayout.Space(20f); GUILayout.Label("Normal state sprite"); GUILayout.EndHorizontal(); if (mImage0 != bg) { mImage0 = bg; Save(); } GUILayout.BeginHorizontal(); bg = UISpriteInspector.SpriteField(UISettings.atlas, "Hover", mImage1, GUILayout.Width(200f)); GUILayout.Space(20f); GUILayout.Label("Hover state sprite"); GUILayout.EndHorizontal(); if (mImage1 != bg) { mImage1 = bg; Save(); } GUILayout.BeginHorizontal(); bg = UISpriteInspector.SpriteField(UISettings.atlas, "Pressed", mImage2, GUILayout.Width(200f)); GUILayout.Space(20f); GUILayout.Label("Pressed state sprite"); GUILayout.EndHorizontal(); if (mImage2 != bg) { mImage2 = bg; Save(); } } if (ShouldCreate(go, UISettings.atlas != null)) { int depth = NGUITools.CalculateNextDepth(go); go = NGUITools.AddChild(go); go.name = "Image Button"; UIAtlas.Sprite sp = UISettings.atlas.GetSprite(mImage0); UISprite sprite = (sp.inner == sp.outer) ? NGUITools.AddWidget <UISprite>(go) : (UISprite)NGUITools.AddWidget <UISlicedSprite>(go); sprite.name = "Background"; sprite.depth = depth; sprite.atlas = UISettings.atlas; sprite.spriteName = mImage0; sprite.transform.localScale = new Vector3(150f, 40f, 1f); sprite.MakePixelPerfect(); if (UISettings.font != null) { UILabel lbl = NGUITools.AddWidget <UILabel>(go); lbl.font = UISettings.font; lbl.text = go.name; lbl.MakePixelPerfect(); } // Add a collider NGUITools.AddWidgetCollider(go); // Add the scripts UIImageButton ib = go.AddComponent <UIImageButton>(); ib.target = sprite; ib.normalSprite = mImage0; ib.hoverSprite = mImage1; ib.pressedSprite = mImage2; go.AddComponent <UIButtonSound>(); Selection.activeGameObject = go; } }
/// <summary> /// Refresh all labels that use this font. /// </summary> public void MarkAsDirty() { mSprite = null; UILabel[] labels = NGUITools.FindActive<UILabel>(); for (int i = 0, imax = labels.Length; i < imax; ++i) { UILabel lbl = labels[i]; if (lbl.enabled && lbl.gameObject.active && CheckIfRelated(this, lbl.font)) { UIFont fnt = lbl.font; lbl.font = null; lbl.font = fnt; } } }
/// <summary> /// Create a popup list or a menu. /// </summary> void CreatePopup(GameObject go, bool isDropDown) { if (NGUISettings.atlas != null) { NGUIEditorTools.SpriteField("Foreground", "Foreground sprite (shown on the button)", NGUISettings.atlas, mListFG, OnListFG); NGUIEditorTools.SpriteField("Background", "Background sprite (envelops the options)", NGUISettings.atlas, mListBG, OnListBG); NGUIEditorTools.SpriteField("Highlight", "Sprite used to highlight the selected option", NGUISettings.atlas, mListHL, OnListHL); } if (ShouldCreate(go, NGUISettings.atlas != null && NGUISettings.font != null)) { int depth = NGUITools.CalculateNextDepth(go); go = NGUITools.AddChild(go); go.name = isDropDown ? "Popup List" : "Popup Menu"; UIAtlas.Sprite sphl = NGUISettings.atlas.GetSprite(mListHL); UIAtlas.Sprite spfg = NGUISettings.atlas.GetSprite(mListFG); Vector2 hlPadding = new Vector2( Mathf.Max(4f, sphl.inner.xMin - sphl.outer.xMin), Mathf.Max(4f, sphl.inner.yMin - sphl.outer.yMin)); Vector2 fgPadding = new Vector2( Mathf.Max(4f, spfg.inner.xMin - spfg.outer.xMin), Mathf.Max(4f, spfg.inner.yMin - spfg.outer.yMin)); // Background sprite UISprite sprite = NGUITools.AddSprite(go, NGUISettings.atlas, mListFG); sprite.depth = depth; sprite.atlas = NGUISettings.atlas; sprite.pivot = UIWidget.Pivot.Left; sprite.transform.localScale = new Vector3(150f + fgPadding.x * 2f, NGUISettings.font.size + fgPadding.y * 2f, 1f); sprite.transform.localPosition = Vector3.zero; sprite.MakePixelPerfect(); // Text label UILabel lbl = NGUITools.AddWidget <UILabel>(go); lbl.font = NGUISettings.font; lbl.text = go.name; lbl.pivot = UIWidget.Pivot.Left; lbl.cachedTransform.localPosition = new Vector3(fgPadding.x, 0f, 0f); lbl.MakePixelPerfect(); // Add a collider NGUITools.AddWidgetCollider(go); // Add the popup list UIPopupList list = go.AddComponent <UIPopupList>(); list.atlas = NGUISettings.atlas; list.font = NGUISettings.font; list.backgroundSprite = mListBG; list.highlightSprite = mListHL; list.padding = hlPadding; if (isDropDown) { list.textLabel = lbl; } for (int i = 0; i < 5; ++i) { list.items.Add(isDropDown ? ("List Option " + i) : ("Menu Option " + i)); } // Add the scripts go.AddComponent <UIButton>().tweenTarget = sprite.gameObject; go.AddComponent <UIButtonSound>(); Selection.activeGameObject = go; } }
/// <summary> /// Draw the inspector widget. /// </summary> public override void OnInspectorGUI () { EditorGUIUtility.LookLikeControls(80f); mAtlas = target as UIAtlas; 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<UIAtlas>(mAtlas.replacement, OnSelectAtlas); NGUIEditorTools.DrawSeparator(); GUILayout.Label("You can have one atlas simply point to\n" + "another one. This is useful if you want to be\n" + "able to quickly replace the contents of one\n" + "atlas with another one, for example for\n" + "swapping an SD atlas with an HD one, or\n" + "replacing an English atlas with a Chinese\n" + "one. All the sprites referencing this atlas\n" + "will update their references to the new one."); 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(); } UIAtlas.Coordinates coords = (UIAtlas.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 == UIAtlas.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 == UIAtlas.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 == UIAtlas.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); UIAtlas.Sprite newSprite = new UIAtlas.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; } } } } }
static UIAtlas.Sprite AddSprite(ICollection<UIAtlas.Sprite> sprites, SpriteEntry se) { UIAtlas.Sprite sprite = sprites.FirstOrDefault(sp => sp.name == se.Tex.name); // See if this sprite already exists if (sprite != null) { float x0 = sprite.inner.xMin - sprite.outer.xMin; float y0 = sprite.inner.yMin - sprite.outer.yMin; float x1 = sprite.outer.xMax - sprite.inner.xMax; float y1 = sprite.outer.yMax - sprite.inner.yMax; sprite.outer = se.Rect; sprite.inner = se.Rect; sprite.inner.xMin = Mathf.Max(sprite.inner.xMin + x0, sprite.outer.xMin); sprite.inner.yMin = Mathf.Max(sprite.inner.yMin + y0, sprite.outer.yMin); sprite.inner.xMax = Mathf.Min(sprite.inner.xMax - x1, sprite.outer.xMax); sprite.inner.yMax = Mathf.Min(sprite.inner.yMax - y1, sprite.outer.yMax); } else { sprite = new UIAtlas.Sprite {name = se.Tex.name, outer = se.Rect, inner = se.Rect}; sprites.Add(sprite); } float width = Mathf.Max(1f, sprite.outer.width); float height = Mathf.Max(1f, sprite.outer.height); // Sprite's padding values are relative to width and height sprite.paddingLeft = se.MinX / width; sprite.paddingRight = se.MaxX / width; sprite.paddingTop = se.MaxY / height; sprite.paddingBottom = se.MinY / height; return sprite; }
/// <summary> /// Update the UV coordinates. /// </summary> override public bool OnUpdate() { if (mChanged || !mSpriteSet) { mSpriteSet = true; mSprite = null; mChanged = true; UpdateUVs(true); return true; } UpdateUVs(false); return false; }
/// <summary> /// Draw the inspector widget. /// </summary> public override void OnInspectorGUI() { mRegisteredUndo = false; EditorGUIUtility.LookLikeControls(80f); mAtlas = target as UIAtlas; if (!mConfirmDelete) { NGUIEditorTools.DrawSeparator(); Material mat = EditorGUILayout.ObjectField("Material", mAtlas.material, typeof(Material), false) as Material; if (mAtlas.material != mat) { RegisterUndo(); mAtlas.material = 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); Undo.RegisterUndo(mAtlas, "Import Sprites"); NGUIJson.LoadSpriteData(mAtlas, ta); mRegisteredUndo = true; if (mSprite != null) mSprite = mAtlas.GetSprite(mSprite.name); mAtlas.MarkAsDirty(); } UIAtlas.Coordinates coords = (UIAtlas.Coordinates)EditorGUILayout.EnumPopup("Coordinates", mAtlas.coordinates); if (coords != mAtlas.coordinates) { RegisterUndo(); mAtlas.coordinates = coords; mConfirmDelete = false; } } } if (mAtlas.material != null) { Color blue = new Color(0f, 0.7f, 1f, 1f); Color green = new Color(0.4f, 1f, 0f, 1f); if (mSprite == null && mAtlas.sprites.Count > 0) { mSprite = mAtlas.sprites[0]; } 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")) { RegisterUndo(); mAtlas.sprites.Remove(mSprite); mConfirmDelete = false; } GUI.backgroundColor = Color.white; } GUILayout.EndHorizontal(); } else mConfirmDelete = false; } else { GUI.backgroundColor = Color.green; GUILayout.BeginHorizontal(); { EditorGUILayout.PrefixLabel("Add/Delete"); if (GUILayout.Button("New Sprite")) { RegisterUndo(); UIAtlas.Sprite newSprite = new UIAtlas.Sprite(); if (mSprite != null) { newSprite.name = "Copy of " + mSprite.name; newSprite.outer = mSprite.outer; newSprite.inner = mSprite.inner; } else { newSprite.name = "New Sprite"; } mAtlas.sprites.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 (!mConfirmDelete && mSprite != null) { NGUIEditorTools.DrawSeparator(); string spriteName = UISpriteInspector.SpriteField(mAtlas, mSprite.name); if (spriteName != mSprite.name) { mSprite = mAtlas.GetSprite(spriteName); } if (mSprite == null) return; // Grab the sprite's inner and outer dimensions Rect inner = mSprite.inner; Rect outer = mSprite.outer; Texture2D tex = mAtlas.material.mainTexture as Texture2D; if (tex != null) { string name = EditorGUILayout.TextField("Edit Name", mSprite.name); if (mSprite.name != name && !string.IsNullOrEmpty(name)) { bool found = false; foreach (UIAtlas.Sprite sp in mAtlas.sprites) { if (sp.name == name) { found = true; break; } } if (!found) { RegisterUndo(); mSprite.name = name; } } // 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); EditorGUILayout.Separator(); // Padding is mainly meant to be used by the 'trimmed' feature of TexturePacker if (mAtlas.coordinates == UIAtlas.Coordinates.Pixels) { int l0 = Mathf.RoundToInt(mSprite.paddingLeft * mSprite.outer.width); int r0 = Mathf.RoundToInt(mSprite.paddingRight * mSprite.outer.width); int t0 = Mathf.RoundToInt(mSprite.paddingTop * mSprite.outer.height); int b0 = Mathf.RoundToInt(mSprite.paddingBottom * mSprite.outer.height); int l1 = l0; int r1 = r0; int t1 = t0; int b1 = b0; GUILayout.BeginHorizontal(); { GUILayout.Label("Padding"); GUILayout.Space(7f); EditorGUIUtility.LookLikeControls(40f); l1 = EditorGUILayout.IntField("Left", l0, GUILayout.MinWidth(40f)); r1 = EditorGUILayout.IntField("Right", r0, GUILayout.MinWidth(40f)); } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); { GUILayout.Space(60f); EditorGUIUtility.LookLikeControls(40f); t1 = EditorGUILayout.IntField("Top", t0, GUILayout.MinWidth(40f)); b1 = EditorGUILayout.IntField("Btm.", b0, GUILayout.MinWidth(40f)); } GUILayout.EndHorizontal(); if (l0 != l1 || r0 != r1 || t0 != t1 || b0 != b1) { RegisterUndo(); mSprite.paddingLeft = l1 / mSprite.outer.width; mSprite.paddingRight = r1 / mSprite.outer.width; mSprite.paddingTop = t1 / mSprite.outer.height; mSprite.paddingBottom = b1 / mSprite.outer.height; MarkSpriteAsDirty(); } EditorGUIUtility.LookLikeControls(80f); } // 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 == UIAtlas.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(); GUILayout.BeginHorizontal(); { mView = (View)EditorGUILayout.EnumPopup("Show", mView); GUILayout.Label("Shader", GUILayout.Width(45f)); if (mUseShader != EditorGUILayout.Toggle(mUseShader, GUILayout.Width(20f))) { mUseShader = !mUseShader; if (mUseShader && mView == View.Sprite) { // TODO: Remove this when Unity fixes the bug with DrawPreviewTexture not being affected by BeginGroup Debug.LogWarning("There is a bug in Unity that prevents the texture from getting clipped properly.\n" + "Until it's fixed by Unity, your texture may spill onto the rest of the Unity's GUI while using this mode."); } } } GUILayout.EndHorizontal(); Rect uv0 = outer; Rect uv1 = inner; if (mAtlas.coordinates == UIAtlas.Coordinates.Pixels) { uv0 = NGUIMath.ConvertToTexCoords(uv0, tex.width, tex.height); uv1 = NGUIMath.ConvertToTexCoords(uv1, tex.width, tex.height); } // Draw the atlas EditorGUILayout.Separator(); Material m = mUseShader ? mAtlas.material : null; Rect rect = (mView == View.Atlas) ? NGUIEditorTools.DrawAtlas(tex, m) : NGUIEditorTools.DrawSprite(tex, uv0, m); // Draw the sprite outline NGUIEditorTools.DrawOutline(rect, uv0, uv1); EditorGUILayout.Separator(); } if (GUI.changed) { RegisterUndo(); mSprite.outer = outer; mSprite.inner = inner; mConfirmDelete = false; } } } } // If something changed, mark the atlas as dirty if (mRegisteredUndo) EditorUtility.SetDirty(mAtlas); }
/// <summary> /// Refresh all labels that use this font. /// </summary> public void MarkAsDirty () { #if UNITY_EDITOR UnityEditor.EditorUtility.SetDirty(gameObject); #endif if (mReplacement != null) mReplacement.MarkAsDirty(); mSprite = null; UILabel[] labels = NGUITools.FindActive<UILabel>(); for (int i = 0, imax = labels.Length; i < imax; ++i) { UILabel lbl = labels[i]; if (lbl.enabled && NGUITools.GetActive(lbl.gameObject) && CheckIfRelated(this, lbl.font)) { UIFont fnt = lbl.font; lbl.font = null; lbl.font = fnt; } } // Clear all symbols for (int i = 0, imax = mSymbols.Count; i < imax; ++i) symbols[i].MarkAsDirty(); }
private void Start() { if (!RPOSInventoryCell._myMaterial) { Bundling.Load<Material>("content/item/mat/ItemIconShader", out RPOSInventoryCell._myMaterial); } this._icon.enabled = false; if ((int)this.modSprites.Length > 0) { this.mod_empty = this.modSprites[0].atlas.GetSprite("slot_empty"); this.mod_full = this.modSprites[0].atlas.GetSprite("slot_full"); } }
/// <summary> /// Update the UV coordinates. /// </summary> public override void Update() { base.Update(); if (mChanged || !mSpriteSet) { mSpriteSet = true; mSprite = null; mChanged = true; UpdateUVs(true); } else UpdateUVs(false); }
/// <summary> /// Mark this symbol as dirty, clearing the sprite reference. /// </summary> public void MarkAsDirty() { mSprite = null; }
/// <summary> /// Update the UV coordinates. /// </summary> override public bool OnUpdate () { if (mLastName != mSpriteName) { mSprite = null; mChanged = true; mLastName = mSpriteName; UpdateUVs(false); return true; } UpdateUVs(false); return false; }
/// <summary> /// Sprite comparison function for sorting. /// </summary> static int CompareSprites(UIAtlas.Sprite a, UIAtlas.Sprite b) { return(a.name.CompareTo(b.name)); }