查看: 10290|回复: 81

[unity2d] Sprite Packer

  [复制链接]

17

主题

18

帖子

448

积分

vip会员

Rank: 1

积分
448
发表于 2016-7-15 13:41:28 | 显示全部楼层 |阅读模式
当设计精灵图形,可以很方便的对每个字符的一个单独的纹理文件工作。然而,一个精灵的纹理的很大一部分会被空的空间图形元素和之间的空间会产生浪费的内存在运行时。为获得最佳性能,最好是包几个雪碧纹理紧密结合在一起的图形在一个单一的纹理称为阿特拉斯。提供一个统一的雪碧封隔器公用事业自动化从个体精神生成过程纹理地图集。
统一处理雪碧阿特拉斯纹理幕后的生成和使用,用户需要做的没有手动分配。阿特拉斯可以被包装进入播放模式或在建和Sprite对象的图形将从阿特拉斯一旦生成了。
用户需要指定要启用,纹理精灵包装的纹理导入包装标签。
使用精灵封隔器
精灵封隔器默认是禁用的,你可以配置它从编辑器设置(菜单:Edit -> Project Settings -> Editor)。雪碧的包装模式是可以改变的残疾人到启用的建立(即包装用于建立但不播放模式)或始终启用(即包装is enabled and builds都播放模式)。
如果你打开雪碧封隔器窗口(菜单:Window -> Sprite Packer) 和 点击 的包裹在左上角的按钮,你会看到纹理填充在阿特拉斯的安排。
Sprite Packer
如果你选择在项目面板的雪碧,这还将突出显示其在阿特拉斯的位置。提纲实际上是渲染网格轮廓,它还定义了用于包装严密的地区。
在精灵的封隔器窗口顶部的工具栏有许多影响包装和查看控件。这个包裹按钮启动包装操作但不会强迫任何更新,如果阿特拉斯没有因为它是最后的包装变了。(相关改装按钮会出现当你实现一个自定义包装政策解释定制的雪碧封隔器below)。the阿特拉斯的观点和#页菜单,允许你选择哪一页,阿特拉斯在窗口中显示(单阿特拉斯可以被分为多个“页面”如果没有在最大纹理尺寸所有精灵们足够的空间)。旁边的页码选择“包装策略”用于阿特拉斯菜单(见下图)。在工具栏的右两控制缩放视图并为阿特拉斯颜色和alpha显示之间切换。
包装策略
精灵封隔器使用包装策略决定如何分配的精灵到地图集。可以创建自己的包装政策(见下文)但默认的封隔器政策,紧封隔器政策和紧旋转使雪碧包装政策选择总是可用。这些政策的包装标签财产的纹理导入器直接选择名称的阿特拉斯,雪碧将包装等所有精灵一样的包装的标签将被包装在同一阿特拉斯。图谱进一步按纹理导入设置让他们比赛无论源纹理的用户集。具有相同的纹理压缩设置精灵将被分成相同的阿特拉斯可能在哪里。
  • defaultpackerpolicy将使用默认的矩形包装除非“[紧张]”中指定的包装标签(即你的包装标签”[紧张]字符”将允许密封包装)。
  • tightpackerpolicy将默认使用密封包装如果雪碧有紧密的网格。如果“[矩形]”中指定的包装标签,矩形包装会做(即你的包装标签”[矩形] ui_elements”将迫使矩形包装)。
  • tightrotateenabledspritepackerpolicy将默认使用密封包装如果雪碧有紧密的网格将使旋转的精灵。如果“[矩形]”中指定的包装标签,矩形包装会做(即你的包装标签”[矩形] ui_elements”将迫使矩形包装)。
定制的雪碧封隔器
这个defaultpackerpolicy期权是最充分的目的,但你也可以实现自己的自定义包装政策如果你需要。要做到这一点,你需要在编辑脚本实现一个类的unityeditor.sprites.ipackerpolicy接口。这个接口需要以下方法:
  • 获取版本返回你的封隔器政策的版本价值。版本应该撞如果修改做策略脚本和这个政策是保存到版本控制。
  • ongroupatlases实施你的包装逻辑在这里。定义在packerjob地图集和从给定的textureimporters分配精灵。
defaultpackerpolicy使用正确的包装(见spritepackingmode)默认。如果你做的空间肌理效果或想要使用不同的网格渲染的精灵这是有用的。自定义策略可以重写此而使用密封包装。
  • 改装按钮时只启用自定义策略选择。
    • ongroupatlases否则textureimporter元数据或选定的packerpolicy版本值的变化称为。
    • 使用改装按钮在您的自定义策略工作时。
  • 精灵可以装tightrotateenabledspritepackerpolicy自动旋转。
    • spritepackingrotation是保留型未来统一版本。

其他
  • 地图缓存在项目库atlascache。
    • 删除此文件夹,然后启动统一意志力图谱被改装。统一必须关闭时。
  • 阿特拉斯是不是在开始加载缓存。
    • 所有的纹理必须检查包装时首次统一后重新启动。此操作可能需要一些时间,取决于项目的总数量的纹理。
    • 只需要地图加载。
  • 默认最大大小阿特拉斯是2048x2048。
  • 当packingtag设置,纹理不会被压缩,spritepacker可以抓住原始像素值然后进行压缩的阿特拉斯。
defaultpackerpolicy
  1. using System;
  2. using System.Linq;
  3. using UnityEngine;
  4. using UnityEditor;
  5. using System.Collections.Generic;


  6. public class DefaultPackerPolicySample : UnityEditor.Sprites.IPackerPolicy
  7. {
  8.         protected class Entry
  9.         {
  10.             public Sprite            sprite;
  11.         public UnityEditor.Sprites.AtlasSettings settings;
  12.             public string            atlasName;
  13.             public SpritePackingMode packingMode;
  14.             public int               anisoLevel;
  15.         }

  16.         private const uint kDefaultPaddingPower = 3; // Good for base and two mip levels.

  17.         public virtual int GetVersion() { return 1; }
  18.         protected virtual string TagPrefix { get { return "[TIGHT]"; } }
  19.         protected virtual bool AllowTightWhenTagged { get { return true; } }
  20.         protected virtual bool AllowRotationFlipping { get { return false; } }

  21.     public static bool IsCompressedFormat(TextureFormat fmt)
  22.     {
  23.         if (fmt >= TextureFormat.DXT1 && fmt <= TextureFormat.DXT5)
  24.             return true;
  25.         if (fmt >= TextureFormat.DXT1Crunched && fmt <= TextureFormat.DXT5Crunched)
  26.             return true;
  27.         if (fmt >= TextureFormat.PVRTC_RGB2 && fmt <= TextureFormat.PVRTC_RGBA4)
  28.             return true;
  29.         if (fmt == TextureFormat.ETC_RGB4)
  30.             return true;
  31.         if (fmt >= TextureFormat.ATC_RGB4 && fmt <= TextureFormat.ATC_RGBA8)
  32.             return true;
  33.         if (fmt >= TextureFormat.EAC_R && fmt <= TextureFormat.EAC_RG_SIGNED)
  34.             return true;
  35.         if (fmt >= TextureFormat.ETC2_RGB && fmt <= TextureFormat.ETC2_RGBA8)
  36.             return true;
  37.         if (fmt >= TextureFormat.ASTC_RGB_4x4 && fmt <= TextureFormat.ASTC_RGBA_12x12)
  38.             return true;
  39.         if (fmt >= TextureFormat.DXT1Crunched && fmt <= TextureFormat.DXT5Crunched)
  40.             return true;
  41.         return false;
  42.     }

  43.     public void OnGroupAtlases(BuildTarget target, UnityEditor.Sprites.PackerJob job, int[] textureImporterInstanceIDs)
  44.         {
  45.             List<Entry> entries = new List<Entry>();

  46.             foreach (int instanceID in textureImporterInstanceIDs)
  47.             {
  48.                 TextureImporter ti = EditorUtility.InstanceIDToObject(instanceID) as TextureImporter;

  49.                 TextureFormat desiredFormat;
  50.                 ColorSpace colorSpace;
  51.                 int compressionQuality;
  52.                 ti.ReadTextureImportInstructions(target, out desiredFormat, out colorSpace, out compressionQuality);

  53.                 TextureImporterSettings tis = new TextureImporterSettings();
  54.                 ti.ReadTextureSettings(tis);

  55.             Sprite[] sprites =
  56.                 AssetDatabase.LoadAllAssetRepresentationsAtPath(ti.assetPath)
  57.                     .Select(x => x as Sprite)
  58.                     .Where(x => x != null)
  59.                     .ToArray();
  60.                 foreach (Sprite sprite in sprites)
  61.                 {
  62.                     Entry entry = new Entry();
  63.                     entry.sprite = sprite;
  64.                     entry.settings.format = desiredFormat;
  65.                     entry.settings.colorSpace = colorSpace;
  66.                     // Use Compression Quality for Grouping later only for Compressed Formats. Otherwise leave it Empty.
  67.                 entry.settings.compressionQuality = IsCompressedFormat(desiredFormat)  compressionQuality : 0;
  68.                 entry.settings.filterMode = Enum.IsDefined(typeof(FilterMode), ti.filterMode)
  69.                      ti.filterMode
  70.                     : FilterMode.Bilinear;
  71.                     entry.settings.maxWidth = 2048;
  72.                     entry.settings.maxHeight = 2048;
  73.                     entry.settings.generateMipMaps = ti.mipmapEnabled;
  74.                     entry.settings.enableRotation = AllowRotationFlipping;
  75.                     if (ti.mipmapEnabled)
  76.                         entry.settings.paddingPower = kDefaultPaddingPower;
  77.                     else
  78.                         entry.settings.paddingPower = (uint)EditorSettings.spritePackerPaddingPower;
  79.                     #if ENABLE_ANDROID_ATLAS_ETC1_COMPRESSION
  80.                         entry.settings.allowsAlphaSplitting = ti.GetAllowsAlphaSplitting ();
  81.                     #endif //ENABLE_ANDROID_ATLAS_ETC1_COMPRESSION

  82.                     entry.atlasName = ParseAtlasName(ti.spritePackingTag);
  83.                     entry.packingMode = GetPackingMode(ti.spritePackingTag, tis.spriteMeshType);
  84.                     entry.anisoLevel = ti.anisoLevel;

  85.                     entries.Add(entry);
  86.                 }

  87.                 Resources.UnloadAsset(ti);
  88.             }

  89.             // First split sprites into groups based on atlas name
  90.             var atlasGroups =
  91.                 from e in entries
  92.                 group e by e.atlasName;
  93.             foreach (var atlasGroup in atlasGroups)
  94.             {
  95.                 int page = 0;
  96.                 // Then split those groups into smaller groups based on texture settings
  97.                 var settingsGroups =
  98.                     from t in atlasGroup
  99.                     group t by t.settings;
  100.                 foreach (var settingsGroup in settingsGroups)
  101.                 {
  102.                     string atlasName = atlasGroup.Key;
  103.                     if (settingsGroups.Count() > 1)
  104.                         atlasName += string.Format(" (Group {0})", page);

  105.                 UnityEditor.Sprites.AtlasSettings settings = settingsGroup.Key;
  106.                     settings.anisoLevel = 1;
  107.                     // Use the highest aniso level from all entries in this atlas
  108.                     if (settings.generateMipMaps)
  109.                         foreach (Entry entry in settingsGroup)
  110.                             if (entry.anisoLevel > settings.anisoLevel)
  111.                                 settings.anisoLevel = entry.anisoLevel;

  112.                     job.AddAtlas(atlasName, settings);
  113.                     foreach (Entry entry in settingsGroup)
  114.                     {
  115.                         job.AssignToAtlas(atlasName, entry.sprite, entry.packingMode, SpritePackingRotation.None);
  116.                     }

  117.                     ++page;
  118.                 }
  119.             }
  120.         }

  121.         protected bool IsTagPrefixed(string packingTag)
  122.         {
  123.             packingTag = packingTag.Trim();
  124.             if (packingTag.Length < TagPrefix.Length)
  125.                 return false;
  126.             return (packingTag.Substring(0, TagPrefix.Length) == TagPrefix);
  127.         }

  128.         private string ParseAtlasName(string packingTag)
  129.         {
  130.             string name = packingTag.Trim();
  131.             if (IsTagPrefixed(name))
  132.                 name = name.Substring(TagPrefix.Length).Trim();
  133.             return (name.Length == 0)  "(unnamed)" : name;
  134.         }

  135.         private SpritePackingMode GetPackingMode(string packingTag, SpriteMeshType meshType)
  136.         {
  137.             if (meshType == SpriteMeshType.Tight)
  138.                 if (IsTagPrefixed(packingTag) == AllowTightWhenTagged)
  139.                     return SpritePackingMode.Tight;
  140.             return SpritePackingMode.Rectangle;
  141.         }
  142. }
复制代码
tightpackerpolicy
  1. using System;
  2. using System.Linq;
  3. using UnityEngine;
  4. using UnityEditor;
  5. using UnityEditor.Sprites;
  6. using System.Collections.Generic;

  7. // TightPackerPolicy will tightly pack non-rectangle Sprites unless their packing tag contains "[RECT]".
  8. class TightPackerPolicySample : DefaultPackerPolicySample
  9. {
  10.         protected override string TagPrefix { get { return "[RECT]"; } }
  11.         protected override bool AllowTightWhenTagged { get { return false; } }
  12.         protected override bool AllowRotationFlipping { get { return false; } }
  13. }
复制代码
TightRotateEnabledSpritePackerPolicy
  1. using System;
  2. using System.Linq;
  3. using UnityEngine;
  4. using UnityEditor;
  5. using UnityEditor.Sprites;
  6. using System.Collections.Generic;

  7. // TightPackerPolicy will tightly pack non-rectangle Sprites unless their packing tag contains "[RECT]".
  8. class TightRotateEnabledSpritePackerPolicySample : DefaultPackerPolicySample
  9. {
  10.         protected override string TagPrefix { get { return "[RECT]"; } }
  11.         protected override bool AllowTightWhenTagged { get { return false; } }
  12.         protected override bool AllowRotationFlipping { get { return true; } }
  13. }
复制代码





回复

使用道具 举报

0

主题

825

帖子

2676

积分

vip会员

Rank: 1

积分
2676
发表于 2016-7-15 13:41:29 来自手机 | 显示全部楼层
谢谢楼主分享
回复 支持 反对

使用道具 举报

0

主题

913

帖子

2990

积分

vip会员

Rank: 1

积分
2990
发表于 2016-7-19 23:08:58 来自手机 | 显示全部楼层
我又来了,太贵了,我盯着你好久了。
回复 支持 反对

使用道具 举报

0

主题

885

帖子

2946

积分

vip会员

Rank: 1

积分
2946
发表于 2016-7-21 05:20:37 | 显示全部楼层
这个不错这个不错这个不错
回复 支持 反对

使用道具 举报

0

主题

888

帖子

2914

积分

vip会员

Rank: 1

积分
2914
发表于 2016-7-27 07:36:42 来自手机 | 显示全部楼层
我来看看 这个怎么样
回复 支持 反对

使用道具 举报

0

主题

30

帖子

200

积分

vip会员

Rank: 1

积分
200
发表于 2016-7-27 23:04:48 来自手机 | 显示全部楼层
等会儿下载看看
回复 支持 反对

使用道具 举报

0

主题

32

帖子

212

积分

vip会员

Rank: 1

积分
212
发表于 2016-7-28 05:28:37 | 显示全部楼层
这个必须顶,撸主好人
回复 支持 反对

使用道具 举报

0

主题

30

帖子

200

积分

vip会员

Rank: 1

积分
200
发表于 2016-7-28 15:47:22 | 显示全部楼层
谢谢楼主分享
回复 支持 反对

使用道具 举报

0

主题

28

帖子

188

积分

vip会员

Rank: 1

积分
188
发表于 2016-7-29 04:10:53 来自手机 | 显示全部楼层
谢谢楼主分享
回复 支持 反对

使用道具 举报

0

主题

37

帖子

242

积分

vip会员

Rank: 1

积分
242
发表于 2016-7-29 15:13:31 | 显示全部楼层
不错,我喜欢这个,看看多少金币哦
回复 支持 反对

使用道具 举报

*滑块验证:
您需要登录后才可以回帖 登录 | enginedx注册

本版积分规则

 
 



邮件留言:


 
返回顶部