public bool Validate(UIAtlas atlas) { if (atlas == null) { return false; } if (!this.mIsValid) { if (string.IsNullOrEmpty(this.spriteName)) { return false; } this.mSprite = (atlas == null) ? null : atlas.GetSprite(this.spriteName); if (this.mSprite != null) { Texture texture = atlas.texture; if (texture == null) { this.mSprite = null; } else { this.mUV = new Rect((float) this.mSprite.x, (float) this.mSprite.y, (float) this.mSprite.width, (float) this.mSprite.height); this.mUV = NGUIMath.ConvertToTexCoords(this.mUV, texture.width, texture.height); this.mOffsetX = this.mSprite.paddingLeft; this.mOffsetY = this.mSprite.paddingTop; this.mWidth = this.mSprite.width; this.mHeight = this.mSprite.height; this.mAdvance = this.mSprite.width + (this.mSprite.paddingLeft + this.mSprite.paddingRight); this.mIsValid = true; } } } return (this.mSprite != null); }
public void CopyBorderFrom(UISpriteData sd) { this.borderLeft = sd.borderLeft; this.borderRight = sd.borderRight; this.borderTop = sd.borderTop; this.borderBottom = sd.borderBottom; }
protected void SetAtlasSprite(UISpriteData sprite){ mSpriteSet = true; if (sprite != null) { mSprite = sprite; mSpriteName = mSprite.name; } else { mSpriteName = (mSprite!=null) ? mSprite.name : ""; mSprite = sprite; } }
public void CopyFrom(UISpriteData sd) { this.name = sd.name; this.x = sd.x; this.y = sd.y; this.width = sd.width; this.height = sd.height; this.borderLeft = sd.borderLeft; this.borderRight = sd.borderRight; this.borderTop = sd.borderTop; this.borderBottom = sd.borderBottom; this.paddingLeft = sd.paddingLeft; this.paddingRight = sd.paddingRight; this.paddingTop = sd.paddingTop; this.paddingBottom = sd.paddingBottom; }
void InitAtlas(){ if (null != Atlas) { mSpriteSet = false; mSprite = null; if(string.IsNullOrEmpty(mSpriteName)){ if(Atlas != null && Atlas.spriteList.Count>0){ SetAtlasSprite(Atlas.spriteList[0]); mSpriteName = mSprite.name; } } if(!string.IsNullOrEmpty(mSpriteName)){ string sprite = mSpriteName; mSpriteName = ""; spriteName = sprite; } } }
/// <summary> /// Add a new sprite to the atlas, given the texture it's coming from and the packed rect within the atlas. /// </summary> static UISpriteData AddSprite(List<UISpriteData> sprites, SpriteEntry se) { // See if this sprite already exists foreach (UISpriteData sp in sprites) { if (sp.name == se.name) { sp.CopyFrom(se); return sp; } } UISpriteData sprite = new UISpriteData(); sprite.CopyFrom(se); sprites.Add(sprite); return sprite; }
// Use this for initialization void Start() { Texture2D textrue = AvatarAssetManager.s.getTexture("skin/cloth/1"); Shader shader = Shader.Find("Unlit/Transparent Colored"); Material mat = new Material(shader); mat.mainTexture = textrue; UISpriteData uiSpData = new UISpriteData(); uiSpData.width = textrue.width; uiSpData.height = textrue.height; UIAtlas atlas = gameObject.AddComponent<UIAtlas>(); atlas.spriteMaterial = mat; List<UISpriteData> list = new List<UISpriteData>(); list.Add(uiSpData); atlas.spriteList = list; UISprite sp = gameObject.AddComponent<UISprite>(); sp.atlas = atlas; sp.MakePixelPerfect(); }
/// <summary> /// Copy all values of the specified sprite data. /// </summary> public void CopyFrom (UISpriteData sd) { name = sd.name; x = sd.x; y = sd.y; width = sd.width; height = sd.height; borderLeft = sd.borderLeft; borderRight = sd.borderRight; borderTop = sd.borderTop; borderBottom = sd.borderBottom; paddingLeft = sd.paddingLeft; paddingRight = sd.paddingRight; paddingTop = sd.paddingTop; paddingBottom = sd.paddingBottom; }
public void SetUp() { GameObject go = new GameObject(); atlas = go.AddComponent<UIAtlas>(); sprite = go.AddComponent<UISprite>(); sprite.atlas = atlas; sprite.spriteName = "testSprite"; UISpriteData[] spriteDatas = new UISpriteData[] { new UISpriteData() { name = "available" }, new UISpriteData() { name = "unused" } }; sprite.spriteName = "available"; atlas.spriteList.AddRange(spriteDatas); usages = new AtlasUsages(atlas); }
public UISpriteData GetAltasSprite(){ if (!mSpriteSet) { mSprite = null; } if (mSprite == null && Atlas != null) { if(!string.IsNullOrEmpty(mSpriteName)){ UISpriteData sp = Atlas.GetSprite(mSpriteName); if(sp == null) return null; SetAtlasSprite(sp); } if(mSprite == null && Atlas.spriteList.Count > 0){ UISpriteData sp = Atlas.spriteList[0]; if(sp == null) return null; SetAtlasSprite(sp); if(mSprite == null){ this.PRINT(Atlas.name+"seems to have a null sprite"); return null; } mSpriteName = mSprite.name; } } return mSprite; }
/// <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 { mUV = new Rect(mSprite.x, mSprite.y, mSprite.width, mSprite.height); mUV = NGUIMath.ConvertToTexCoords(mUV, tex.width, tex.height); mOffsetX = mSprite.paddingLeft; mOffsetY = mSprite.paddingTop; mWidth = mSprite.width; mHeight = mSprite.height; mAdvance = mSprite.width + (mSprite.paddingLeft + mSprite.paddingRight); mIsValid = true; } } } return (mSprite != null); }
/// <summary> /// Parse the specified JSon file, loading sprite information for the specified atlas. /// </summary> static void LoadSpriteData (UIAtlas atlas, Hashtable decodedHash) { if (decodedHash == null || atlas == null) return; List<UISpriteData> oldSprites = atlas.spriteList; atlas.spriteList = new List<UISpriteData>(); Hashtable frames = (Hashtable)decodedHash["frames"]; foreach (System.Collections.DictionaryEntry item in frames) { UISpriteData newSprite = new UISpriteData(); newSprite.name = item.Key.ToString(); bool exists = false; // Check to see if this sprite exists foreach (UISpriteData 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"]; newSprite.x = frameX; newSprite.y = frameY; newSprite.width = frameW; newSprite.height = 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) { int spriteX = int.Parse(spriteSize["x"].ToString()); int spriteW = int.Parse(spriteSize["w"].ToString()); int sourceW = int.Parse(sourceSize["w"].ToString()); newSprite.paddingLeft = spriteX; newSprite.paddingRight = sourceW - (spriteX + spriteW); } if (frameH > 0) { int spriteY = int.Parse(spriteSize["y"].ToString()); int spriteH = int.Parse(spriteSize["h"].ToString()); int sourceH = int.Parse(sourceSize["h"].ToString()); newSprite.paddingTop = spriteY; newSprite.paddingBottom = sourceH - (spriteY + spriteH); } } // If the sprite was present before, see if we can copy its inner rect foreach (UISpriteData oldSprite in oldSprites) { if (oldSprite.name.Equals(newSprite.name, StringComparison.OrdinalIgnoreCase)) { newSprite.borderLeft = oldSprite.borderLeft; newSprite.borderRight = oldSprite.borderRight; newSprite.borderBottom = oldSprite.borderBottom; newSprite.borderTop = oldSprite.borderTop; } } // Add this new sprite atlas.spriteList.Add(newSprite); } // Sort imported sprites alphabetically atlas.spriteList.Sort(CompareSprites); Debug.Log("Imported " + atlas.spriteList.Count + " sprites"); }
public UISpriteData borrowSpriteByname(string name, UISprite uisp, object callback, object args) { if (name == null) { return(null); } if (mReplacement != null) { return(mReplacement.borrowSpriteByname(name, uisp, callback, args)); } // Debug.Log ("borrow name==" + name); int i = spriteMap [name] == null ? -1 : (int)spriteMap [name]; if (i < 0) { #if UNITY_EDITOR Debug.LogWarning("can't find sprite ,name=[" + name + "],objname = [" + (uisp != null ? uisp.name : "") + "]"); #endif Coolape.Utl.doCallback(callback, uisp, name, args); return(null); } // Sprite ret = sprites.Count > i ? sprites [i] : null; UISpriteData ret = mSprites.Count > i ? mSprites [i] : null; if (ret == null) { #if UNITY_EDITOR Debug.LogWarning("can't find sprite ,name=[" + name + "]"); #endif Coolape.Utl.doCallback(callback, uisp, name, args); return(ret); } isBorrowSprite = true; int rc = retainCounter [ret.path] == null ? 0 : (int)(retainCounter [ret.path]); if (ret.material == null || ret.material.mainTexture == null || assetBundleMap [ret.path] == null) { // rc = 0; Texture tt = null; try { if (assetBundleMap [ret.path] == null) { #if UNITY_EDITOR if (Application.isPlaying) { getTuxture(ret, uisp, callback, args); isBorrowSprite = false; return(null); } else { string path = ret.path; path = path.Replace("/upgradeRes/", "/upgradeRes4Publish/"); path = path.Replace("/upgradeRes4Publish/", "/upgradeRes4Dev/"); assetBundleMap [ret.path] = Coolape.CLVerManager.self.getAtalsTexture4Edit(path); } #else getTuxture(ret, uisp, callback, args); isBorrowSprite = false; return(null); #endif } if (assetBundleMap [ret.path] == null) { Debug.LogError(ret.path + " is null . name == " + name); isBorrowSprite = false; return(null); } } catch (Exception e) { isBorrowSprite = false; Debug.LogError(e); return(null); } #if UNITY_EDITOR if (Application.isPlaying) { if (assetBundleMap[ret.path] is AssetBundle) { tt = (assetBundleMap[ret.path] as AssetBundle).mainAsset as Texture; } else { getTuxture(ret, uisp, callback, args); isBorrowSprite = false; return(null); } } else { if (assetBundleMap [ret.path].GetType() != typeof(Texture) && assetBundleMap [ret.path].GetType() != typeof(Texture2D)) { assetBundleMap [ret.path] = null; return(null); } tt = (Texture)(assetBundleMap [ret.path]); } #else //tt = (Texture)(assetBundleMap [ret.path]); tt = (assetBundleMap [ret.path] as AssetBundle).mainAsset as Texture; #endif if (tt != null) { if (ret.material == null) { ret.material = getMaterail(tt, ret.path); } else { ret.material.mainTexture = tt; } } else { assetBundleMap [ret.path] = null; #if UNITY_EDITOR Debug.LogWarning("can't find Texture in Resource path :[" + ret.path + "]"); #endif return(null); } } rc++; retainCounter [ret.path] = rc; isBorrowSprite = false; #if UNITY_EDITOR if (Coolape.CLAssetsManager.self != null && !string.IsNullOrEmpty(Coolape.CLAssetsManager.self.debugKey) && ret.path.Contains(Coolape.CLAssetsManager.self.debugKey)) { Debug.LogError("borrow Sprite==" + ret.path + "==" + name + "====" + rc); } #endif Coolape.Utl.doCallback(callback, uisp, ret.name, args); #if UNITY_EDITOR Coolape.Utl.doCallback(onBorrowSpriteCallback, this, ret); #endif return(ret); }
/// <summary> /// Extract the specified sprite from the atlas texture. /// </summary> static SpriteEntry ExtractSprite(UISpriteData es, Texture2D tex, Texture2D alphaTex) { return((tex != null) ? ExtractSprite(es, tex.GetPixels32(), alphaTex != null ? alphaTex.GetPixels32() : null, tex.width, tex.height) : null); }
public void Show() { if (base.enabled && NGUITools.GetActive(base.gameObject) && mChild == null && atlas != null && isValid && items.Count > 0) { mLabelList.Clear(); if (mPanel == null) { mPanel = UIPanel.Find(base.transform); if (mPanel == null) { return; } } handleEvents = 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; UISpriteData atlasSprite = mHighlight.GetAtlasSprite(); if (atlasSprite != null) { float num = (float)atlasSprite.borderTop; float num2 = (float)activeFontSize; float activeFontScale = this.activeFontScale; float num3 = num2 * activeFontScale; float num4 = 0f; float num5 = 0f - padding.y; List <UILabel> list = new List <UILabel>(); if (!items.Contains(mSelectedItem)) { mSelectedItem = null; } int i = 0; for (int count = items.Count; i < count; i++) { string text = items[i]; UILabel uILabel = NGUITools.AddWidget <UILabel>(mChild); uILabel.name = i.ToString(); uILabel.pivot = UIWidget.Pivot.TopLeft; uILabel.bitmapFont = bitmapFont; uILabel.trueTypeFont = trueTypeFont; uILabel.fontSize = fontSize; uILabel.fontStyle = fontStyle; uILabel.text = ((!isLocalized) ? text : Localization.Get(text)); uILabel.color = textColor; Transform cachedTransform = uILabel.cachedTransform; float num6 = border.x + padding.x; Vector2 pivotOffset = uILabel.pivotOffset; cachedTransform.localPosition = new Vector3(num6 - pivotOffset.x, num5, -1f); uILabel.overflowMethod = UILabel.Overflow.ResizeFreely; uILabel.alignment = alignment; list.Add(uILabel); num5 -= num3; num5 -= padding.y; float a = num4; Vector2 printedSize = uILabel.printedSize; num4 = Mathf.Max(a, printedSize.x); UIEventListener uIEventListener = UIEventListener.Get(uILabel.gameObject); uIEventListener.onHover = OnItemHover; uIEventListener.onPress = OnItemPress; uIEventListener.onClick = OnItemClick; uIEventListener.parameter = text; if (mSelectedItem == text || (i == 0 && string.IsNullOrEmpty(mSelectedItem))) { Highlight(uILabel, instant: true); } mLabelList.Add(uILabel); } float a2 = num4; Vector3 size = bounds.size; num4 = Mathf.Max(a2, size.x * activeFontScale - (border.x + padding.x) * 2f); float num7 = num4; Vector3 vector = new Vector3(num7 * 0.5f, (0f - num2) * 0.5f, 0f); Vector3 vector2 = new Vector3(num7, num3 + padding.y, 1f); int j = 0; for (int count2 = list.Count; j < count2; j++) { UILabel uILabel2 = list[j]; NGUITools.AddWidgetCollider(uILabel2.gameObject); uILabel2.autoResizeBoxCollider = false; BoxCollider component = uILabel2.GetComponent <BoxCollider>(); if (component != null) { Vector3 center = component.center; vector.z = center.z; component.center = vector; component.size = vector2; } else { BoxCollider2D component2 = uILabel2.GetComponent <BoxCollider2D>(); component2.offset = vector; component2.size = vector2; } } int width = Mathf.RoundToInt(num4); num4 += (border.x + padding.x) * 2f; num5 -= border.y; mBackground.width = Mathf.RoundToInt(num4); mBackground.height = Mathf.RoundToInt(0f - num5 + border.y); int k = 0; for (int count3 = list.Count; k < count3; k++) { UILabel uILabel3 = list[k]; uILabel3.overflowMethod = UILabel.Overflow.ShrinkContent; uILabel3.width = width; } float num8 = 2f * atlas.pixelSize; float f = num4 - (border.x + padding.x) * 2f + (float)atlasSprite.borderLeft * num8; float f2 = num3 + num * num8; mHighlight.width = Mathf.RoundToInt(f); mHighlight.height = Mathf.RoundToInt(f2); bool flag = position == Position.Above; if (position == Position.Auto) { UICamera uICamera = UICamera.FindCameraForLayer(base.gameObject.layer); if (uICamera != null) { Vector3 vector3 = uICamera.cachedCamera.WorldToViewportPoint(transform.position); flag = (vector3.y < 0.5f); } } if (isAnimated) { float bottom = num5 + num3; Animate(mHighlight, flag, bottom); int l = 0; for (int count4 = list.Count; l < count4; l++) { Animate(list[l], flag, bottom); } AnimateColor(mBackground); AnimateScale(mBackground, flag, bottom); } if (flag) { Transform transform3 = transform2; Vector3 min = bounds.min; float x = min.x; Vector3 max = bounds.max; float y = max.y - num5 - border.y; Vector3 min2 = bounds.min; transform3.localPosition = new Vector3(x, y, min2.z); } } } else { OnSelect(isSelected: false); } }
/// <summary> /// Add a border around the sprite that copies the pixels from the opposite side, making it possible for the sprite to tile without seams. /// </summary> void AddTiledBorder (UISpriteData sprite) { List<UIAtlasMaker.SpriteEntry> sprites = new List<UIAtlasMaker.SpriteEntry>(); UIAtlasMaker.ExtractSprites(mAtlas, sprites); UIAtlasMaker.SpriteEntry se = null; for (int i = 0; i < sprites.Count; ++i) { if (sprites[i].name == sprite.name) { se = sprites[i]; break; } } if (se != null) { int w1 = se.tex.width - se.borderLeft - se.borderRight; int h1 = se.tex.height - se.borderBottom - se.borderTop; int w2 = se.tex.width + 2; int h2 = se.tex.height + 2; Color32[] c1 = se.tex.GetPixels32(); Color32[] c2 = new Color32[w2 * h2]; for (int y2 = 0; y2 < h2; ++y2) { int y1 = se.borderBottom + NGUIMath.RepeatIndex(y2 - se.borderBottom - 1, h1); for (int x2 = 0; x2 < w2; ++x2) { int x1 = se.borderLeft + NGUIMath.RepeatIndex(x2 - se.borderLeft - 1, w1); c2[x2 + y2 * w2] = c1[x1 + y1 * se.tex.width]; } } if (se.temporaryTexture) DestroyImmediate(se.tex); ++se.borderLeft; ++se.borderRight; ++se.borderTop; ++se.borderBottom; se.tex = new Texture2D(w2, h2); se.tex.name = sprite.name; se.tex.SetPixels32(c2); se.tex.Apply(); se.temporaryTexture = true; UIAtlasMaker.UpdateAtlas(mAtlas, sprites); DestroyImmediate(se.tex); se.tex = null; } }
/// <summary> /// Draw the inspector widget. /// </summary> public override void OnInspectorGUI() { NGUIEditorTools.SetLabelWidth(80f); mAtlas = target as UIAtlas; UISpriteData sprite = (mAtlas != null) ? mAtlas.GetSprite(NGUISettings.selectedSprite) : null; GUILayout.Space(6f); if (mAtlas.replacement != null) { mType = AtlasType.Reference; mReplacement = mAtlas.replacement; } GUILayout.BeginHorizontal(); AtlasType after = (AtlasType)EditorGUILayout.EnumPopup("Atlas Type", mType); GUILayout.Space(18f); GUILayout.EndHorizontal(); if (mType != after) { if (after == AtlasType.Normal) { mType = AtlasType.Normal; OnSelectAtlas(null); } else { mType = AtlasType.Reference; } } if (mType == AtlasType.Reference) { ComponentSelector.Draw <UIAtlas>(mAtlas.replacement, OnSelectAtlas, true); GUILayout.Space(6f); 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; NGUITools.SetDirty(mAtlas); } return; } //GUILayout.Space(6f); 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.premultipliedAlpha); } mAtlas.MarkAsChanged(); } 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, !mAtlas.premultipliedAlpha); } NGUIEditorTools.RegisterUndo("Import Sprites", mAtlas); NGUIJson.LoadSpriteData(mAtlas, ta); if (sprite != null) { sprite = mAtlas.GetSprite(sprite.name); } mAtlas.MarkAsChanged(); } float pixelSize = EditorGUILayout.FloatField("Pixel Size", mAtlas.pixelSize, GUILayout.Width(120f)); if (pixelSize != mAtlas.pixelSize) { NGUIEditorTools.RegisterUndo("Atlas Change", mAtlas); mAtlas.pixelSize = pixelSize; } } if (mAtlas.spriteMaterial != null) { Color blueColor = new Color(0f, 0.7f, 1f, 1f); Color greenColor = new Color(0.4f, 1f, 0f, 1f); if (sprite == null && mAtlas.spriteList.Count > 0) { string spriteName = NGUISettings.selectedSprite; if (!string.IsNullOrEmpty(spriteName)) { sprite = mAtlas.GetSprite(spriteName); } if (sprite == null) { sprite = mAtlas.spriteList[0]; } } if (sprite != null) { if (sprite == null) { return; } Texture2D tex = mAtlas.spriteMaterial.mainTexture as Texture2D; if (tex != null) { if (!NGUIEditorTools.DrawHeader("Sprite Details")) { return; } NGUIEditorTools.BeginContents(); GUILayout.Space(3f); NGUIEditorTools.DrawAdvancedSpriteField(mAtlas, sprite.name, SelectSprite, true); GUILayout.Space(6f); GUI.changed = false; GUI.backgroundColor = greenColor; NGUIEditorTools.IntVector sizeA = NGUIEditorTools.IntPair("Dimensions", "X", "Y", sprite.x, sprite.y); NGUIEditorTools.IntVector sizeB = NGUIEditorTools.IntPair(null, "Width", "Height", sprite.width, sprite.height); EditorGUILayout.Separator(); GUI.backgroundColor = blueColor; NGUIEditorTools.IntVector borderA = NGUIEditorTools.IntPair("Border", "Left", "Right", sprite.borderLeft, sprite.borderRight); NGUIEditorTools.IntVector borderB = NGUIEditorTools.IntPair(null, "Bottom", "Top", sprite.borderBottom, sprite.borderTop); EditorGUILayout.Separator(); GUI.backgroundColor = Color.white; NGUIEditorTools.IntVector padA = NGUIEditorTools.IntPair("Padding", "Left", "Right", sprite.paddingLeft, sprite.paddingRight); NGUIEditorTools.IntVector padB = NGUIEditorTools.IntPair(null, "Bottom", "Top", sprite.paddingBottom, sprite.paddingTop); if (GUI.changed) { NGUIEditorTools.RegisterUndo("Atlas Change", mAtlas); sprite.x = sizeA.x; sprite.y = sizeA.y; sprite.width = sizeB.x; sprite.height = sizeB.y; sprite.paddingLeft = padA.x; sprite.paddingRight = padA.y; sprite.paddingBottom = padB.x; sprite.paddingTop = padB.y; sprite.borderLeft = borderA.x; sprite.borderRight = borderA.y; sprite.borderBottom = borderB.x; sprite.borderTop = borderB.y; MarkSpriteAsDirty(); } GUILayout.Space(3f); GUILayout.BeginHorizontal(); if (GUILayout.Button("Duplicate")) { UIAtlasMaker.SpriteEntry se = UIAtlasMaker.DuplicateSprite(mAtlas, sprite.name); if (se != null) { NGUISettings.selectedSprite = se.name; } } if (GUILayout.Button("Save As...")) { #if UNITY_3_5 string path = EditorUtility.SaveFilePanel("Save As", NGUISettings.currentPath, sprite.name + ".png", "png"); #else string path = EditorUtility.SaveFilePanelInProject("Save As", sprite.name + ".png", "png", "Extract sprite into which file?"); #endif if (!string.IsNullOrEmpty(path)) { NGUISettings.currentPath = System.IO.Path.GetDirectoryName(path); UIAtlasMaker.SpriteEntry se = UIAtlasMaker.ExtractSprite(mAtlas, sprite.name); if (se != null) { byte[] bytes = se.tex.EncodeToPNG(); File.WriteAllBytes(path, bytes); AssetDatabase.ImportAsset(path); if (se.temporaryTexture) { DestroyImmediate(se.tex); } } } } GUILayout.EndHorizontal(); NGUIEditorTools.EndContents(); } if (NGUIEditorTools.DrawHeader("Modify")) { NGUIEditorTools.BeginContents(); EditorGUILayout.BeginHorizontal(); GUILayout.Space(20f); EditorGUILayout.BeginVertical(); NGUISettings.backgroundColor = EditorGUILayout.ColorField("Background", NGUISettings.backgroundColor); if (GUILayout.Button("Add a Shadow")) { AddShadow(sprite); } if (GUILayout.Button("Add a Soft Outline")) { AddOutline(sprite); } if (GUILayout.Button("Add a Transparent Border")) { AddTransparentBorder(sprite); } if (GUILayout.Button("Add a Clamped Border")) { AddClampedBorder(sprite); } if (GUILayout.Button("Add a Tiled Border")) { AddTiledBorder(sprite); } EditorGUI.BeginDisabledGroup(!sprite.hasBorder); if (GUILayout.Button("Crop Border")) { CropBorder(sprite); } EditorGUI.EndDisabledGroup(); EditorGUILayout.EndVertical(); GUILayout.Space(20f); EditorGUILayout.EndHorizontal(); NGUIEditorTools.EndContents(); } if (NGUIEditorTools.previousSelection != null) { GUILayout.Space(3f); GUI.backgroundColor = Color.green; if (GUILayout.Button("<< Return to " + NGUIEditorTools.previousSelection.name)) { NGUIEditorTools.SelectPrevious(); } GUI.backgroundColor = Color.white; } } } }
public void BuildMesh(bool is_y) { Material mat = null; Texture tex = null; int paddingLeft = 0, paddingRight = 0, paddingTop = 0, paddingBottom = 0; int spr_x = 0, spr_y = 0, spr_w = 1, spr_h = 1; #if NGUI_USED UISpriteData sprData = null; if ((mAtlas == null) || ((mat = mAtlas.spriteMaterial) == null) || ((tex = mat.mainTexture) == null) || ((sprData = mAtlas.GetSprite(mSpriteName)) == null)) { Debug.Log("Build error - Atlas:" + mAtlas + ", Material:" + mat + ", Texture:" + tex + ", SpriteData:" + sprData); return; } paddingLeft = sprData.paddingLeft; paddingRight = sprData.paddingRight; paddingTop = sprData.paddingTop; paddingBottom = sprData.paddingBottom; spr_x = sprData.x; spr_y = sprData.y; spr_w = sprData.width; spr_h = sprData.height; #else if (((mat = _Material) == null) || ((tex = mat.mainTexture) == null)) { Debug.Log("Build error - Material:" + mat + ", Texture:" + tex); return; } spr_x = Mathf.RoundToInt(_SpriteRect.x); spr_y = Mathf.RoundToInt(_SpriteRect.y); spr_w = Mathf.RoundToInt(_SpriteRect.width); spr_h = Mathf.RoundToInt(_SpriteRect.height); #endif int width = paddingLeft + spr_w + paddingRight; int height = paddingTop + spr_h + paddingBottom; int numbers = 1; int numVertices = numbers * 4; int numTriangles = numbers * 6; float left = 0; float top = height; float right = width; float bottom = 0; left += paddingLeft; right -= paddingRight; top -= paddingTop; bottom += paddingBottom; Vector4 vsize = Vector4.zero; vsize.x = ((float)left / width) * _Size.x - _Size.x * 0.5f; vsize.y = ((float)bottom / height) * _Size.y - _Size.y * 0.5f; vsize.w = ((float)right / width) * _Size.x - _Size.x * 0.5f; vsize.z = ((float)top / height) * _Size.y - _Size.y * 0.5f; vsize.w -= vsize.x; // w vsize.z -= vsize.y; // h Vector2 [] _vertices = new Vector2 [4]; _vertices[0] = new Vector2(vsize.x, vsize.y); _vertices[1] = new Vector2(vsize.x + vsize.w, vsize.y); _vertices[2] = new Vector2(vsize.x + vsize.w, vsize.y + vsize.z); _vertices[3] = new Vector2(vsize.x, vsize.y + vsize.z); Vector4 usize = Vector4.zero; usize.x = (float)spr_x / tex.width; usize.y = (tex.height - ((float)spr_y + spr_h)) / tex.height; usize.w = ((float)spr_x + spr_w) / tex.width; usize.z = (tex.height - (float)spr_y) / tex.height; usize.w -= usize.x; // w usize.z -= usize.y; // h // Generate the mesh data Vector3 [] vertices = new Vector3[numVertices]; Vector3 [] normals = new Vector3[numVertices]; Vector2 [] uv = new Vector2[numVertices]; int [] triangles = new int [numTriangles]; int ori_index = 0; Vector2 start = _vertices[ori_index++]; Vector2 second = _vertices[ori_index++]; Vector2 third, fourth; for (int i = 0; i < numbers; i++) { int vertexIndex = i * 4; int triangleIndex = i * 6; third = _vertices[ori_index++]; fourth = _vertices[ori_index++]; vertices[vertexIndex + 0] = GetYPosition(start, is_y); vertices[vertexIndex + 1] = GetYPosition(second, is_y); vertices[vertexIndex + 2] = GetYPosition(third, is_y); vertices[vertexIndex + 3] = GetYPosition(fourth, is_y); second = fourth; uv[vertexIndex + 0] = GetUVPosition(vertices[vertexIndex + 0], vsize, usize, is_y); uv[vertexIndex + 1] = GetUVPosition(vertices[vertexIndex + 1], vsize, usize, is_y); uv[vertexIndex + 2] = GetUVPosition(vertices[vertexIndex + 2], vsize, usize, is_y); uv[vertexIndex + 3] = GetUVPosition(vertices[vertexIndex + 3], vsize, usize, is_y); normals[vertexIndex + 0] = new Vector3(0, 0, -1); normals[vertexIndex + 1] = new Vector3(0, 0, -1); normals[vertexIndex + 2] = new Vector3(0, 0, -1); normals[vertexIndex + 3] = new Vector3(0, 0, -1); triangles[triangleIndex + 0] = vertexIndex; triangles[triangleIndex + 1] = vertexIndex + 1; triangles[triangleIndex + 2] = vertexIndex + 2; triangles[triangleIndex + 3] = vertexIndex; triangles[triangleIndex + 4] = vertexIndex + 2; triangles[triangleIndex + 5] = vertexIndex + 3; } // Create a new Mesh and populate with the data Mesh mesh = new Mesh(); mesh.name = "tile_map"; mesh.vertices = vertices; mesh.normals = normals; mesh.uv = uv; mesh.triangles = triangles; MeshFilter mf = gameObject.GetComponent <MeshFilter>(); if (mf == null) { mf = gameObject.AddComponent <MeshFilter>(); } mf.sharedMesh = mesh; MeshRenderer mr = gameObject.GetComponent <MeshRenderer>(); if (mr == null) { mr = gameObject.AddComponent <MeshRenderer>(); } mr.sharedMaterial = mat; mr.lightProbeUsage = UnityEngine.Rendering.LightProbeUsage.Off; mr.reflectionProbeUsage = UnityEngine.Rendering.ReflectionProbeUsage.Off; mr.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off; mr.receiveShadows = false; __meshRenderer = mr; Debug.Log("Done Mesh!"); }
/// <summary> /// Convenience function that displays a list of sprites and returns the selected value. /// </summary> static public void AdvancedSpriteField(UIAtlas 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) { if (!string.Equals(spriteName, mLastSprite)) { mLastSprite = spriteName; mEditedName = null; } string newName = GUILayout.TextField(string.IsNullOrEmpty(mEditedName) ? spriteName : mEditedName); if (newName != spriteName) { mEditedName = newName; if (GUILayout.Button("Rename", GUILayout.Width(60f))) { UISpriteData sprite = atlas.GetSprite(spriteName); if (sprite != null) { NGUIEditorTools.RegisterUndo("Edit Sprite Name", atlas); sprite.name = newName; List <UISprite> sprites = FindAll <UISprite>(); for (int i = 0; i < sprites.Count; ++i) { UISprite sp = sprites[i]; if (sp.atlas == atlas && sp.spriteName == spriteName) { NGUIEditorTools.RegisterUndo("Edit Sprite Name", sp); sp.spriteName = newName; } } mLastSprite = newName; spriteName = newName; mEditedName = null; NGUISettings.selectedSprite = spriteName; } } } } else { GUILayout.BeginHorizontal(); GUILayout.Label(spriteName, "HelpBox", GUILayout.Height(18f)); GUILayout.Space(18f); GUILayout.EndHorizontal(); if (GUILayout.Button("Edit", GUILayout.Width(40f))) { NGUISettings.selectedSprite = spriteName; Select(atlas.gameObject); } } } GUILayout.EndHorizontal(); }
protected void refreshNumber() { Vector2 windowSize = getWindowSize(); // 整数部分 int dotPos = mNumber.LastIndexOf('.'); if (mNumber.Length > 0 && (dotPos == 0 || dotPos == mNumber.Length - 1)) { UnityUtility.logError("error : number can not start or end with dot!"); return; } string intPart = dotPos != -1 ? mNumber.Substring(0, dotPos) : mNumber; for (int i = 0; i < intPart.Length; ++i) { mNumberList[i].setSpriteName(mSpriteNameList[intPart[i] - '0']); } // 小数点和小数部分 if (dotPos != -1) { mNumberList[dotPos].setSpriteName(mSpriteNameList[10]); string floatPart = mNumber.Substring(dotPos + 1, mNumber.Length - dotPos - 1); for (int i = 0; i < floatPart.Length; ++i) { mNumberList[i + dotPos + 1].setSpriteName(mSpriteNameList[floatPart[i] - '0']); } } // 调整所有数字的大小,此处的aspectRatio可能没有更新 Vector2 numberSize = Vector2.zero; float numberScale = 0.0f; int numberLength = mNumber.Length; if (numberLength > 0) { int firstNumber = mNumber[0] - '0'; numberSize.y = windowSize.y; UISpriteData spriteData = mSpriteDataList[firstNumber]; float inverseHeight = 1.0f / spriteData.height; float ratio = (float)spriteData.width * inverseHeight; numberSize.x = ratio * numberSize.y; numberScale = windowSize.y * inverseHeight; } if (dotPos != -1) { Vector2 dotTextureSize = new Vector2(mSpriteDataList[10].width, mSpriteDataList[10].height); mNumberList[dotPos].setWindowSize(dotTextureSize * numberScale); } for (int i = 0; i < numberLength; ++i) { if (mNumber[i] != '.') { mNumberList[i].setWindowSize(numberSize); } } // 调整窗口位置,隐藏不需要显示的窗口 int contentWidth = getContentWidth(); Vector2 pos = Vector2.zero; if (mDockingPosition == DOCKING_POSITION.DP_RIGHT) { pos = new Vector2(windowSize.x - contentWidth, 0); } else if (mDockingPosition == DOCKING_POSITION.DP_CENTER) { pos = new Vector2((windowSize.x - contentWidth) * 0.5f, 0); } int count = mNumberList.Count; for (int i = 0; i < count; ++i) { mNumberList[i].setActive(i < numberLength); if (i < numberLength) { Vector2 size = mNumberList[i].getWindowSize(); mNumberList[i].setLocalPosition(pos - windowSize * 0.5f + size * 0.5f); pos.x += size.x + mInterval; } } }
public override void OnPreviewGUI(Rect drawRect, GUIStyle background) { MeshBuilder mb = target as MeshBuilder; #if NGUI_USED if ((mb == null) || (mb.mAtlas == null)) { return; } Texture2D tex = mb.mAtlas.texture as Texture2D; if (tex == null) { return; } UISpriteData sprData = mb.mAtlas.GetSprite(mb.mSpriteName); if (sprData == null) { return; } NGUIEditorTools.DrawSprite(tex, drawRect, sprData, Color.white); #else Texture tex2D; if ((mb._Material == null) || ((tex2D = mb._Material.mainTexture) == null)) { return; } Rect outerRect = drawRect; Rect sprRect = mb._SpriteRect; outerRect.width = sprRect.width; outerRect.height = sprRect.height; if (sprRect.width > 0) { float f = drawRect.width / outerRect.width; outerRect.width *= f; outerRect.height *= f; } if (drawRect.height > outerRect.height) { outerRect.y += (drawRect.height - outerRect.height) * 0.5f; } else if (outerRect.height > drawRect.height) { float f = drawRect.height / outerRect.height; outerRect.width *= f; outerRect.height *= f; } if (drawRect.width > outerRect.width) { outerRect.x += (drawRect.width - outerRect.width) * 0.5f; } Rect uv = sprRect; int width = tex2D.width; int height = tex2D.height; if (width != 0f && height != 0f) { uv.xMin = sprRect.xMin / width; uv.xMax = sprRect.xMax / width; uv.yMin = 1f - sprRect.yMax / height; uv.yMax = 1f - sprRect.yMin / height; } GUI.DrawTextureWithTexCoords(outerRect, tex2D, uv, true); #endif }
public void GenerateFilter() { Mesh mesh = new Mesh(); int length = text.Length; Vector3[] vertices = new Vector3[length << 2]; Vector2[] uvs = new Vector2[vertices.Length]; int[] triangles = new int[(length << 1) * 3]; Texture tex = atlas.texture; Color[] colors = new Color[vertices.Length]; int tmp = 0; float tmp2 = 0; switch (hAlignType) { case HorizontalAlignType.Center: tmp2 = -(vertices.Length >> 3); break; case HorizontalAlignType.Left: tmp2 = 0; break; case HorizontalAlignType.Right: tmp2 = -(vertices.Length >> 2); break; default: tmp2 = 0; break; } float r = 1; for (int i = 0; i < vertices.Length; i += 4) { tmp = (i + 1) % 2; string s = text[i / 4].ToString(); UISpriteData mSprite = atlas.GetSprite(s); r = (mSprite.width * 1.0f / mSprite.height); vertices[i] = new Vector3(tmp2, tmp + 1); vertices[i + 1] = new Vector3(tmp2, tmp); tmp2 += r; vertices[i + 2] = new Vector3(tmp2, tmp + 1); vertices[i + 3] = new Vector3(tmp2, tmp); colors[i] = color; colors[i + 1] = outlineColor; colors[i + 2] = color; colors[i + 3] = outlineColor; Rect inner = new Rect(mSprite.x + mSprite.borderLeft, mSprite.y + mSprite.borderTop, mSprite.width - mSprite.borderLeft - mSprite.borderRight, mSprite.height - mSprite.borderBottom - mSprite.borderTop); inner = NGUIMath.ConvertToTexCoords(inner, tex.width, tex.height); uvs[i] = new Vector2(inner.xMin, inner.yMax); uvs[i + 1] = new Vector2(inner.xMin, inner.yMin); uvs[i + 2] = new Vector2(inner.xMax, inner.yMax); uvs[i + 3] = new Vector2(inner.xMax, inner.yMin); } for (int i = 0; i < triangles.Length; i += 6) { tmp = (i / 3) << 1; triangles[i] = triangles[i + 3] = tmp; triangles[i + 1] = triangles[i + 5] = tmp + 3; triangles[i + 2] = tmp + 1; triangles[i + 4] = tmp + 2; } mesh.vertices = vertices; mesh.colors = colors; mesh.triangles = triangles; mesh.uv = uvs; meshFilter.mesh = mesh; }
/// <summary> /// Draw a sprite preview. /// </summary> static public void DrawSprite(Texture2D tex, Rect drawRect, UISpriteData sprite, Color color, Material mat) { // Create the texture rectangle that is centered inside rect. Rect outerRect = drawRect; outerRect.width = sprite.width; outerRect.height = sprite.height; if (sprite.width > 0) { float f = drawRect.width / outerRect.width; outerRect.width *= f; outerRect.height *= f; } if (drawRect.height > outerRect.height) { outerRect.y += (drawRect.height - outerRect.height) * 0.5f; } else if (outerRect.height > drawRect.height) { float f = drawRect.height / outerRect.height; outerRect.width *= f; outerRect.height *= f; } if (drawRect.width > outerRect.width) { outerRect.x += (drawRect.width - outerRect.width) * 0.5f; } // Draw the background NGUIEditorTools.DrawTiledTexture(outerRect, NGUIEditorTools.backdropTexture); // Draw the sprite GUI.color = color; if (mat == null) { Rect uv = new Rect(sprite.x, sprite.y, sprite.width, sprite.height); uv = NGUIMath.ConvertToTexCoords(uv, tex.width, tex.height); GUI.DrawTextureWithTexCoords(outerRect, tex, uv, true); } else { // NOTE: There is an issue in Unity that prevents it from clipping the drawn preview // using BeginGroup/EndGroup, and there is no way to specify a UV rect... le'suq. UnityEditor.EditorGUI.DrawPreviewTexture(outerRect, tex, mat); } // Draw the border indicator lines GUI.BeginGroup(outerRect); { tex = NGUIEditorTools.contrastTexture; GUI.color = Color.white; if (sprite.borderLeft > 0) { float x0 = (float)sprite.borderLeft / sprite.width * outerRect.width - 1; NGUIEditorTools.DrawTiledTexture(new Rect(x0, 0f, 1f, outerRect.height), tex); } if (sprite.borderRight > 0) { float x1 = (float)(sprite.width - sprite.borderRight) / sprite.width * outerRect.width - 1; NGUIEditorTools.DrawTiledTexture(new Rect(x1, 0f, 1f, outerRect.height), tex); } if (sprite.borderBottom > 0) { float y0 = (float)(sprite.height - sprite.borderBottom) / sprite.height * outerRect.height - 1; NGUIEditorTools.DrawTiledTexture(new Rect(0f, y0, outerRect.width, 1f), tex); } if (sprite.borderTop > 0) { float y1 = (float)sprite.borderTop / sprite.height * outerRect.height - 1; NGUIEditorTools.DrawTiledTexture(new Rect(0f, y1, outerRect.width, 1f), tex); } } GUI.EndGroup(); // Draw the lines around the sprite Handles.color = Color.black; Handles.DrawLine(new Vector3(outerRect.xMin, outerRect.yMin), new Vector3(outerRect.xMin, outerRect.yMax)); Handles.DrawLine(new Vector3(outerRect.xMax, outerRect.yMin), new Vector3(outerRect.xMax, outerRect.yMax)); Handles.DrawLine(new Vector3(outerRect.xMin, outerRect.yMin), new Vector3(outerRect.xMax, outerRect.yMin)); Handles.DrawLine(new Vector3(outerRect.xMin, outerRect.yMax), new Vector3(outerRect.xMax, outerRect.yMax)); // Sprite size label string text = string.Format("Sprite Size: {0}x{1}", Mathf.RoundToInt(sprite.width), Mathf.RoundToInt(sprite.height)); EditorGUI.DropShadowLabel(GUILayoutUtility.GetRect(Screen.width, 18f), text); }
/// <summary> /// Draw a sprite preview. /// </summary> static public void DrawSprite(Texture2D tex, Rect rect, UISpriteData sprite, Color color) { DrawSprite(tex, rect, sprite, color, null); }
/// <summary> /// Add a dark shadowy outline around the sprite, giving it some visual depth. /// </summary> void AddDepth (UISpriteData sprite) { List<UIAtlasMaker.SpriteEntry> sprites = new List<UIAtlasMaker.SpriteEntry>(); UIAtlasMaker.ExtractSprites(mAtlas, sprites); UIAtlasMaker.SpriteEntry se = null; for (int i = 0; i < sprites.Count; ++i) { if (sprites[i].name == sprite.name) { se = sprites[i]; break; } } if (se != null) { int w1 = se.tex.width; int h1 = se.tex.height; int w2 = w1 + 2; int h2 = h1 + 2; Color32[] c1 = se.tex.GetPixels32(); Color32[] c2 = new Color32[w2 * h2]; for (int y2 = 0; y2 < h2; ++y2) { int y1 = NGUIMath.ClampIndex(y2 - 1, h1); for (int x2 = 0; x2 < w2; ++x2) { int x1 = NGUIMath.ClampIndex(x2 - 1, w1); int i2 = x2 + y2 * w2; c2[i2] = c1[x1 + y1 * w1]; if (x2 == 0 || x2 + 1 == w2 || y2 == 0 || y2 + 1 == h2) c2[i2].a = 0; } } for (int y2 = 0; y2 < h2; ++y2) { for (int x2 = 0; x2 < w2; ++x2) { int index = x2 + y2 * w2; Color32 uc = c2[index]; if (uc.a == 255) continue; Color original = uc; float val = original.a * 4f; int count = 4; float div1 = 1f / 255f; float div2 = 2f / 255f; if (x2 != 0) { val += c2[x2 - 1 + y2 * w2].a * div2; count += 2; } if (x2 + 1 != w2) { val += c2[x2 + 1 + y2 * w2].a * div2; count += 2; } if (y2 != 0) { val += c2[x2 + (y2 - 1) * w2].a * div2; count += 2; } if (y2 + 1 != h2) { val += c2[x2 + (y2 + 1) * w2].a * div2; count += 2; } if (x2 != 0 && y2 != 0) { val += c2[x2 - 1 + (y2 - 1) * w2].a * div1; ++count; } if (x2 != 0 && y2 + 1 != h2) { val += c2[x2 - 1 + (y2 + 1) * w2].a * div1; ++count; } if (x2 + 1 != w2 && y2 != 0) { val += c2[x2 + 1 + (y2 - 1) * w2].a * div1; ++count; } if (x2 + 1 != w2 && y2 + 1 != h2) { val += c2[x2 + 1 + (y2 + 1) * w2].a * div1; ++count; } val /= count; Color shadow = new Color(0f, 0f, 0f, val); shadow = Color.Lerp(original, shadow, mAlpha); c2[index] = Color.Lerp(shadow, original, original.a); } } if (se.temporaryTexture) DestroyImmediate(se.tex); ++se.borderLeft; ++se.borderRight; ++se.borderTop; ++se.borderBottom; se.tex = new Texture2D(w2, h2); se.tex.name = sprite.name; se.tex.SetPixels32(c2); se.tex.Apply(); se.temporaryTexture = true; UIAtlasMaker.UpdateAtlas(mAtlas, sprites); DestroyImmediate(se.tex); se.tex = null; } }
/// <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 && isValid && items.Count > 0) { mLabelList.Clear(); // Automatically locate the panel responsible for this object if (mPanel == null) { mPanel = UIPanel.Find(transform); if (mPanel == null) { return; } } // Disable the navigation script handleEvents = 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; UISpriteData hlsp = mHighlight.GetAtlasSprite(); if (hlsp == null) { return; } float hlspHeight = hlsp.borderTop; float fontHeight = activeFontSize; float dynScale = activeFontScale; float labelHeight = fontHeight * dynScale; float x = 0f, y = -padding.y; int labelFontSize = (bitmapFont != null) ? bitmapFont.defaultSize : fontSize; 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.bitmapFont = bitmapFont; lbl.trueTypeFont = trueTypeFont; lbl.fontSize = labelFontSize; lbl.fontStyle = fontStyle; lbl.text = isLocalized ? Localization.Get(s) : s; lbl.color = textColor; lbl.cachedTransform.localPosition = new Vector3(bgPadding.x + padding.x, y, -1f); lbl.overflowMethod = UILabel.Overflow.ResizeFreely; lbl.MakePixelPerfect(); if (dynScale != 1f) { lbl.cachedTransform.localScale = Vector3.one * dynScale; } labels.Add(lbl); y -= labelHeight; y -= padding.y; x = Mathf.Max(x, lbl.printedSize.x); // 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 || (i == 0 && string.IsNullOrEmpty(mSelectedItem))) { 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 * dynScale - (bgPadding.x + padding.x) * 2f); float cx = x / dynScale; Vector3 bcCenter = new Vector3(cx * 0.5f, -fontHeight * 0.5f, 0f); Vector3 bcSize = new Vector3(cx, (labelHeight + padding.y) / dynScale, 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.width = Mathf.RoundToInt(x); mBackground.height = Mathf.RoundToInt(-y + bgPadding.y); // Scale the highlight sprite to envelop a single item float scaleFactor = 2f * atlas.pixelSize; float w = x - (bgPadding.x + padding.x) * 2f + hlsp.borderLeft * scaleFactor; float h = labelHeight + hlspHeight * scaleFactor; mHighlight.width = Mathf.RoundToInt(w); mHighlight.height = Mathf.RoundToInt(h); 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 + labelHeight; 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> /// Extract the specified sprite from the atlas texture. /// </summary> static SpriteEntry ExtractSprite (UISpriteData es, Color32[] oldPixels, int oldWidth, int oldHeight) { int xmin = Mathf.Clamp(es.x, 0, oldWidth); int ymin = Mathf.Clamp(es.y, 0, oldHeight); int xmax = Mathf.Min(xmin + es.width, oldWidth - 1); int ymax = Mathf.Min(ymin + es.height, oldHeight - 1); int newWidth = Mathf.Clamp(es.width, 0, oldWidth); int newHeight = Mathf.Clamp(es.height, 0, oldHeight); if (newWidth == 0 || newHeight == 0) return null; Color32[] newPixels = new Color32[newWidth * newHeight]; for (int y = 0; y < newHeight; ++y) { int cy = ymin + y; if (cy > ymax) cy = ymax; for (int x = 0; x < newWidth; ++x) { int cx = xmin + x; if (cx > xmax) cx = xmax; int newIndex = (newHeight - 1 - y) * newWidth + x; int oldIndex = (oldHeight - 1 - cy) * oldWidth + cx; newPixels[newIndex] = oldPixels[oldIndex]; } } // Create a new sprite SpriteEntry sprite = new SpriteEntry(); sprite.CopyFrom(es); sprite.SetRect(0, 0, newWidth, newHeight); sprite.temporaryTexture = true; sprite.tex = new Texture2D(newWidth, newHeight); sprite.tex.SetPixels32(newPixels); sprite.tex.Apply(); return sprite; }
public override void MarkAsChanged() { mSprite = null; mSpriteSet = false; base.MarkAsChanged(); }
/// <summary> /// Add a dark shadowy outline around the sprite, giving it some visual depth. /// </summary> void AddOutline (UISpriteData sprite) { List<UIAtlasMaker.SpriteEntry> sprites = new List<UIAtlasMaker.SpriteEntry>(); UIAtlasMaker.ExtractSprites(mAtlas, sprites); UIAtlasMaker.SpriteEntry se = null; for (int i = 0; i < sprites.Count; ++i) { if (sprites[i].name == sprite.name) { se = sprites[i]; break; } } if (se != null) { int w1 = se.tex.width; int h1 = se.tex.height; int w2 = w1 + 2; int h2 = h1 + 2; Color32[] c2 = NGUIEditorTools.AddBorder(se.tex.GetPixels32(), w1, h1); NGUIEditorTools.AddDepth(c2, w2, h2, NGUISettings.backgroundColor); if (se.temporaryTexture) DestroyImmediate(se.tex); if ((se.borderLeft | se.borderRight | se.borderBottom | se.borderTop) != 0) { ++se.borderLeft; ++se.borderRight; ++se.borderTop; ++se.borderBottom; } se.tex = new Texture2D(w2, h2); se.tex.name = sprite.name; se.tex.SetPixels32(c2); se.tex.Apply(); se.temporaryTexture = true; UIAtlasMaker.UpdateAtlas(mAtlas, sprites); DestroyImmediate(se.tex); se.tex = null; } }
public override void OnFill(BetterList<Vector3> verts, BetterList<Vector2> uvs, BetterList<Color32> cols) { Texture mainTexture = this.mainTexture; if (mainTexture != null) { if (this.mSprite == null) { this.mSprite = this.atlas.GetSprite(this.spriteName); } if (this.mSprite == null) { return; } this.mOuterUV.Set((float) this.mSprite.x, (float) this.mSprite.y, (float) this.mSprite.width, (float) this.mSprite.height); this.mInnerUV.Set((float) (this.mSprite.x + this.mSprite.borderLeft), (float) (this.mSprite.y + this.mSprite.borderTop), (float) ((this.mSprite.width - this.mSprite.borderLeft) - this.mSprite.borderRight), (float) ((this.mSprite.height - this.mSprite.borderBottom) - this.mSprite.borderTop)); this.mOuterUV = NGUIMath.ConvertToTexCoords(this.mOuterUV, mainTexture.width, mainTexture.height); this.mInnerUV = NGUIMath.ConvertToTexCoords(this.mInnerUV, mainTexture.width, mainTexture.height); } switch (this.type) { case Type.Simple: this.SimpleFill(verts, uvs, cols); break; case Type.Sliced: this.SlicedFill(verts, uvs, cols); break; case Type.Tiled: this.TiledFill(verts, uvs, cols); break; case Type.Filled: this.FilledFill(verts, uvs, cols); break; } }
/// <summary> /// Apply an effect to the font. /// </summary> void ApplyEffect(Effect effect, Color foreground, Color background) { BMFont bf = mFont.bmFont; int offsetX = 0; int offsetY = 0; if (mFont.atlas != null) { UISpriteData sd = mFont.atlas.GetSprite(bf.spriteName); if (sd == null) { return; } offsetX = sd.x; offsetY = sd.y + mFont.texHeight - sd.paddingTop; } string path = AssetDatabase.GetAssetPath(mFont.texture); Texture2D bfTex = NGUIEditorTools.ImportTexture(path, true, true, false); Color32[] atlas = bfTex.GetPixels32(); // First we need to extract textures for all the glyphs, making them bigger in the process List <BMGlyph> glyphs = bf.glyphs; List <Texture2D> glyphTextures = new List <Texture2D>(glyphs.Count); for (int i = 0, imax = glyphs.Count; i < imax; ++i) { BMGlyph glyph = glyphs[i]; if (glyph.width < 1 || glyph.height < 1) { continue; } int width = glyph.width; int height = glyph.height; if (effect == Effect.Outline || effect == Effect.Shadow || effect == Effect.Border) { width += 2; height += 2; --glyph.offsetX; --glyph.offsetY; } else if (effect == Effect.Crop && width > 2 && height > 2) { width -= 2; height -= 2; ++glyph.offsetX; ++glyph.offsetY; } int size = width * height; Color32[] colors = new Color32[size]; Color32 clear = background; clear.a = 0; for (int b = 0; b < size; ++b) { colors[b] = clear; } if (effect == Effect.Crop) { for (int y = 0; y < height; ++y) { for (int x = 0; x < width; ++x) { int fx = x + glyph.x + offsetX + 1; int fy = y + (mFont.texHeight - glyph.y - glyph.height) + 1; if (mFont.atlas != null) { fy += bfTex.height - offsetY; } colors[x + y * width] = atlas[fx + fy * bfTex.width]; } } } else { for (int y = 0; y < glyph.height; ++y) { for (int x = 0; x < glyph.width; ++x) { int fx = x + glyph.x + offsetX; int fy = y + (mFont.texHeight - glyph.y - glyph.height); if (mFont.atlas != null) { fy += bfTex.height - offsetY; } Color c = atlas[fx + fy * bfTex.width]; if (effect == Effect.Border) { colors[x + 1 + (y + 1) * width] = c; } else { if (effect == Effect.AlphaCurve) { c.a = Mathf.Clamp01(mCurve.Evaluate(c.a)); } Color bg = background; bg.a = (effect == Effect.BackgroundCurve) ? Mathf.Clamp01(mCurve.Evaluate(c.a)) : c.a; Color fg = foreground; fg.a = (effect == Effect.ForegroundCurve) ? Mathf.Clamp01(mCurve.Evaluate(c.a)) : c.a; if (effect == Effect.Outline || effect == Effect.Shadow) { colors[x + 1 + (y + 1) * width] = Color.Lerp(bg, c, c.a); } else { colors[x + y * width] = Color.Lerp(bg, fg, c.a); } } } } // Apply the appropriate affect if (effect == Effect.Shadow) { NGUIEditorTools.AddShadow(colors, width, height, NGUISettings.backgroundColor); } else if (effect == Effect.Outline) { NGUIEditorTools.AddDepth(colors, width, height, NGUISettings.backgroundColor); } } Texture2D tex = new Texture2D(width, height, TextureFormat.ARGB32, false); tex.SetPixels32(colors); tex.Apply(); glyphTextures.Add(tex); } // Pack all glyphs into a new texture Texture2D final = new Texture2D(bfTex.width, bfTex.height, TextureFormat.ARGB32, false); Rect[] rects = final.PackTextures(glyphTextures.ToArray(), 1); final.Apply(); // Make RGB channel use the background color (Unity makes it black by default) Color32[] fcs = final.GetPixels32(); Color32 bc = background; for (int i = 0, imax = fcs.Length; i < imax; ++i) { if (fcs[i].a == 0) { fcs[i].r = bc.r; fcs[i].g = bc.g; fcs[i].b = bc.b; } } final.SetPixels32(fcs); final.Apply(); // Update the glyph rectangles int index = 0; int tw = final.width; int th = final.height; for (int i = 0, imax = glyphs.Count; i < imax; ++i) { BMGlyph glyph = glyphs[i]; if (glyph.width < 1 || glyph.height < 1) { continue; } Rect rect = rects[index++]; glyph.x = Mathf.RoundToInt(rect.x * tw); glyph.y = Mathf.RoundToInt(rect.y * th); glyph.width = Mathf.RoundToInt(rect.width * tw); glyph.height = Mathf.RoundToInt(rect.height * th); glyph.y = th - glyph.y - glyph.height; } // Update the font's texture dimensions mFont.texWidth = final.width; mFont.texHeight = final.height; if (mFont.atlas == null) { // Save the final texture byte[] bytes = final.EncodeToPNG(); NGUITools.DestroyImmediate(final); System.IO.File.WriteAllBytes(path, bytes); AssetDatabase.Refresh(ImportAssetOptions.ForceSynchronousImport); } else { // Update the atlas final.name = mFont.spriteName; bool val = NGUISettings.atlasTrimming; NGUISettings.atlasTrimming = false; UIAtlasMaker.AddOrUpdate(mFont.atlas, final); NGUISettings.atlasTrimming = val; NGUITools.DestroyImmediate(final); } // Cleanup for (int i = 0; i < glyphTextures.Count; ++i) { NGUITools.DestroyImmediate(glyphTextures[i]); } // Refresh all labels mFont.MarkAsChanged(); }
public override void Update() { base.Update(); if (base.mChanged || !this.mSpriteSet) { this.mSpriteSet = true; this.mSprite = null; base.mChanged = true; } }
public override void OnInspectorGUI() { NGUIEditorTools.SetLabelWidth(80f); GUILayout.Space(6f); if (mFont.replacement != null) { mType = FontType.Reference; mReplacement = mFont.replacement; } else if (mFont.dynamicFont != null) { mType = FontType.Dynamic; } GUI.changed = false; GUILayout.BeginHorizontal(); mType = (FontType)EditorGUILayout.EnumPopup("Font Type", mType); NGUIEditorTools.DrawPadding(); GUILayout.EndHorizontal(); if (GUI.changed) { if (mType == FontType.Bitmap) { OnSelectFont(null); } if (mType != FontType.Dynamic && mFont.dynamicFont != null) { mFont.dynamicFont = null; } } if (mType == FontType.Reference) { ComponentSelector.Draw(mFont.replacement, OnSelectFont, true); GUILayout.Space(6f); EditorGUILayout.HelpBox("You can have one font simply point to " + "another one. This is useful if you want to be " + "able to quickly replace the contents of one " + "font with another one, for example for " + "swapping an SD font with an HD one, or " + "replacing an English font with a Chinese " + "one. All the labels referencing this font " + "will update their references to the new one.", MessageType.Info); if (mReplacement != mFont && mFont.replacement != mReplacement) { NGUIEditorTools.RegisterUndo("Font Change", mFont as Object); mFont.replacement = mReplacement; NGUITools.SetDirty(mFont as Object); } return; } else if (mType == FontType.Dynamic) { #if UNITY_3_5 EditorGUILayout.HelpBox("Dynamic fonts require Unity 4.0 or higher.", MessageType.Error); #else Font fnt = EditorGUILayout.ObjectField("TTF Font", mFont.dynamicFont, typeof(Font), false) as Font; if (fnt != mFont.dynamicFont) { NGUIEditorTools.RegisterUndo("Font change", mFont as Object); mFont.dynamicFont = fnt; } Material mat = EditorGUILayout.ObjectField("Material", mFont.material, typeof(Material), false) as Material; if (mFont.material != mat) { NGUIEditorTools.RegisterUndo("Font Material", mFont as Object); mFont.material = mat; } GUILayout.BeginHorizontal(); int size = EditorGUILayout.IntField("Default Size", mFont.defaultSize, GUILayout.Width(120f)); FontStyle style = (FontStyle)EditorGUILayout.EnumPopup(mFont.dynamicFontStyle); NGUIEditorTools.DrawPadding(); GUILayout.EndHorizontal(); if (size != mFont.defaultSize) { NGUIEditorTools.RegisterUndo("Font change", mFont as Object); mFont.defaultSize = size; } if (style != mFont.dynamicFontStyle) { NGUIEditorTools.RegisterUndo("Font change", mFont as Object); mFont.dynamicFontStyle = style; } #endif } else { ComponentSelector.Draw(mFont.atlas, OnSelectAtlas, true); if (mFont.atlas != null) { if (mFont.bmFont.isValid) { NGUIEditorTools.DrawAdvancedSpriteField(mFont.atlas, mFont.spriteName, SelectSprite, false); } } else { // No atlas specified -- set the material and texture rectangle directly Material mat = EditorGUILayout.ObjectField("Material", mFont.material, typeof(Material), false) as Material; if (mFont.material != mat) { NGUIEditorTools.RegisterUndo("Font Material", mFont as Object); mFont.material = mat; } } if (!mFont.isDynamic) { EditorGUI.BeginDisabledGroup(true); EditorGUILayout.IntField("Default Size", mFont.defaultSize, GUILayout.Width(120f)); EditorGUI.EndDisabledGroup(); } EditorGUILayout.Space(); // For updating the font's data when importing from an external source, such as the texture packer bool resetWidthHeight = false; if (mFont.atlas != null || mFont.material != null) { TextAsset data = EditorGUILayout.ObjectField("Import Data", null, typeof(TextAsset), false) as TextAsset; if (data != null) { NGUIEditorTools.RegisterUndo("Import Font Data", mFont as Object); BMFontReader.Load(mFont.bmFont, (mFont as Object).name, data.bytes); mFont.MarkAsChanged(); resetWidthHeight = true; Debug.Log("Imported " + mFont.bmFont.glyphCount + " characters"); } } if (mFont is UIFont && mFont.bmFont.isValid) { EditorGUILayout.HelpBox("Legacy font type should be upgraded in order to maintain compatibility with Unity 2018 and newer.", MessageType.Warning, true); if (GUILayout.Button("Upgrade")) { var path = EditorUtility.SaveFilePanelInProject("Save As", (mFont as Object).name + ".asset", "asset", "Save atlas as...", NGUISettings.currentPath); if (!string.IsNullOrEmpty(path)) { NGUISettings.currentPath = System.IO.Path.GetDirectoryName(path); var asset = ScriptableObject.CreateInstance <NGUIFont>(); asset.bmFont = mFont.bmFont; asset.symbols = mFont.symbols; asset.atlas = mFont.atlas; asset.spriteName = mFont.spriteName; asset.uvRect = mFont.uvRect; asset.defaultSize = mFont.defaultSize; var fontName = path.Replace(".asset", ""); fontName = fontName.Substring(path.LastIndexOfAny(new char[] { '/', '\\' }) + 1); asset.name = fontName; AssetDatabase.CreateAsset(asset, path); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(ImportAssetOptions.ForceSynchronousImport); asset = AssetDatabase.LoadAssetAtPath <NGUIFont>(path); NGUISettings.ambigiousFont = asset; Selection.activeObject = asset; if (asset != null) { mFont.replacement = asset; mFont.MarkAsChanged(); } } } } if (mFont.bmFont.isValid) { Texture2D tex = mFont.texture; if (tex != null && mFont.atlas == null) { // Pixels are easier to work with than UVs Rect pixels = NGUIMath.ConvertToPixels(mFont.uvRect, tex.width, tex.height, false); // Automatically set the width and height of the rectangle to be the original font texture's dimensions if (resetWidthHeight) { pixels.width = mFont.texWidth; pixels.height = mFont.texHeight; } // Font sprite rectangle pixels = EditorGUILayout.RectField("Pixel Rect", pixels); // Convert the pixel coordinates back to UV coordinates Rect uvRect = NGUIMath.ConvertToTexCoords(pixels, tex.width, tex.height); if (mFont.uvRect != uvRect) { NGUIEditorTools.RegisterUndo("Font Pixel Rect", mFont as Object); mFont.uvRect = uvRect; } //NGUIEditorTools.DrawSeparator(); EditorGUILayout.Space(); } } } // Dynamic fonts don't support emoticons if (!mFont.isDynamic && mFont.bmFont.isValid) { if (mFont.atlas != null) { if (NGUIEditorTools.DrawHeader("Symbols and Emoticons")) { NGUIEditorTools.BeginContents(); List <BMSymbol> symbols = mFont.symbols; for (int i = 0; i < symbols.Count;) { BMSymbol sym = symbols[i]; GUILayout.BeginHorizontal(); GUILayout.Label(sym.sequence, GUILayout.Width(40f)); if (NGUIEditorTools.DrawSpriteField(mFont.atlas, sym.spriteName, ChangeSymbolSprite, GUILayout.MinWidth(100f))) { mSelectedSymbol = sym; } if (GUILayout.Button("Edit", GUILayout.Width(40f))) { if (mFont.atlas != null) { NGUISettings.atlas = mFont.atlas; NGUISettings.selectedSprite = sym.spriteName; NGUIEditorTools.Select(mFont.atlas as Object); } } GUI.backgroundColor = Color.red; if (GUILayout.Button("X", GUILayout.Width(22f))) { NGUIEditorTools.RegisterUndo("Remove symbol", mFont as Object); mSymbolSequence = sym.sequence; mSymbolSprite = sym.spriteName; symbols.Remove(sym); mFont.MarkAsChanged(); } GUI.backgroundColor = Color.white; GUILayout.EndHorizontal(); GUILayout.Space(4f); ++i; } if (symbols.Count > 0) { GUILayout.Space(6f); } GUILayout.BeginHorizontal(); mSymbolSequence = EditorGUILayout.TextField(mSymbolSequence, GUILayout.Width(40f)); NGUIEditorTools.DrawSpriteField(mFont.atlas, mSymbolSprite, SelectSymbolSprite); bool isValid = !string.IsNullOrEmpty(mSymbolSequence) && !string.IsNullOrEmpty(mSymbolSprite); GUI.backgroundColor = isValid ? Color.green : Color.grey; if (GUILayout.Button("Add", GUILayout.Width(40f)) && isValid) { NGUIEditorTools.RegisterUndo("Add symbol", mFont as Object); mFont.AddSymbol(mSymbolSequence, mSymbolSprite); mFont.MarkAsChanged(); mSymbolSequence = ""; mSymbolSprite = ""; } GUI.backgroundColor = Color.white; GUILayout.EndHorizontal(); if (symbols.Count == 0) { EditorGUILayout.HelpBox("Want to add an emoticon to your font? In the field above type ':)', choose a sprite, then hit the Add button.", MessageType.Info); } else { GUILayout.Space(4f); } NGUIEditorTools.EndContents(); } } } if (mFont.bmFont != null && mFont.bmFont.isValid) { if (NGUIEditorTools.DrawHeader("Modify")) { NGUIEditorTools.BeginContents(); UISpriteData sd = mFont.sprite; bool disable = (sd != null && (sd.paddingLeft != 0 || sd.paddingBottom != 0)); EditorGUI.BeginDisabledGroup(disable || mFont.packedFontShader); EditorGUILayout.BeginHorizontal(); GUILayout.Space(20f); EditorGUILayout.BeginVertical(); GUILayout.BeginHorizontal(); GUILayout.BeginVertical(); NGUISettings.foregroundColor = EditorGUILayout.ColorField("Foreground", NGUISettings.foregroundColor); NGUISettings.backgroundColor = EditorGUILayout.ColorField("Background", NGUISettings.backgroundColor); GUILayout.EndVertical(); mCurve = EditorGUILayout.CurveField("", mCurve, GUILayout.Width(40f), GUILayout.Height(40f)); GUILayout.EndHorizontal(); if (GUILayout.Button("Add a Shadow")) { ApplyEffect(Effect.Shadow, NGUISettings.foregroundColor, NGUISettings.backgroundColor); } if (GUILayout.Button("Add a Soft Outline")) { ApplyEffect(Effect.Outline, NGUISettings.foregroundColor, NGUISettings.backgroundColor); } if (GUILayout.Button("Rebalance Colors")) { ApplyEffect(Effect.Rebalance, NGUISettings.foregroundColor, NGUISettings.backgroundColor); } if (GUILayout.Button("Apply Curve to Alpha")) { ApplyEffect(Effect.AlphaCurve, NGUISettings.foregroundColor, NGUISettings.backgroundColor); } if (GUILayout.Button("Apply Curve to Foreground")) { ApplyEffect(Effect.ForegroundCurve, NGUISettings.foregroundColor, NGUISettings.backgroundColor); } if (GUILayout.Button("Apply Curve to Background")) { ApplyEffect(Effect.BackgroundCurve, NGUISettings.foregroundColor, NGUISettings.backgroundColor); } GUILayout.Space(10f); if (GUILayout.Button("Add Transparent Border (+1)")) { ApplyEffect(Effect.Border, NGUISettings.foregroundColor, NGUISettings.backgroundColor); } if (GUILayout.Button("Remove Border (-1)")) { ApplyEffect(Effect.Crop, NGUISettings.foregroundColor, NGUISettings.backgroundColor); } EditorGUILayout.EndVertical(); GUILayout.Space(20f); EditorGUILayout.EndHorizontal(); EditorGUI.EndDisabledGroup(); if (disable) { GUILayout.Space(3f); EditorGUILayout.HelpBox("The sprite used by this font has been trimmed and is not suitable for modification. " + "Try re-adding this sprite with 'Trim Alpha' disabled.", MessageType.Warning); } NGUIEditorTools.EndContents(); } } // The font must be valid at this point for the rest of the options to show up if (mFont.isDynamic || mFont.bmFont.isValid) { if (mFont.atlas == null) { mView = View.Font; mUseShader = false; } } // Preview option if (!mFont.isDynamic && mFont.atlas != null) { GUILayout.BeginHorizontal(); { mView = (View)EditorGUILayout.EnumPopup("Preview", mView); GUILayout.Label("Shader", GUILayout.Width(45f)); mUseShader = EditorGUILayout.Toggle(mUseShader, GUILayout.Width(20f)); } GUILayout.EndHorizontal(); } }
/// <summary> /// Draw the inspector widget. /// </summary> public override void OnInspectorGUI() { NGUIEditorTools.SetLabelWidth(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()); UISpriteData 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 = new Rect(sprite.x, sprite.y, sprite.width, sprite.height); 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.height / sprite.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; } } } }
public UISpriteData GetAtlasSprite() { if (!this.mSpriteSet) { this.mSprite = null; } if ((this.mSprite == null) && (this.mAtlas != null)) { if (!string.IsNullOrEmpty(this.mSpriteName)) { UISpriteData sprite = this.mAtlas.GetSprite(this.mSpriteName); if (sprite == null) { return null; } this.SetAtlasSprite(sprite); } if ((this.mSprite == null) && (this.mAtlas.spriteList.Count > 0)) { UISpriteData sp = this.mAtlas.spriteList[0]; if (sp == null) { return null; } this.SetAtlasSprite(sp); if (this.mSprite == null) { Debug.LogError(this.mAtlas.name + " seems to have a null sprite!"); return null; } this.mSpriteName = this.mSprite.name; } } return this.mSprite; }
public BetterList <string> GetListOfSprites(string match) { if (this.mReplacement) { return(this.mReplacement.GetListOfSprites(match)); } if (string.IsNullOrEmpty(match)) { return(this.GetListOfSprites()); } if (this.mSprites.Count == 0) { this.Upgrade(); } BetterList <string> betterList = new BetterList <string>(); int i = 0; int count = this.mSprites.Count; while (i < count) { UISpriteData uISpriteData = this.mSprites[i]; if (uISpriteData != null && !string.IsNullOrEmpty(uISpriteData.name) && string.Equals(match, uISpriteData.name, StringComparison.OrdinalIgnoreCase)) { betterList.Add(uISpriteData.name); return(betterList); } i++; } string[] array = match.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); for (int j = 0; j < array.Length; j++) { array[j] = array[j].ToLower(); } int k = 0; int count2 = this.mSprites.Count; while (k < count2) { UISpriteData uISpriteData2 = this.mSprites[k]; if (uISpriteData2 != null && !string.IsNullOrEmpty(uISpriteData2.name)) { string text = uISpriteData2.name.ToLower(); int num = 0; for (int l = 0; l < array.Length; l++) { if (text.Contains(array[l])) { num++; } } if (num == array.Length) { betterList.Add(uISpriteData2.name); } } k++; } return(betterList); }
protected void SetAtlasSprite(UISpriteData sp) { base.mChanged = true; this.mSpriteSet = true; if (sp != null) { this.mSprite = sp; this.mSpriteName = this.mSprite.name; } else { this.mSpriteName = (this.mSprite == null) ? string.Empty : this.mSprite.name; this.mSprite = sp; } }
/// <summary> /// Update the UV coordinates. /// </summary> public override void Update () { base.Update(); if (mChanged || !mSpriteSet) { mSpriteSet = true; mSprite = null; mChanged = true; } }
public virtual void Show() { if (base.enabled && NGUITools.GetActive(base.gameObject) && UIPopupList.mChild == null && this.atlas != null && this.isValid && this.items.Count > 0) { this.mLabelList.Clear(); base.StopCoroutine("CloseIfUnselected"); UICamera.selectedObject = (UICamera.hoveredObject ?? base.gameObject); this.mSelection = UICamera.selectedObject; this.source = UICamera.selectedObject; if (this.source == null) { Debug.LogError("Popup list needs a source object..."); return; } this.mOpenFrame = Time.frameCount; if (this.mPanel == null) { this.mPanel = UIPanel.Find(base.transform); if (this.mPanel == null) { return; } } UIPopupList.mChild = new GameObject("Drop-down List"); UIPopupList.mChild.layer = base.gameObject.layer; UIPopupList.current = this; Transform transform = UIPopupList.mChild.transform; transform.parent = this.mPanel.cachedTransform; Vector3 localPosition; Vector3 vector; Vector3 v; if (this.openOn == UIPopupList.OpenOn.Manual && this.mSelection != base.gameObject) { localPosition = UICamera.lastEventPosition; vector = this.mPanel.cachedTransform.InverseTransformPoint(this.mPanel.anchorCamera.ScreenToWorldPoint(localPosition)); v = vector; transform.localPosition = vector; localPosition = transform.position; } else { Bounds bounds = NGUIMath.CalculateRelativeWidgetBounds(this.mPanel.cachedTransform, base.transform, false, false); vector = bounds.min; v = bounds.max; transform.localPosition = vector; localPosition = transform.position; } base.StartCoroutine("CloseIfUnselected"); transform.localRotation = Quaternion.identity; transform.localScale = Vector3.one; this.mBackground = NGUITools.AddSprite(UIPopupList.mChild, this.atlas, this.backgroundSprite); this.mBackground.pivot = UIWidget.Pivot.TopLeft; this.mBackground.depth = NGUITools.CalculateNextDepth(this.mPanel.gameObject); this.mBackground.color = this.backgroundColor; Vector4 border = this.mBackground.border; this.mBgBorder = border.y; this.mBackground.cachedTransform.localPosition = new Vector3(0f, border.y, 0f); this.mHighlight = NGUITools.AddSprite(UIPopupList.mChild, this.atlas, this.highlightSprite); this.mHighlight.pivot = UIWidget.Pivot.TopLeft; this.mHighlight.color = this.highlightColor; UISpriteData atlasSprite = this.mHighlight.GetAtlasSprite(); if (atlasSprite == null) { return; } float num = (float)atlasSprite.borderTop; float num2 = (float)this.activeFontSize; float activeFontScale = this.activeFontScale; float num3 = num2 * activeFontScale; float num4 = 0f; float num5 = -this.padding.y; List <UILabel> list = new List <UILabel>(); if (!this.items.Contains(this.mSelectedItem)) { this.mSelectedItem = null; } int i = 0; int count = this.items.Count; while (i < count) { string text = this.items[i]; UILabel uilabel = NGUITools.AddWidget <UILabel>(UIPopupList.mChild); uilabel.name = i.ToString(); uilabel.pivot = UIWidget.Pivot.TopLeft; uilabel.bitmapFont = this.bitmapFont; uilabel.trueTypeFont = this.trueTypeFont; uilabel.fontSize = this.fontSize; uilabel.fontStyle = this.fontStyle; string text2 = (!this.isLocalized) ? text : Localization.Get(text); if (this.toUpper) { text2 = text2.ToUpper(); } uilabel.text = text2; uilabel.color = this.textColor; uilabel.cachedTransform.localPosition = new Vector3(border.x + this.padding.x - uilabel.pivotOffset.x, num5, -1f); uilabel.overflowMethod = UILabel.Overflow.ResizeFreely; uilabel.alignment = this.alignment; list.Add(uilabel); num5 -= num3; num5 -= this.padding.y; num4 = Mathf.Max(num4, uilabel.printedSize.x); UIEventListener uieventListener = UIEventListener.Get(uilabel.gameObject); uieventListener.onHover = new UIEventListener.BoolDelegate(this.OnItemHover); uieventListener.onPress = new UIEventListener.BoolDelegate(this.OnItemPress); uieventListener.parameter = text; if (this.mSelectedItem == text || (i == 0 && string.IsNullOrEmpty(this.mSelectedItem))) { this.Highlight(uilabel, true); } this.mLabelList.Add(uilabel); i++; } num4 = Mathf.Max(num4, v.x - vector.x - (border.x + this.padding.x) * 2f); float num6 = num4; Vector3 vector2 = new Vector3(num6 * 0.5f, -num3 * 0.5f, 0f); Vector3 vector3 = new Vector3(num6, num3 + this.padding.y, 1f); int j = 0; int count2 = list.Count; while (j < count2) { UILabel uilabel2 = list[j]; NGUITools.AddWidgetCollider(uilabel2.gameObject); uilabel2.autoResizeBoxCollider = false; BoxCollider component = uilabel2.GetComponent <BoxCollider>(); if (component != null) { vector2.z = component.center.z; component.center = vector2; component.size = vector3; } else { BoxCollider2D component2 = uilabel2.GetComponent <BoxCollider2D>(); component2.offset = vector2; component2.size = vector3; } j++; } int width = Mathf.RoundToInt(num4); num4 += (border.x + this.padding.x) * 2f; num5 -= border.y; this.mBackground.width = Mathf.RoundToInt(num4); this.mBackground.height = Mathf.RoundToInt(-num5 + border.y); int k = 0; int count3 = list.Count; while (k < count3) { UILabel uilabel3 = list[k]; uilabel3.overflowMethod = UILabel.Overflow.ShrinkContent; uilabel3.width = width; k++; } float num7 = 2f * this.atlas.pixelSize; float f = num4 - (border.x + this.padding.x) * 2f + (float)atlasSprite.borderLeft * num7; float f2 = num3 + num * num7; this.mHighlight.width = Mathf.RoundToInt(f); this.mHighlight.height = Mathf.RoundToInt(f2); bool flag = this.position == UIPopupList.Position.Above; if (this.position == UIPopupList.Position.Auto) { UICamera uicamera = UICamera.FindCameraForLayer(this.mSelection.layer); if (uicamera != null) { flag = (uicamera.cachedCamera.WorldToViewportPoint(localPosition).y < 0.5f); } } if (this.isAnimated) { this.AnimateColor(this.mBackground); if (Time.timeScale == 0f || Time.timeScale >= 0.1f) { float bottom = num5 + num3; this.Animate(this.mHighlight, flag, bottom); int l = 0; int count4 = list.Count; while (l < count4) { this.Animate(list[l], flag, bottom); l++; } this.AnimateScale(this.mBackground, flag, bottom); } } if (flag) { vector.y = v.y - border.y; v.y = vector.y + (float)this.mBackground.height; v.x = vector.x + (float)this.mBackground.width; transform.localPosition = new Vector3(vector.x, v.y - border.y, vector.z); } else { v.y = vector.y + border.y; vector.y = v.y - (float)this.mBackground.height; v.x = vector.x + (float)this.mBackground.width; } Transform parent = this.mPanel.cachedTransform.parent; if (parent != null) { vector = this.mPanel.cachedTransform.TransformPoint(vector); v = this.mPanel.cachedTransform.TransformPoint(v); vector = parent.InverseTransformPoint(vector); v = parent.InverseTransformPoint(v); } Vector3 b = (!this.mPanel.hasClipping) ? this.mPanel.CalculateConstrainOffset(vector, v) : Vector3.zero; localPosition = transform.localPosition + b; localPosition.x = Mathf.Round(localPosition.x); localPosition.y = Mathf.Round(localPosition.y); transform.localPosition = localPosition; } else { this.OnSelect(false); } }
public void doReleaseTexture(string name, bool force) { if (mReplacement != null) { mReplacement.doReleaseTexture(name, force); return; } if (isBorrowSprite) { return; } if (string.IsNullOrEmpty(name)) { return; } int i = spriteMap [name] == null ? -1 : (int)spriteMap [name]; if (i < 0) { return; } UISpriteData sp = mSprites.Count > 1 ? mSprites [i] : null; if (sp == null) { return; } int rc = retainCounter [sp.path] == null ? 0 : (int)retainCounter [sp.path]; if (rc <= 0) { if (!force && sp.lastReturnTime - System.DateTime.Now.ToFileTime() > 0) { if (!releaseTex.Contains(name)) { releaseTex.Enqueue(name); } CancelInvoke("ReleaseTexture"); Invoke("ReleaseTexture", 5); return; } Material mat = materailPool[sp.path] as Material; if (mat != null && mat.mainTexture != null) { try { //================================================= #if UNITY_EDITOR if (Coolape.CLAssetsManager.self != null && !string.IsNullOrEmpty(Coolape.CLAssetsManager.self.debugKey) && sp.path.Contains(Coolape.CLAssetsManager.self.debugKey)) { Debug.LogError("doReleaseTexture====" + sp.path); } #endif //if(!string.IsNullOrEmpty(mat.mainTexture.name)) { // Resources.UnloadAsset (mat.mainTexture); //} // 其它引用了该图的都要释放 for (int j = 0; j < mSprites.Count; j++) { UISpriteData tmpsp = mSprites [j]; if (tmpsp.path == sp.path && tmpsp != sp) { tmpsp.material = null; } } sp.material = null; materailPool[sp.path] = null; mat.mainTexture = null; //DestroyImmediate (mat.mainTexture, true); DestroyImmediate(mat, true); mat = null; AssetBundle ab = assetBundleMap[sp.path] as AssetBundle; if (ab != null) { ab.Unload(true); } assetBundleMap[sp.path] = null; //================================================= } catch (System.Exception e) { Debug.LogError(sp.name + " err:" + e); } } } }
/// <summary> /// Retrieve the atlas sprite referenced by the spriteName field. /// </summary> public UISpriteData GetAtlasSprite () { if (!mSpriteSet) mSprite = null; if (mSprite == null && mAtlas != null) { if (!string.IsNullOrEmpty(mSpriteName)) { UISpriteData sp = mAtlas.GetSprite(mSpriteName); if (sp == null) return null; SetAtlasSprite(sp); } if (mSprite == null && mAtlas.spriteList.Count > 0) { UISpriteData 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; } } return mSprite; }
/// <summary> /// Sprite comparison function for sorting. /// </summary> static int CompareSprites(UISpriteData a, UISpriteData b) { return(a.name.CompareTo(b.name)); }
/// <summary> /// Virtual function called by the UIPanel that fills the buffers. /// </summary> public override void OnFill (BetterList<Vector3> verts, BetterList<Vector2> uvs, BetterList<Color32> cols) { Texture tex = mainTexture; if (tex != null) { if (mSprite == null) mSprite = atlas.GetSprite(spriteName); if (mSprite == null) return; mOuterUV.Set(mSprite.x, mSprite.y, mSprite.width, mSprite.height); mInnerUV.Set(mSprite.x + mSprite.borderLeft, mSprite.y + mSprite.borderTop, mSprite.width - mSprite.borderLeft - mSprite.borderRight, mSprite.height - mSprite.borderBottom - mSprite.borderTop); mOuterUV = NGUIMath.ConvertToTexCoords(mOuterUV, tex.width, tex.height); mInnerUV = NGUIMath.ConvertToTexCoords(mInnerUV, tex.width, tex.height); } switch (type) { case Type.Simple: SimpleFill(verts, uvs, cols); break; case Type.Sliced: SlicedFill(verts, uvs, cols); break; case Type.Filled: FilledFill(verts, uvs, cols); break; case Type.Tiled: TiledFill(verts, uvs, cols); break; } }
/// <summary> /// Parse the specified JSon file, loading sprite information for the specified atlas. /// </summary> static void LoadSpriteData(UIAtlas atlas, Hashtable decodedHash) { if (decodedHash == null || atlas == null) { return; } List <UISpriteData> oldSprites = atlas.spriteList; atlas.spriteList = new List <UISpriteData> (); Hashtable frames = (Hashtable)decodedHash ["frames"]; foreach (System.Collections.DictionaryEntry item in frames) { UISpriteData newSprite = new UISpriteData(); newSprite.name = item.Key.ToString(); bool exists = false; // Check to see if this sprite exists foreach (UISpriteData 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"]; newSprite.x = frameX; newSprite.y = frameY; newSprite.width = frameW; newSprite.height = frameH; // Support for trimmed sprites Hashtable sourceSize = (Hashtable)table ["sourceSize"]; Hashtable spriteSize = (Hashtable)table ["spriteSourceSize"]; if (spriteSize != null && sourceSize != null) { if (frameW > 0) { int spriteX = int.Parse(spriteSize ["x"].ToString()); int spriteW = int.Parse(spriteSize ["w"].ToString()); int sourceW = int.Parse(sourceSize ["w"].ToString()); newSprite.paddingLeft = spriteX; newSprite.paddingRight = sourceW - (spriteX + spriteW); } if (frameH > 0) { int spriteY = int.Parse(spriteSize ["y"].ToString()); int spriteH = int.Parse(spriteSize ["h"].ToString()); int sourceH = int.Parse(sourceSize ["h"].ToString()); newSprite.paddingTop = spriteY; newSprite.paddingBottom = sourceH - (spriteY + spriteH); } } // If the sprite was present before, see if we can copy its inner rect foreach (UISpriteData oldSprite in oldSprites) { if (oldSprite.name.Equals(newSprite.name, StringComparison.OrdinalIgnoreCase)) { newSprite.borderLeft = oldSprite.borderLeft; newSprite.borderRight = oldSprite.borderRight; newSprite.borderBottom = oldSprite.borderBottom; newSprite.borderTop = oldSprite.borderTop; } } // Add this new sprite atlas.spriteList.Add(newSprite); } // Sort imported sprites alphabetically atlas.spriteList.Sort(CompareSprites); Debug.Log("Imported " + atlas.spriteList.Count + " sprites"); }
/// <summary> /// Sprite comparison function for sorting. /// </summary> static int CompareSprites (UISpriteData a, UISpriteData b) { return a.name.CompareTo(b.name); }
/// <summary> /// Draw the inspector widget. /// </summary> public override void OnInspectorGUI() { NGUIEditorTools.SetLabelWidth(80f); mAtlas = target as UIAtlas; UISpriteData sprite = (mAtlas != null) ? mAtlas.GetSprite(NGUISettings.selectedSprite) : null; GUILayout.Space(6f); if (mAtlas.replacement != null) { mType = AtlasType.Reference; mReplacement = mAtlas.replacement; } GUILayout.BeginHorizontal(); AtlasType after = (AtlasType)EditorGUILayout.EnumPopup("Atlas Type", mType); GUILayout.Space(18f); GUILayout.EndHorizontal(); if (mType != after) { if (after == AtlasType.Normal) { mType = AtlasType.Normal; OnSelectAtlas(null); } else { mType = AtlasType.Reference; } } if (mType == AtlasType.Reference) { ComponentSelector.Draw <UIAtlas>(mAtlas.replacement, OnSelectAtlas); GUILayout.Space(6f); 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; } //GUILayout.Space(6f); 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.premultipliedAlpha); } mAtlas.MarkAsDirty(); } 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, !mAtlas.premultipliedAlpha); } NGUIEditorTools.RegisterUndo("Import Sprites", mAtlas); NGUIJson.LoadSpriteData(mAtlas, ta); if (sprite != null) { sprite = mAtlas.GetSprite(sprite.name); } mAtlas.MarkAsDirty(); } float pixelSize = EditorGUILayout.FloatField("Pixel Size", mAtlas.pixelSize, GUILayout.Width(120f)); if (pixelSize != mAtlas.pixelSize) { NGUIEditorTools.RegisterUndo("Atlas Change", mAtlas); mAtlas.pixelSize = pixelSize; } } if (mAtlas.spriteMaterial != null) { Color blue = new Color(0f, 0.7f, 1f, 1f); Color green = new Color(0.4f, 1f, 0f, 1f); if (sprite == null && mAtlas.spriteList.Count > 0) { string spriteName = NGUISettings.selectedSprite; if (!string.IsNullOrEmpty(spriteName)) { sprite = mAtlas.GetSprite(spriteName); } if (sprite == null) { sprite = mAtlas.spriteList[0]; } } if (sprite != null) { if (sprite == null) { return; } Texture2D tex = mAtlas.spriteMaterial.mainTexture as Texture2D; if (tex != null) { if (!NGUIEditorTools.DrawHeader("Sprite Details")) { return; } NGUIEditorTools.BeginContents(); GUILayout.Space(3f); NGUIEditorTools.AdvancedSpriteField(mAtlas, sprite.name, SelectSprite, true); GUILayout.Space(6f); GUI.changed = false; GUI.backgroundColor = green; NGUIEditorTools.IntVector sizeA = NGUIEditorTools.IntPair("Dimensions", "X", "Y", sprite.x, sprite.y); NGUIEditorTools.IntVector sizeB = NGUIEditorTools.IntPair(null, "Width", "Height", sprite.width, sprite.height); EditorGUILayout.Separator(); GUI.backgroundColor = blue; NGUIEditorTools.IntVector borderA = NGUIEditorTools.IntPair("Border", "Left", "Right", sprite.borderLeft, sprite.borderRight); NGUIEditorTools.IntVector borderB = NGUIEditorTools.IntPair(null, "Bottom", "Top", sprite.borderBottom, sprite.borderTop); EditorGUILayout.Separator(); GUI.backgroundColor = Color.white; NGUIEditorTools.IntVector padA = NGUIEditorTools.IntPair("Padding", "Left", "Right", sprite.paddingLeft, sprite.paddingRight); NGUIEditorTools.IntVector padB = NGUIEditorTools.IntPair(null, "Bottom", "Top", sprite.paddingBottom, sprite.paddingTop); if (GUI.changed) { NGUIEditorTools.RegisterUndo("Atlas Change", mAtlas); sprite.x = sizeA.x; sprite.y = sizeA.y; sprite.width = sizeB.x; sprite.height = sizeB.y; sprite.paddingLeft = padA.x; sprite.paddingRight = padA.y; sprite.paddingBottom = padB.x; sprite.paddingTop = padB.y; sprite.borderLeft = borderA.x; sprite.borderRight = borderA.y; sprite.borderBottom = borderB.x; sprite.borderTop = borderB.y; MarkSpriteAsDirty(); } NGUIEditorTools.EndContents(); } if (NGUIEditorTools.previousSelection != null) { GUI.backgroundColor = Color.green; if (GUILayout.Button("<< Return to " + NGUIEditorTools.previousSelection.name)) { NGUIEditorTools.SelectPrevious(); } GUI.backgroundColor = Color.white; } } } }
/// <summary> /// Convenience function that retrieves a sprite by name. /// </summary> public UISpriteData GetSprite(string name) { if (mReplacement != null) { return(mReplacement.GetSprite(name)); } else if (!string.IsNullOrEmpty(name)) { if (mSprites.Count == 0) { Upgrade(); } if (mSprites.Count == 0) { return(null); } // O(1) lookup via a dictionary #if UNITY_EDITOR if (Application.isPlaying) #endif { // The number of indices differs from the sprite list? Rebuild the indices. if (mSpriteIndices.Count != mSprites.Count) { MarkSpriteListAsChanged(); } int index; if (mSpriteIndices.TryGetValue(name, out index)) { // If the sprite is present, return it as-is if (index > -1 && index < mSprites.Count) { return(mSprites[index]); } // The sprite index was out of range -- perhaps the sprite was removed? Rebuild the indices. MarkSpriteListAsChanged(); // Try to look up the index again return(mSpriteIndices.TryGetValue(name, out index) ? mSprites[index] : null); } } // Sequential O(N) lookup. for (int i = 0, imax = mSprites.Count; i < imax; ++i) { UISpriteData s = mSprites[i]; // string.Equals doesn't seem to work with Flash export if (!string.IsNullOrEmpty(s.name) && name == s.name) { #if UNITY_EDITOR if (!Application.isPlaying) { return(s); } #endif // If this point was reached then the sprite is present in the non-indexed list, // so the sprite indices should be updated. MarkSpriteListAsChanged(); return(s); } } } return(null); }
private void OnGUI() { if (!mAtlas) { mAtlas = NGUISettings.atlas; } ComponentSelector.Draw <UIAtlas>("Atlas", mAtlas, obj => { if (mAtlas != obj) { mAtlas = obj as UIAtlas; } }, true, GUILayout.MinWidth(80f)); if (!mAtlas) { mSprites = new string[0]; } else { GUILayout.BeginHorizontal(); GUILayout.Space(5F); EditorGUILayout.BeginVertical(); if (NGUIEditorTools.DrawMinimalisticHeader("Sprites")) { EditorGUILayout.BeginHorizontal(); GUILayout.Space(15F); EditorGUILayout.BeginVertical(); GUILayout.Space(2F); int newLength = EditorGUILayout.IntField("Size", mSprites.Length); int oldLength = mSprites.Length; if (newLength != oldLength) { int minLength = Mathf.Min(newLength, oldLength); string[] sprites = new string[newLength]; for (int i = 0; i < minLength; i++) { sprites[i] = mSprites[i]; } mSprites = sprites; } for (int i = 0; i < mSprites.Length; i++) { int index = i; NGUIEditorTools.DrawAdvancedSpriteField(mAtlas, mSprites[index], spriteName => { mSprites[index] = spriteName; Repaint(); }, false); } GUILayout.Space(2F); EditorGUILayout.EndVertical(); GUILayout.Space(3F); EditorGUILayout.EndHorizontal(); } GUILayout.EndVertical(); GUILayout.EndHorizontal(); GUILayout.Space(10F); } GUILayout.BeginHorizontal(); GUILayout.Space(10F); bool start = GUILayout.Button("Create/Update Materials"); GUILayout.Space(10F); GUILayout.EndHorizontal(); if (start && mAtlas && mSprites.Length > 0) { string atlasPath = AssetDatabase.GetAssetPath(mAtlas); string dirPath = atlasPath.Replace("/UIAtlas/", "/Materials/").Replace(".prefab", "/"); DirectoryInfo dir = new DirectoryInfo(dirPath); if (!dir.Exists) { dir.Create(); } bool anyAssetsChanged = false; UISpriteData[] spriteDatas = new UISpriteData[mSprites.Length]; for (int index = 0; index < mSprites.Length; index++) { string spriteName = mSprites[index]; if (!string.IsNullOrEmpty(spriteName)) { UISpriteData spriteData = mAtlas.GetSprite(spriteName); if (spriteData != null) { string path = dirPath + spriteName + ".mat"; bool exist = File.Exists(path); Material mat = exist ? AssetDatabase.LoadAssetAtPath <Material>(path) : new Material(mAtlas.spriteMaterial); float scaleX = (float)spriteData.width / mAtlas.width; float scaleY = (float)spriteData.height / mAtlas.height; float offsetX = (float)spriteData.x / mAtlas.width; float offsetY = (float)(mAtlas.height - spriteData.y - spriteData.height) / mAtlas.height; mat.SetTextureScale("_MainTex", new Vector2(scaleX, scaleY)); mat.SetTextureOffset("_MainTex", new Vector2(offsetX, offsetY)); if (exist) { anyAssetsChanged = true; } else { AssetDatabase.CreateAsset(mat, path); } } } } if (anyAssetsChanged) { AssetDatabase.SaveAssets(); } } }
/// <summary> /// Add a transparent border around the sprite. /// </summary> void AddTransparentBorder (UISpriteData sprite) { List<UIAtlasMaker.SpriteEntry> sprites = new List<UIAtlasMaker.SpriteEntry>(); UIAtlasMaker.ExtractSprites(mAtlas, sprites); UIAtlasMaker.SpriteEntry se = null; for (int i = 0; i < sprites.Count; ++i) { if (sprites[i].name == sprite.name) { se = sprites[i]; break; } } if (se != null) { int w1 = se.tex.width; int h1 = se.tex.height; int w2 = w1 + 2; int h2 = h1 + 2; Color32[] c1 = se.tex.GetPixels32(); Color32[] c2 = new Color32[w2 * h2]; for (int y2 = 0; y2 < h2; ++y2) { int y1 = NGUIMath.ClampIndex(y2 - 1, h1); for (int x2 = 0; x2 < w2; ++x2) { int x1 = NGUIMath.ClampIndex(x2 - 1, w1); int i2 = x2 + y2 * w2; c2[i2] = c1[x1 + y1 * w1]; if (x2 == 0 || x2 + 1 == w2 || y2 == 0 || y2 + 1 == h2) c2[i2].a = 0; } } if (se.temporaryTexture) DestroyImmediate(se.tex); ++se.borderLeft; ++se.borderRight; ++se.borderTop; ++se.borderBottom; se.tex = new Texture2D(w2, h2); se.tex.name = sprite.name; se.tex.SetPixels32(c2); se.tex.Apply(); se.temporaryTexture = true; UIAtlasMaker.UpdateAtlas(mAtlas, sprites); DestroyImmediate(se.tex); se.tex = null; } }
/// <summary> /// Draw the custom wizard. /// </summary> void OnGUI() { NGUIEditorTools.SetLabelWidth(80f); if (NGUISettings.atlas == null) { GUILayout.Label("No Atlas selected.", "LODLevelNotifyText"); } else { UIAtlas atlas = NGUISettings.atlas; bool close = false; GUILayout.Label(atlas.name + " Sprites", "LODLevelNotifyText"); NGUIEditorTools.DrawSeparator(); GUILayout.BeginHorizontal(); GUILayout.Space(84f); string before = NGUISettings.partialSprite; string after = EditorGUILayout.TextField("", before, "SearchTextField"); if (before != after) { NGUISettings.partialSprite = after; } if (GUILayout.Button("", "SearchCancelButton", GUILayout.Width(18f))) { NGUISettings.partialSprite = ""; GUIUtility.keyboardControl = 0; } GUILayout.Space(84f); GUILayout.EndHorizontal(); Texture2D tex = atlas.texture as Texture2D; if (tex == null) { GUILayout.Label("The atlas doesn't have a texture to work with"); return; } BetterList <string> sprites = atlas.GetListOfSprites(NGUISettings.partialSprite); float size = 80f; float padded = size + 10f; #if UNITY_4_7 int screenWidth = Screen.width; #else int screenWidth = (int)EditorGUIUtility.currentViewWidth; #endif int columns = Mathf.FloorToInt(screenWidth / padded); if (columns < 1) { columns = 1; } int offset = 0; Rect rect = new Rect(10f, 0, size, size); GUILayout.Space(10f); mPos = GUILayout.BeginScrollView(mPos); int rows = 1; while (offset < sprites.size) { GUILayout.BeginHorizontal(); { int col = 0; rect.x = 10f; for (; offset < sprites.size; ++offset) { UISpriteData sprite = atlas.GetSprite(sprites[offset]); if (sprite == null) { continue; } // Button comes first if (GUI.Button(rect, "")) { if (Event.current.button == 0) { float delta = Time.realtimeSinceStartup - mClickTime; mClickTime = Time.realtimeSinceStartup; if (NGUISettings.selectedSprite != sprite.name) { if (mSprite != null) { NGUIEditorTools.RegisterUndo("Atlas Selection", mSprite); mSprite.MakePixelPerfect(); EditorUtility.SetDirty(mSprite.gameObject); } NGUISettings.selectedSprite = sprite.name; NGUIEditorTools.RepaintSprites(); if (mCallback != null) { mCallback(sprite.name); } } else if (delta < 0.5f) { close = true; } } else { NGUIContextMenu.AddItem("Edit", false, EditSprite, sprite); NGUIContextMenu.AddItem("Delete", false, DeleteSprite, sprite); NGUIContextMenu.Show(); } } if (Event.current.type == EventType.Repaint) { // On top of the button we have a checkboard grid NGUIEditorTools.DrawTiledTexture(rect, NGUIEditorTools.backdropTexture); Rect uv = new Rect(sprite.x, sprite.y, sprite.width, sprite.height); 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 (NGUISettings.selectedSprite == sprite.name) { NGUIEditorTools.DrawOutline(rect, new Color(0.4f, 1f, 0f, 1f)); } } GUI.backgroundColor = new Color(1f, 1f, 1f, 0.5f); GUI.contentColor = new Color(1f, 1f, 1f, 0.7f); GUI.Label(new Rect(rect.x, rect.y + rect.height, rect.width, 32f), sprite.name, "ProgressBarBack"); GUI.contentColor = Color.white; GUI.backgroundColor = Color.white; if (++col >= columns) { ++offset; break; } rect.x += padded; } } GUILayout.EndHorizontal(); GUILayout.Space(padded); rect.y += padded + 26; ++rows; } GUILayout.Space(rows * 26); GUILayout.EndScrollView(); if (close) { Close(); } } }
public static int UISpriteData(IntPtr L) { UISpriteData ret = new UISpriteData( ); LuaStatic.addGameObject2Lua(L,ret,"UISpriteData"); return 1; }
/// <summary> /// Progress bar creation function. /// </summary> void CreateSlider(GameObject go, bool slider) { if (NGUISettings.atlas != null) { NGUIEditorTools.DrawSpriteField("Empty", "Sprite for the background (empty bar)", NGUISettings.atlas, mSliderBG, OnSliderBG, GUILayout.Width(120f)); NGUIEditorTools.DrawSpriteField("Full", "Sprite for the foreground (full bar)", NGUISettings.atlas, mSliderFG, OnSliderFG, GUILayout.Width(120f)); if (slider) { NGUIEditorTools.DrawSpriteField("Thumb", "Sprite for the thumb indicator", NGUISettings.atlas, mSliderTB, OnSliderTB, GUILayout.Width(120f)); } } if (ShouldCreate(go, NGUISettings.atlas != null)) { int depth = NGUITools.CalculateNextDepth(go); go = NGUITools.AddChild(go); go.name = slider ? "Slider" : "Progress Bar"; // Background sprite UISpriteData bgs = NGUISettings.atlas.GetSprite(mSliderBG); UISprite back = (UISprite)NGUITools.AddWidget <UISprite>(go); back.type = bgs.hasBorder ? UISprite.Type.Sliced : UISprite.Type.Simple; back.name = "Background"; back.depth = depth; back.pivot = UIWidget.Pivot.Left; back.atlas = NGUISettings.atlas; back.spriteName = mSliderBG; back.width = 200; back.height = 30; back.transform.localPosition = Vector3.zero; back.MakePixelPerfect(); // Foreground sprite UISpriteData fgs = NGUISettings.atlas.GetSprite(mSliderFG); UISprite front = NGUITools.AddWidget <UISprite>(go); front.type = fgs.hasBorder ? UISprite.Type.Sliced : UISprite.Type.Simple; front.name = "Foreground"; front.pivot = UIWidget.Pivot.Left; front.atlas = NGUISettings.atlas; front.spriteName = mSliderFG; front.width = 200; front.height = 30; 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.foregroundWidget = front; // Thumb sprite if (slider) { UISpriteData tbs = NGUISettings.atlas.GetSprite(mSliderTB); UISprite thb = NGUITools.AddWidget <UISprite>(go); thb.type = tbs.hasBorder ? UISprite.Type.Sliced : UISprite.Type.Simple; thb.name = "Thumb"; thb.atlas = NGUISettings.atlas; thb.spriteName = mSliderTB; thb.width = 20; thb.height = 40; thb.transform.localPosition = new Vector3(200f, 0f, 0f); thb.MakePixelPerfect(); NGUITools.AddWidgetCollider(thb.gameObject); thb.gameObject.AddComponent <UIButtonColor>(); thb.gameObject.AddComponent <UIButtonScale>(); uiSlider.thumb = thb.transform; } uiSlider.value = 1f; // Select the slider Selection.activeGameObject = go; } }
/// <summary> /// Extract the specified sprite from the atlas texture. /// </summary> static SpriteEntry ExtractSprite (UISpriteData es, Texture2D tex) { return (tex != null) ? ExtractSprite(es, tex.GetPixels32(), tex.width, tex.height) : null; }
/// <summary> /// Create a popup list or a menu. /// </summary> void CreatePopup(GameObject go, bool isDropDown) { if (NGUISettings.atlas != null) { NGUIEditorTools.DrawSpriteField("Foreground", "Foreground sprite (shown on the button)", NGUISettings.atlas, mListFG, OnListFG, GUILayout.Width(120f)); NGUIEditorTools.DrawSpriteField("Background", "Background sprite (envelops the options)", NGUISettings.atlas, mListBG, OnListBG, GUILayout.Width(120f)); NGUIEditorTools.DrawSpriteField("Highlight", "Sprite used to highlight the selected option", NGUISettings.atlas, mListHL, OnListHL, GUILayout.Width(120f)); } if (ShouldCreate(go, NGUISettings.atlas != null && NGUISettings.ambigiousFont != null)) { int depth = NGUITools.CalculateNextDepth(go); go = NGUITools.AddChild(go); go.name = isDropDown ? "Popup List" : "Popup Menu"; UISpriteData sphl = NGUISettings.atlas.GetSprite(mListHL); UISpriteData spfg = NGUISettings.atlas.GetSprite(mListFG); Vector2 hlPadding = new Vector2(Mathf.Max(4f, sphl.paddingLeft), Mathf.Max(4f, sphl.paddingTop)); Vector2 fgPadding = new Vector2(Mathf.Max(4f, spfg.paddingLeft), Mathf.Max(4f, spfg.paddingTop)); // Background sprite UISprite sprite = NGUITools.AddSprite(go, NGUISettings.atlas, mListFG); sprite.depth = depth; sprite.atlas = NGUISettings.atlas; sprite.pivot = UIWidget.Pivot.Left; sprite.width = Mathf.RoundToInt(150f + fgPadding.x * 2f); sprite.height = Mathf.RoundToInt(NGUISettings.fontSize + fgPadding.y * 2f); sprite.transform.localPosition = Vector3.zero; sprite.MakePixelPerfect(); // Text label UILabel lbl = NGUITools.AddWidget <UILabel>(go); lbl.ambigiousFont = NGUISettings.ambigiousFont; lbl.fontSize = NGUISettings.fontSize; lbl.fontStyle = NGUISettings.fontStyle; lbl.text = go.name; lbl.pivot = UIWidget.Pivot.Left; lbl.cachedTransform.localPosition = new Vector3(fgPadding.x, 0f, 0f); lbl.AssumeNaturalSize(); // Add a collider NGUITools.AddWidgetCollider(go); // Add the popup list UIPopupList list = go.AddComponent <UIPopupList>(); list.atlas = NGUISettings.atlas; list.ambigiousFont = NGUISettings.ambigiousFont; list.fontSize = NGUISettings.fontSize; list.fontStyle = NGUISettings.fontStyle; list.backgroundSprite = mListBG; list.highlightSprite = mListHL; list.padding = hlPadding; if (isDropDown) { EventDelegate.Add(list.onChange, lbl.SetCurrentSelection); } 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 <UIPlaySound>(); Selection.activeGameObject = go; } }
/// <summary> /// Performs an upgrade from the legacy way of specifying data to the new one. /// </summary> bool Upgrade() { if (mSprites.Count == 0 && sprites.Count > 0) { Texture tex = material.mainTexture; int width = (tex != null) ? tex.width : 512; int height = (tex != null) ? tex.height : 512; for (int i = 0; i < sprites.Count; ++i) { Sprite old = sprites[i]; Rect outer = old.outer; Rect inner = old.inner; if (mCoordinates == Coordinates.TexCoords) { NGUIMath.ConvertToPixels(outer, width, height, true); NGUIMath.ConvertToPixels(inner, width, height, true); } UISpriteData sd = new UISpriteData(); sd.name = old.name; sd.x = Mathf.RoundToInt(outer.xMin); sd.y = Mathf.RoundToInt(outer.yMin); sd.width = Mathf.RoundToInt(outer.width); sd.height = Mathf.RoundToInt(outer.height); sd.paddingLeft = Mathf.RoundToInt(old.paddingLeft * outer.width); sd.paddingRight = Mathf.RoundToInt(old.paddingRight * outer.width); sd.paddingBottom = Mathf.RoundToInt(old.paddingBottom * outer.height); sd.paddingTop = Mathf.RoundToInt(old.paddingTop * outer.height); sd.borderLeft = Mathf.RoundToInt(inner.xMin - outer.xMin); sd.borderRight = Mathf.RoundToInt(outer.xMax - inner.xMax); sd.borderBottom = Mathf.RoundToInt(inner.yMin - outer.yMin); sd.borderTop = Mathf.RoundToInt(outer.yMax - inner.yMax); mSprites.Add(sd); } sprites.Clear(); #if UNITY_EDITOR UnityEditor.EditorUtility.SetDirty(this); UnityEditor.AssetDatabase.SaveAssets(); #endif return true; } return false; }
/// <summary> /// Show the popup list dialog. /// </summary> public void Show() { if (enabled && NGUITools.GetActive(gameObject) && mChild == null && atlas != null && isValid && items.Count > 0) { mLabelList.Clear(); StopCoroutine("CloseIfUnselected"); // Ensure the popup's source has the selection UICamera.selectedObject = (UICamera.hoveredObject ?? gameObject); mSelection = UICamera.selectedObject; source = UICamera.selectedObject; if (source == null) { Debug.LogError("Popup list needs a source object..."); return; } mOpenFrame = Time.frameCount; // Automatically locate the panel responsible for this object if (mPanel == null) { mPanel = UIPanel.Find(transform); if (mPanel == null) { return; } } // Calculate the dimensions of the object triggering the popup list so we can position it below it Vector3 min; Vector3 max; // Create the root object for the list mChild = new GameObject("Drop-down List"); mChild.layer = gameObject.layer; if (separatePanel) { if (GetComponent <Collider>() != null) { Rigidbody rb = mChild.AddComponent <Rigidbody>(); rb.isKinematic = true; } else if (GetComponent <Collider2D>() != null) { Rigidbody2D rb = mChild.AddComponent <Rigidbody2D>(); rb.isKinematic = true; } mChild.AddComponent <UIPanel>().depth = 1000000; } current = this; Transform t = mChild.transform; t.parent = mPanel.cachedTransform; Vector3 pos; // Manually triggered popup list on some other game object if (openOn == OpenOn.Manual && mSelection != gameObject) { pos = UICamera.lastEventPosition; min = mPanel.cachedTransform.InverseTransformPoint(mPanel.anchorCamera.ScreenToWorldPoint(pos)); max = min; t.localPosition = min; pos = t.position; } else { Bounds bounds = NGUIMath.CalculateRelativeWidgetBounds(mPanel.cachedTransform, transform, false, false); min = bounds.min; max = bounds.max; t.localPosition = min; pos = t.position; } StartCoroutine("CloseIfUnselected"); t.localRotation = Quaternion.identity; t.localScale = Vector3.one; // Add a sprite for the background mBackground = NGUITools.AddSprite(mChild, atlas, backgroundSprite, separatePanel ? 0 : NGUITools.CalculateNextDepth(mPanel.gameObject)); mBackground.pivot = UIWidget.Pivot.TopLeft; 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, mBackground.depth + 1); mHighlight.pivot = UIWidget.Pivot.TopLeft; mHighlight.color = highlightColor; UISpriteData hlsp = mHighlight.GetAtlasSprite(); if (hlsp == null) { return; } float hlspHeight = hlsp.borderTop; float fontHeight = activeFontSize; float dynScale = activeFontScale; float labelHeight = fontHeight * dynScale; float x = 0f, y = -padding.y; List <UILabel> labels = new List <UILabel>(); // Clear the selection if it's no longer present if (!items.Contains(mSelectedItem)) { mSelectedItem = null; } // 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, mBackground.depth + 2); lbl.name = i.ToString(); lbl.pivot = UIWidget.Pivot.TopLeft; lbl.bitmapFont = bitmapFont; lbl.trueTypeFont = trueTypeFont; lbl.fontSize = fontSize; lbl.fontStyle = fontStyle; lbl.text = isLocalized ? Localization.Get(s) : s; lbl.color = textColor; lbl.cachedTransform.localPosition = new Vector3(bgPadding.x + padding.x - lbl.pivotOffset.x, y, -1f); lbl.overflowMethod = UILabel.Overflow.ResizeFreely; lbl.alignment = alignment; labels.Add(lbl); y -= labelHeight; y -= padding.y; x = Mathf.Max(x, lbl.printedSize.x); // 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 || (i == 0 && string.IsNullOrEmpty(mSelectedItem))) { 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, (max.x - min.x) - (bgPadding.x + padding.x) * 2f); float cx = x; Vector3 bcCenter = new Vector3(cx * 0.5f, -labelHeight * 0.5f, 0f); Vector3 bcSize = new Vector3(cx, (labelHeight + padding.y), 1f); // Run through all labels and add colliders for (int i = 0, imax = labels.Count; i < imax; ++i) { UILabel lbl = labels[i]; NGUITools.AddWidgetCollider(lbl.gameObject); lbl.autoResizeBoxCollider = false; BoxCollider bc = lbl.GetComponent <BoxCollider>(); if (bc != null) { bcCenter.z = bc.center.z; bc.center = bcCenter; bc.size = bcSize; } else { BoxCollider2D b2d = lbl.GetComponent <BoxCollider2D>(); #if UNITY_4_3 || UNITY_4_5 || UNITY_4_6 b2d.center = bcCenter; #else b2d.offset = bcCenter; #endif b2d.size = bcSize; } } int lblWidth = Mathf.RoundToInt(x); x += (bgPadding.x + padding.x) * 2f; y -= bgPadding.y; // Scale the background sprite to envelop the entire set of items mBackground.width = Mathf.RoundToInt(x); mBackground.height = Mathf.RoundToInt(-y + bgPadding.y); // Set the label width to make alignment work for (int i = 0, imax = labels.Count; i < imax; ++i) { UILabel lbl = labels[i]; lbl.overflowMethod = UILabel.Overflow.ShrinkContent; lbl.width = lblWidth; } // Scale the highlight sprite to envelop a single item float scaleFactor = 2f * atlas.pixelSize; float w = x - (bgPadding.x + padding.x) * 2f + hlsp.borderLeft * scaleFactor; float h = labelHeight + hlspHeight * scaleFactor; mHighlight.width = Mathf.RoundToInt(w); mHighlight.height = Mathf.RoundToInt(h); bool placeAbove = (position == Position.Above); if (position == Position.Auto) { UICamera cam = UICamera.FindCameraForLayer(mSelection.layer); if (cam != null) { Vector3 viewPos = cam.cachedCamera.WorldToViewportPoint(pos); placeAbove = (viewPos.y < 0.5f); } } // If the list should be animated, let's animate it by expanding it if (isAnimated) { AnimateColor(mBackground); if (Time.timeScale == 0f || Time.timeScale >= 0.1f) { float bottom = y + labelHeight; Animate(mHighlight, placeAbove, bottom); for (int i = 0, imax = labels.Count; i < imax; ++i) { Animate(labels[i], placeAbove, bottom); } 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) { min.y = max.y - bgPadding.y; max.y = min.y + mBackground.height; max.x = min.x + mBackground.width; t.localPosition = new Vector3(min.x, max.y - bgPadding.y, min.z); } else { max.y = min.y + bgPadding.y; min.y = max.y - mBackground.height; max.x = min.x + mBackground.width; } Transform pt = mPanel.cachedTransform.parent; if (pt != null) { min = mPanel.cachedTransform.TransformPoint(min); max = mPanel.cachedTransform.TransformPoint(max); min = pt.InverseTransformPoint(min); max = pt.InverseTransformPoint(max); } // Ensure that everything fits into the panel's visible range Vector3 offset = mPanel.hasClipping ? Vector3.zero : mPanel.CalculateConstrainOffset(min, max); pos = t.localPosition + offset; pos.x = Mathf.Round(pos.x); pos.y = Mathf.Round(pos.y); t.localPosition = pos; } else { OnSelect(false); } }
/// <summary> /// Crop the border pixels around the sprite. /// </summary> void CropBorder (UISpriteData sprite) { List<UIAtlasMaker.SpriteEntry> sprites = new List<UIAtlasMaker.SpriteEntry>(); UIAtlasMaker.ExtractSprites(mAtlas, sprites); UIAtlasMaker.SpriteEntry se = null; for (int i = 0; i < sprites.Count; ++i) { if (sprites[i].name == sprite.name) { se = sprites[i]; break; } } if (se != null) { int w1 = se.tex.width; int h1 = se.tex.height; int w2 = w1 - se.borderLeft - se.borderRight; int h2 = h1 - se.borderTop - se.borderBottom; Color32[] c1 = se.tex.GetPixels32(); Color32[] c2 = new Color32[w2 * h2]; for (int y2 = 0; y2 < h2; ++y2) { int y1 = y2 + se.borderBottom; for (int x2 = 0; x2 < w2; ++x2) { int x1 = x2 + se.borderLeft; c2[x2 + y2 * w2] = c1[x1 + y1 * w1]; } } se.borderLeft = 0; se.borderRight = 0; se.borderTop = 0; se.borderBottom = 0; if (se.temporaryTexture) DestroyImmediate(se.tex); se.tex = new Texture2D(w2, h2); se.tex.name = sprite.name; se.tex.SetPixels32(c2); se.tex.Apply(); se.temporaryTexture = true; UIAtlasMaker.UpdateAtlas(mAtlas, sprites); DestroyImmediate(se.tex); se.tex = null; } }
/// <summary> /// Convenience function that retrieves a list of all sprite names that contain the specified phrase /// </summary> public BetterList <string> GetListOfSprites(string match) { if (mReplacement) { return(mReplacement.GetListOfSprites(match)); } if (string.IsNullOrEmpty(match)) { return(GetListOfSprites()); } if (mSprites.Count == 0) { Upgrade(); } BetterList <string> list = new BetterList <string>(); // First try to find an exact match for (int i = 0, imax = mSprites.Count; i < imax; ++i) { UISpriteData s = mSprites[i]; if (s != null && !string.IsNullOrEmpty(s.name) && string.Equals(match, s.name, StringComparison.OrdinalIgnoreCase)) { list.Add(s.name); return(list); } } // No exact match found? Split up the search into space-separated components. string[] keywords = match.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); for (int i = 0; i < keywords.Length; ++i) { keywords[i] = keywords[i].ToLower(); } // Try to find all sprites where all keywords are present for (int i = 0, imax = mSprites.Count; i < imax; ++i) { UISpriteData s = mSprites[i]; if (s != null && !string.IsNullOrEmpty(s.name)) { string tl = s.name.ToLower(); int matches = 0; for (int b = 0; b < keywords.Length; ++b) { if (tl.Contains(keywords[b])) { ++matches; } } if (matches == keywords.Length) { list.Add(s.name); } } } return(list); }
/// <summary> /// Refresh all labels that use this font. /// </summary> public void MarkAsChanged () { #if UNITY_EDITOR NGUITools.SetDirty(gameObject); #endif if (mReplacement != null) mReplacement.MarkAsChanged(); 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.bitmapFont)) { UIFont fnt = lbl.bitmapFont; lbl.bitmapFont = null; lbl.bitmapFont = fnt; } } // Clear all symbols for (int i = 0, imax = symbols.Count; i < imax; ++i) symbols[i].MarkAsChanged(); }
/// <summary> /// Set the atlas sprite directly. /// </summary> public void SetSprite(UISpriteData sp) { SetAtlasSprite(sp); }