Unity3d游戏安装包 极限减少之 四分图、二分图 (NGUI向)

来源:互联网 发布:java产生随机数的代码 编辑:程序博客网 时间:2024/06/14 05:43

在这个酒香也怕巷子深,游戏不打广告不买用户不刷榜就会死的时代。每个游戏代理都想让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://blog.csdn.net/huutu http://www.thisisgame.com.cn


工程下载:

http://pan.baidu.com/s/1i3IN3CT



0 0
原创粉丝点击