版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_26999509/article/details/81570904
NGUI UISprite预览图Preview拓展
功能说明
1、拓展UISprite的Preview视图,同时显示UIAtlas Texture和Sprite
2、支持在UIAtlas上直接点选Sprite
3、无需打开Atlas选择框和Sprite选择框两步操作
Gif示意图
逻辑介绍
1、找到UISpriteInspector脚本,其脚本的OnPreView函数逻辑,源码如下:
public override void OnPreviewGUI (Rect rect, GUIStyle background)
{
UISprite sprite = target as UISprite;
if (sprite == null || !sprite.isValid) return;
Texture2D tex = sprite.mainTexture as Texture2D;
if (tex == null) return;
UISpriteData sd = sprite.atlas.GetSprite(sprite.spriteName);
NGUIEditorTools.DrawSprite(tex, rect, sd, sprite.color);
}
其中NGUIEditorTools.DrawSprite函数负责绘制Sprite,包括背景、border line、out line、size label等,如下图所示:
2、PreView区域为左右两边,分别绘制Atlas Texture和Sprite,并且Atlas Texture在绘制时依然采用sprite的绘制样式,底图背景 + 黑色轮廓,再次基础上使用的Sprite采用绿色轮廓
public override void OnPreviewGUI (Rect rect, GUIStyle background)
{
UISprite sprite = target as UISprite;
if (sprite == null || !sprite.isValid) return;
Texture2D tex = sprite.mainTexture as Texture2D;
if (tex == null) return;
float interval = 10f;
float width = (rect.width - interval) / 2;
Rect leftRect = new Rect(rect.x,rect.y,width,rect.height);
Rect rightRect = new Rect(rect.x + width + interval,rect.y,width,rect.height);
UISpriteData sd = sprite.atlas.GetSprite(sprite.spriteName);
NGUIEditorTools.DrawAtlas(tex,leftRect,sd);
NGUIEditorTools.DrawSprite(tex, rightRect, sd, sprite.color);
}
static public void DrawAtlas(Texture2D tex,Rect drawRect,UISpriteData sprite)
{
if (!tex) return;
// Create the texture rectangle that is centered inside rect.
Rect outerRect = drawRect;
outerRect.width = tex.width;
outerRect.height = tex.height;
if (tex.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);
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));
if(sprite != null)
{
Handles.color = Color.green;
Rect spriteOutlineRect = outerRect;
float r = outerRect.width / tex.width;
spriteOutlineRect.x = outerRect.xMin + sprite.x * r;
spriteOutlineRect.y = outerRect.yMin + sprite.y * r;
spriteOutlineRect.width = sprite.width * r;
spriteOutlineRect.height = sprite.height * r;
Handles.DrawLine(new Vector3(spriteOutlineRect.xMin, spriteOutlineRect.yMin), new Vector3(spriteOutlineRect.xMin, spriteOutlineRect.yMax));
Handles.DrawLine(new Vector3(spriteOutlineRect.xMax, spriteOutlineRect.yMin), new Vector3(spriteOutlineRect.xMax, spriteOutlineRect.yMax));
Handles.DrawLine(new Vector3(spriteOutlineRect.xMin, spriteOutlineRect.yMin), new Vector3(spriteOutlineRect.xMax, spriteOutlineRect.yMin));
Handles.DrawLine(new Vector3(spriteOutlineRect.xMin, spriteOutlineRect.yMax), new Vector3(spriteOutlineRect.xMax, spriteOutlineRect.yMax));
}
Rect uv = new Rect(0, 0, tex.width, tex.height);
uv = NGUIMath.ConvertToTexCoords(uv, tex.width, tex.height);
GUI.DrawTextureWithTexCoords(outerRect, tex, uv, true);
// Sprite size label
string text = string.Format("Atlas Size: {0}x{1}", Mathf.RoundToInt(tex.width), Mathf.RoundToInt(tex.height));
EditorGUI.DropShadowLabel(GUILayoutUtility.GetRect(Screen.width, 18f), text);
}
示意图如下:
3、点选功能实现
public override void OnPreviewGUI (Rect rect, GUIStyle background)
{
UISprite sprite = target as UISprite;
if (sprite == null || !sprite.isValid) return;
Texture2D tex = sprite.mainTexture as Texture2D;
if (tex == null) return;
float interval = 10f;
float width = (rect.width - interval) / 2;
Rect leftRect = new Rect(rect.x,rect.y,width,rect.height);
Rect rightRect = new Rect(rect.x + width + interval,rect.y,width,rect.height);
UISpriteData sd = sprite.atlas.GetSprite(sprite.spriteName);
NGUIEditorTools.DrawAtlas(tex,leftRect,sd);
NGUIEditorTools.DrawSprite(tex, rightRect, sd, sprite.color);
//点选图片
Event e = Event.current;
if(e.type == EventType.MouseDown)
{
//下面函数通过点击的坐标,和texture、texture draw rect等信息计算出被点选的sprite
UISpriteData click = NGUIEditorTools.GetUISpriteData(tex,sprite.atlas,leftRect,e.mousePosition);
if(click != null)
{
sprite.spriteName = click.name;
EditorUtility.SetDirty(sprite);
}
}
}
//获取sprite在preview中的区域
static public Rect GetAreaInPreview(Texture2D tex,Rect drawRect,UISpriteData sprite)
{
// Create the texture rectangle that is centered inside rect.
Rect outerRect = drawRect;
outerRect.width = tex.width;
outerRect.height = tex.height;
if (tex.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 spriteOutlineRect = outerRect;
float r = outerRect.width / tex.width;
spriteOutlineRect.x = outerRect.xMin + sprite.x * r;
spriteOutlineRect.y = outerRect.yMin + sprite.y * r;
spriteOutlineRect.width = sprite.width * r;
spriteOutlineRect.height = sprite.height * r;
return spriteOutlineRect;
}
//根据点击的坐标,循环遍历出哪个Sprite的Area包含了该pos即可
static public UISpriteData GetUISpriteData(Texture2D tex, UIAtlas atlas,Rect drawRect,Vector2 pos)
{
List<UISpriteData> sprites = atlas.spriteList;
if(sprites == null || sprites.Count <= 0) return null;
for (int i = 0; i < sprites.Count; i++)
{
UISpriteData sprite = sprites[i];
Rect area = GetAreaInPreview(tex,drawRect,sprite);
if(area.Contains(pos))
{
return sprite;
}
}
return null;
}
以上知识分享,如有错误,欢迎指出,共同学习,共同进步。