当前位置:   article > 正文

Unity杂谈(一)图集制作与图集分割_unity 图集分页是怎么实现的

unity 图集分页是怎么实现的

1、图集制作

1.1、NGUI下的图集制作

首先将需要制作成图集的小图放到Unity工程下的某个目录下,再通过NGUI->Open->Atlas Maker。如下图

将会打开图集制作界面,如下图。在选择好需要制作成图集的小图后,点击Craete,将生成NGUI生成好的图集。

NGUI将生成三个文件,分别是png文件(图集);material文件(材质);prefab文件(实际用到的Atlas)。

 

1.2 UGUI制作图集

UGUI打包图集的设置在Project Seting >>Editor>>Sprite Packer的Mode。

其中,Disabled表示不启用图集打包,Enabled For Builds 表示仅在发布时启用。Always Enabled表示一直启用,方便我们开发人员在开发阶段就查看图集打包的情况。我们选择这种方式。

在开启图集打包后,我们选中需要打包成图集的小图(不能放在Resources目录下),将Packing Tag填入指定的值。如下

此时,UGUI将会把Packing Tag值相同的图片打包到同一个图集中,可在Window->Sprite Packer中查看。(如果未出现图集,点击Pack)。实际生成的图集在默认放在Libary/AtlasCache里面。

1.3 使用TexurePacker

TexturePacker官网链接

下载TexturePacker并安装后,打开TexturePacker,如下图

将需要合成图集的小图拖拽到左侧空白处,并在右侧的Data Format 选择 JSON Data(当然可以选择其他格式的文件,这边只是其中的一种方法)。

然后点击publish sprite sheet。生成所需要的图集。

在Unity中,可以通过json文件保存的信息进行图集的再次slice。我在网上找到一些代码,可以对图集进行分割。

TexturePacker.cs

  1. /*
  2. Copyright (c) 2013 Mitch Thompson
  3. Extended by Harald Lurger (2013) (Process to Sprites)
  4. Standard MIT License
  5. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
  6. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
  7. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  8. */
  9. using UnityEngine;
  10. using UnityEditor;
  11. using System.Collections;
  12. using System.Collections.Generic;
  13. public static class TexturePackerExtensions{
  14. public static Rect TPHashtableToRect(this Hashtable table){
  15. return new Rect((float)table["x"], (float)table["y"], (float)table["w"], (float)table["h"]);
  16. }
  17. public static Vector2 TPHashtableToVector2(this Hashtable table){
  18. if(table.ContainsKey("x") && table.ContainsKey("y")){
  19. return new Vector2((float)table["x"], (float)table["y"]);
  20. }
  21. else{
  22. return new Vector2((float)table["w"], (float)table["h"]);
  23. }
  24. }
  25. public static Vector2 TPVector3toVector2(this Vector3 vec){
  26. return new Vector2(vec.x, vec.y);
  27. }
  28. public static bool IsTexturePackerTable(this Hashtable table){
  29. if(table == null) return false;
  30. if(table.ContainsKey("meta")){
  31. Hashtable metaTable = (Hashtable)table["meta"];
  32. if(metaTable.ContainsKey("app")){
  33. return true;
  34. // if((string)metaTable["app"] == "http://www.texturepacker.com"){
  35. // return true;
  36. // }
  37. }
  38. }
  39. return false;
  40. }
  41. }
  42. public class TexturePacker{
  43. public class PackedFrame{
  44. public string name;
  45. public Rect frame;
  46. public Rect spriteSourceSize;
  47. public Vector2 sourceSize;
  48. public bool rotated;
  49. public bool trimmed;
  50. Vector2 atlasSize;
  51. public PackedFrame(string name, Vector2 atlasSize, Hashtable table){
  52. this.name = name;
  53. this.atlasSize = atlasSize;
  54. frame = ((Hashtable)table["frame"]).TPHashtableToRect();
  55. spriteSourceSize = ((Hashtable)table["spriteSourceSize"]).TPHashtableToRect();
  56. sourceSize = ((Hashtable)table["sourceSize"]).TPHashtableToVector2();
  57. rotated = (bool)table["rotated"];
  58. trimmed = (bool)table["trimmed"];
  59. }
  60. public Mesh BuildBasicMesh(float scale, Color32 defaultColor){
  61. return BuildBasicMesh(scale, defaultColor, Quaternion.identity);
  62. }
  63. public Mesh BuildBasicMesh(float scale, Color32 defaultColor, Quaternion rotation){
  64. Mesh m = new Mesh();
  65. Vector3[] verts = new Vector3[4];
  66. Vector2[] uvs = new Vector2[4];
  67. Color32[] colors = new Color32[4];
  68. if(!rotated){
  69. verts[0] = new Vector3(frame.x,frame.y,0);
  70. verts[1] = new Vector3(frame.x,frame.y+frame.height,0);
  71. verts[2] = new Vector3(frame.x+frame.width,frame.y+frame.height,0);
  72. verts[3] = new Vector3(frame.x+frame.width,frame.y,0);
  73. }
  74. else{
  75. verts[0] = new Vector3(frame.x,frame.y,0);
  76. verts[1] = new Vector3(frame.x,frame.y+frame.width,0);
  77. verts[2] = new Vector3(frame.x+frame.height,frame.y+frame.width,0);
  78. verts[3] = new Vector3(frame.x+frame.height,frame.y,0);
  79. }
  80. uvs[0] = verts[0].TPVector3toVector2();
  81. uvs[1] = verts[1].TPVector3toVector2();
  82. uvs[2] = verts[2].TPVector3toVector2();
  83. uvs[3] = verts[3].TPVector3toVector2();
  84. for(int i = 0; i < uvs.Length; i++){
  85. uvs[i].x /= atlasSize.x;
  86. uvs[i].y /= atlasSize.y;
  87. uvs[i].y = 1.0f - uvs[i].y;
  88. }
  89. if(rotated){
  90. verts[3] = new Vector3(frame.x,frame.y,0);
  91. verts[0] = new Vector3(frame.x,frame.y+frame.height,0);
  92. verts[1] = new Vector3(frame.x+frame.width,frame.y+frame.height,0);
  93. verts[2] = new Vector3(frame.x+frame.width,frame.y,0);
  94. }
  95. //v-flip
  96. for(int i = 0; i < verts.Length; i++){
  97. verts[i].y = atlasSize.y - verts[i].y;
  98. }
  99. //original origin
  100. for(int i = 0; i < verts.Length; i++){
  101. verts[i].x -= frame.x - spriteSourceSize.x + (sourceSize.x/2.0f);
  102. verts[i].y -= (atlasSize.y - frame.y) - (sourceSize.y - spriteSourceSize.y) + (sourceSize.y/2.0f);
  103. }
  104. //scaler
  105. for(int i = 0; i < verts.Length; i++){
  106. verts[i] *= scale;
  107. }
  108. //rotator
  109. if(rotation != Quaternion.identity){
  110. for(int i = 0; i < verts.Length; i++){
  111. verts[i] = rotation * verts[i];
  112. }
  113. }
  114. for(int i = 0; i < colors.Length; i++){
  115. colors[i] = defaultColor;
  116. }
  117. m.vertices = verts;
  118. m.uv = uvs;
  119. m.colors32 = colors;
  120. m.triangles = new int[6]{0,3,1,1,3,2};
  121. m.RecalculateNormals();
  122. m.RecalculateBounds();
  123. m.name = name;
  124. return m;
  125. }
  126. public SpriteMetaData BuildBasicSprite(float scale, Color32 defaultColor){
  127. SpriteMetaData smd = new SpriteMetaData();
  128. Rect rect;
  129. if(!rotated){
  130. rect = this.frame;
  131. }
  132. else
  133. {
  134. rect = new Rect(frame.x,frame.y,frame.height,frame.width);
  135. }
  136. /* Look if frame is outside from texture */
  137. if( (frame.x + frame.width) > atlasSize.x || (frame.y + frame.height) > atlasSize.y ||
  138. (frame.x < 0 || frame.y < 0))
  139. {
  140. Debug.Log(this.name + " is outside from texture! Sprite is ignored!");
  141. smd.name = "IGNORE_SPRITE";
  142. return smd;
  143. }
  144. //calculate Height
  145. /* Example: Texture: 1000 Width x 500 height
  146. * Sprite.Recht(0,0,100,100) --> Sprite is on the bottom left
  147. */
  148. rect.y = atlasSize.y - frame.y - rect.height;
  149. smd.rect = rect;
  150. smd.alignment = 1;
  151. smd.name = name;
  152. smd.pivot = this.frame.center;
  153. return smd;
  154. }
  155. }
  156. public class MetaData{
  157. public string image;
  158. public string format;
  159. public Vector2 size;
  160. public float scale;
  161. public string smartUpdate;
  162. public MetaData(Hashtable table){
  163. image = (string)table["image"];
  164. format = (string)table["format"];
  165. size = ((Hashtable)table["size"]).TPHashtableToVector2();
  166. scale = float.Parse(table["scale"].ToString());
  167. smartUpdate = (string)table["smartUpdate"];
  168. }
  169. }
  170. public static List<SpriteMetaData> ProcessToSprites(string text) {
  171. Hashtable table = text.hashtableFromJson();
  172. MetaData meta = new MetaData((Hashtable)table["meta"]);
  173. List<PackedFrame> frames = new List<PackedFrame>();
  174. Hashtable frameTable = (Hashtable)table["frames"];
  175. foreach(DictionaryEntry entry in frameTable){
  176. frames.Add(new PackedFrame((string)entry.Key, meta.size, (Hashtable)entry.Value));
  177. }
  178. SortFrames(frames);
  179. List<SpriteMetaData> sprites = new List<SpriteMetaData>();
  180. for(int i = 0; i < frames.Count; i++){
  181. SpriteMetaData smd = frames[i].BuildBasicSprite( 0.01f, new Color32(128,128,128,128));
  182. if(!smd.name.Equals("IGNORE_SPRITE"))
  183. sprites.Add(smd);
  184. }
  185. return sprites;
  186. }
  187. private static List<PackedFrame> SortFrames (List<PackedFrame> frames) {
  188. for (int i=frames.Count-1; i>0; i--) {
  189. for (int j=0; j<i; j++) {
  190. if (string.Compare(frames[j+1].name, frames[j].name) < 0) {
  191. PackedFrame temp = frames[j+1];
  192. frames[j+1] = frames[j];
  193. frames[j] = temp;
声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号