在这个酒香也怕巷子深,游戏不打广告不买用户不刷榜就会死的时代。每个游戏代理都想让CP提供的安装包越小越好,能99M绝对不要100M。但是游戏开发商们在一遍一遍踢出无用的资源,一点一点得把游戏包扣小,发现大小还是减不下来,该怎么办,这时只有拿美术资源开刀了。
我们来看下面两张图片,是从暗黑战神中抠出来的。 转自http://blog.csdn.net/huutu http://www.thisisgame.com.cn
(PS:从解包安装包分析,暗黑战神已经用了此文所说的二分优化方法)
转自http://blog.csdn.net/huutu http://www.thisisgame.com.cn
(PS:此图本只有一半,是我自己拼上了另外一半)
仔细看便会发现: 转自http://blog.csdn.net/huutu http://www.thisisgame.com.cn
第一张图其实只要左上角 四分之一 就可以了,其它三部分可以复制然后反转就可以得到。
第二张图其实只要左边一半就可以了,右边同样可以复制然后Y轴旋转得到。
转自http://blog.csdn.net/huutu http://www.thisisgame.com.cn
那我们这样做,能节约很多资源吗?
第一张图大小为: 133KB ,四分之一大小的图为:32KB。
第二张图大小为:216KB,一半大小为:56KB(坑爹呢,保存的时候分辨率不一样)
还不错哟!
我们在使用NGUI时,对于UISprite ,可以有多种填充方式,Simple、Tiled、Slice等,Tiled是让一张图片重复的显示去充满设置的屏幕大小。
这和我们的目的很接近,于是我们试一下Tiled。
好像不太符合我们的要求呀。
好,那我们就动手修改NGUI 的UISprite 脚本吧。
打开UISprite.cs 首先我们来最常用的看Simple ,是如何把图片显示在屏幕上的。然后我们自己仿照Simple的流程来添加自己的图片显示方式。
首先我们在UISprite中搜索Simple、找到有一个枚举Type。
public enum Type { Simple, Sliced, Tiled, Filled, Advanced, Quarter, Half, }
应该是在这里定义了Type.Simple,所以我们在UISprite上面才可以选择Simple。尝试添加Quarter(四分图)、Half(二分图)。然后返回Unity查看,添加成功如下图。
然后顺着 Sample搜索到一个Switch Case ,是Type选择的处理函数,我们添加上Quarter、Half的处理函数。
protected void Fill (BetterList<Vector3> verts, BetterList<Vector2> uvs, BetterList<Color32> cols, Rect outer, Rect inner) { mOuterUV = outer; mInnerUV = inner; 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; case Type.Advanced: AdvancedFill(verts, uvs, cols); break; case Type.Quarter: QuarterFill(verts, uvs, cols); break; case Type.Half: HalfFill(verts, uvs, cols); break; } }
然后我们来看Sample这一种图片显示方式的处理代码。
/// <summary> /// Regular sprite fill function is quite simple. /// </summary> void SimpleFill (BetterList<Vector3> verts, BetterList<Vector2> uvs, BetterList<Color32> cols) { Vector4 v = drawingDimensions; //范围,即编辑器中UISprite的方框 Rect。 Vector4 u = drawingUVs; //UV,即选中图片在图集中的位置。 Color32 c = drawingColor; //在编辑器中设置的颜色 ColorTint。 verts.Add(new Vector3(v.x, v.y)); verts.Add(new Vector3(v.x, v.w)); verts.Add(new Vector3(v.z, v.w)); verts.Add(new Vector3(v.z, v.y)); uvs.Add(new Vector2(u.x, u.y)); uvs.Add(new Vector2(u.x, u.w)); uvs.Add(new Vector2(u.z, u.w)); uvs.Add(new Vector2(u.z, u.y)); cols.Add(c); cols.Add(c); cols.Add(c); cols.Add(c); }
这一段代码做了什么呢?
首先添加了四个顶点,然后把纹理通过UV映射到这四个顶点形成的面上,就像给一张桌子铺上桌布一样。
我们来看下面两个坐标。
转自http://blog.csdn.net/huutu http://www.thisisgame.com.cn
顶点坐标以实际坐标为数值,纹理坐标以(0,1)为数值。
顶点坐标图中的方框,就是我们给UISprite设置的显示范围,纹理坐标中的方框,就是我们的纹理坐标。
Sample 这一种方式做的是:
把纹理坐标的1、2、3、4和顶点坐标的1、2、3、4对应起来,即把图片平铺到指定的范围。
那么现在来看我们的四分图。
取图一的左上角四分之一,对应到纹理坐标中。然后我们就把这四分之一的图,平铺到左边顶点坐标的左上角,然后平铺到右上角,右下角、左下角。
我们需要做什么?转自http://blog.csdn.net/huutu http://www.thisisgame.com.cn
我们需要做的是,计算左上角那一块区域的坐标。
首先原来的顶点1要向上移动一半,然后顶点3要向左移动一半,然后顶点4要移动到原点。
具体的过程就到代码中实现吧。
/// <summary> /// 四分图手法; /// </summary> /// <param name="verts"></param> /// <param name="uvs"></param> /// <param name="cols"></param> protected void QuarterFill(BetterList<Vector3> verts, BetterList<Vector2> uvs, BetterList<Color32> cols) { Vector4 v = drawingDimensions; Vector4 u = drawingUVs; Color32 c = drawingColor; Debug.LogError("QuarterFill drawingDimensions=" + drawingDimensions); Debug.LogError("QuarterFill drawingUVs=" + drawingUVs); //计算宽高; float width = v.z - v.x; float height = v.w - v.y; Debug.Log("QuarterFill width=" + width + " height=" + height); //左上角顶点; verts.Add(new Vector3(v.x, v.y+height/2)); verts.Add(new Vector3(v.x, v.w)); verts.Add(new Vector3(v.z - width / 2, v.w)); verts.Add(new Vector3(v.z - width / 2, v.y+height/2)); uvs.Add(new Vector2(u.x, u.y)); uvs.Add(new Vector2(u.x, u.w)); uvs.Add(new Vector2(u.z, u.w)); uvs.Add(new Vector2(u.z, u.y)); cols.Add(c); cols.Add(c); cols.Add(c); cols.Add(c); //左下角顶点; verts.Add(new Vector3(v.x, v.y)); verts.Add(new Vector3(v.x, v.w - height / 2)); verts.Add(new Vector3(v.z - width / 2, v.w - height / 2)); verts.Add(new Vector3(v.z - width / 2, v.y)); //绕X轴反转坐标 1和2交换 3和4交换; uvs.Add(new Vector2(u.x, u.w)); uvs.Add(new Vector2(u.x, u.y)); uvs.Add(new Vector2(u.z, u.y)); uvs.Add(new Vector2(u.z, u.w)); cols.Add(c); cols.Add(c); cols.Add(c); cols.Add(c); //右下角顶点; verts.Add(new Vector3(v.x+width/2, v.y)); verts.Add(new Vector3(v.x+width/2, v.w-height/2)); verts.Add(new Vector3(v.z, v.w-height/2)); verts.Add(new Vector3(v.z, v.y)); //将左下角UV绕Y轴旋转 1和4交换 2和3交换; uvs.Add(new Vector2(u.z, u.w)); uvs.Add(new Vector2(u.z, u.y)); uvs.Add(new Vector2(u.x, u.y)); uvs.Add(new Vector2(u.x, u.w)); cols.Add(c); cols.Add(c); cols.Add(c); cols.Add(c); //右上角顶点; verts.Add(new Vector3(v.x+width/2, v.y + height / 2)); verts.Add(new Vector3(v.x+width/2, v.w)); verts.Add(new Vector3(v.z, v.w)); verts.Add(new Vector3(v.z, v.y + height / 2)); //将左上角按Y轴旋转,1和4交换 2和3交换; uvs.Add(new Vector2(u.z, u.y)); uvs.Add(new Vector2(u.z, u.w)); uvs.Add(new Vector2(u.x, u.w)); uvs.Add(new Vector2(u.x, u.y)); cols.Add(c); cols.Add(c); cols.Add(c); cols.Add(c); } /// <summary> /// 二分图手法; /// </summary> /// <param name="verts"></param> /// <param name="uvs"></param> /// <param name="cols"></param> protected void HalfFill(BetterList<Vector3> verts, BetterList<Vector2> uvs, BetterList<Color32> cols) { Vector4 v = drawingDimensions; Vector4 u = drawingUVs; Color32 c = drawingColor; Debug.LogError("HalfFill drawingDimensions=" + drawingDimensions); Debug.LogError("HalfFill drawingUVs=" + drawingUVs); //计算宽高; float width = v.z - v.x; float height = v.w - v.y; Debug.Log("HalfFill width=" + width + " height=" + height); //左边顶点; verts.Add(new Vector3(v.x, v.y)); verts.Add(new Vector3(v.x, v.w)); verts.Add(new Vector3(v.z - width / 2, v.w)); verts.Add(new Vector3(v.z - width / 2, v.y)); uvs.Add(new Vector2(u.x, u.y)); uvs.Add(new Vector2(u.x, u.w)); uvs.Add(new Vector2(u.z, u.w)); uvs.Add(new Vector2(u.z, u.y)); cols.Add(c); cols.Add(c); cols.Add(c); cols.Add(c); //右边顶点; verts.Add(new Vector3(v.x + width / 2, v.y)); verts.Add(new Vector3(v.x + width / 2, v.w)); verts.Add(new Vector3(v.z, v.w)); verts.Add(new Vector3(v.z, v.y)); //将左边按Y轴旋转,1和4交换 2和3交换; uvs.Add(new Vector2(u.z, u.y)); uvs.Add(new Vector2(u.z, u.w)); uvs.Add(new Vector2(u.x, u.w)); uvs.Add(new Vector2(u.x, u.y)); cols.Add(c); cols.Add(c); cols.Add(c); cols.Add(c); }
工程下载:
http://pan.baidu.com/s/1i3IN3CT
Unity3d游戏安装包 极限减少之 四分图、二分图 (NGUI向)
原文地址:http://blog.csdn.net/huutu/article/details/45050065