W3Cschool
恭喜您成為首批注冊(cè)用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
在設(shè)計(jì)sprite
圖形時(shí),可以方便地為每個(gè)角色使用單獨(dú)的紋理文件。然而,sprite紋理的很大一部分通常將被圖形元素之間的空白空間占據(jù),這個(gè)空間會(huì)在運(yùn)行時(shí)浪費(fèi)視頻內(nèi)存。為了獲得最佳性能,最好將圖形從幾個(gè)sprite
紋理緊密地組合在一個(gè)稱為圖集的單一紋理中。Unity提供了一個(gè)Sprite Packer
實(shí)用工具,用于自動(dòng)化從單個(gè)sprite
紋理生成圖層的過(guò)程。
Unity處理幕后紋理圖案紋理的生成和使用,使用戶無(wú)需手工分配。圖譜可以選擇在進(jìn)入播放模式或構(gòu)建過(guò)程中打包,并且sprite
物體的圖形將在生成后從地圖集獲取。
用戶需要在紋理導(dǎo)入器中指定包裝標(biāo)簽,才能打包該紋理的Sprites。
默認(rèn)情況下,Sprite Packer
已禁用,但可以從編輯器設(shè)置(菜單:編輯( Edit)- >項(xiàng)目設(shè)置(Project Settings) - >編輯(Editor))進(jìn)行配置。sprite包裝模式可以從禁用到啟用(即打包用于構(gòu)建但不是播放模式)或始終啟用(即打包打開播放模式和構(gòu)建)。
如果打開Sprite Packer窗口(菜單:Window
- > Sprite Packer
),然后單擊左上角的Pack按鈕,您將看到在圖集中包裝的紋理的排列。
如果您在“項(xiàng)目(Project)”面板中選擇一個(gè)sprite,這也將突出顯示其在圖集中的位置。輪廓實(shí)際上是渲染網(wǎng)格輪廓,并且還定義了用于緊密包裝的區(qū)域。
Sprite Packer窗口頂部的工具欄有一些影響打包和查看的控件。該Pack
按鈕啟動(dòng)壓縮操作,但不會(huì)強(qiáng)迫任何更新,如果寰并沒(méi)有改變,因?yàn)樗亲詈蟀b。(實(shí)現(xiàn)自定義打包封裝時(shí),會(huì)顯示相關(guān)的重新打包(Repack
)按鈕,如下面的自定義Sprite包Customizing the Sprite Packer
中所述)。在查看圖集View Atlas
和Page #
菜單允許您選擇窗口中顯示哪些地圖集的頁(yè)面(如果沒(méi)有足夠的空間用于最大紋理大小的所有sprite
,單個(gè)地圖集可能會(huì)被分割成多個(gè)“頁(yè)面Page”)。頁(yè)碼旁邊的菜單選擇哪個(gè)Packing Policy
用于地圖冊(cè)atlas
(見下文)。工具欄右側(cè)有兩個(gè)縮放視圖的控件,并在圖集的顏色和alpha
顯示之間進(jìn)行切換。
prite Packer
使用打包封裝來(lái)決定如何將sprite
分配到atlases
中??梢詣?chuàng)建自己的packing policies
(見下文),但默認(rèn)打包程序策略Default Packer Policy
,緊密封裝程序策略(Tight Packer Policy
)和緊密旋轉(zhuǎn)啟用的Sprite打包程序策略選項(xiàng)始終可用。通過(guò)這些策略,紋理導(dǎo)入器中的打包標(biāo)簽屬性直接選擇精靈將要包裝的地圖集的名稱,所有相同包裝標(biāo)簽的所有精靈將被包裝在同一個(gè)圖集中。然后通過(guò)紋理導(dǎo)入設(shè)置對(duì)Atlases進(jìn)行進(jìn)一步排序,使其與用戶為源紋理設(shè)置的任何一致。具有相同紋理壓縮設(shè)置的Sprites將盡可能地分組到相同的圖集中。
DefaultPackerPolicy
將默認(rèn)使用矩形包裝,除非在“ 包裝標(biāo)簽(Packing Tag
) ”中指定“[TIGHT]
”(即將包裝標(biāo)簽設(shè)置為“[TIGHT] Character
”將允許緊密包裝)。Sprite
有緊密的網(wǎng)格,默認(rèn)情況下,TightPackerPolicy
將使用緊密包裝。如果在“ Packing Tag
”中指定了“[RECT]
” ,則矩形包裝將被完成(即將包裝標(biāo)簽Packing Tag
設(shè)置為“[RECT] UI_Elements
”將強(qiáng)制直接包裝)。TightRotateEnabledSpritePackerPolicy
將默認(rèn)使用緊密打包,如果Sprite
具有緊密的網(wǎng)格,并且將允許精靈旋轉(zhuǎn)。如果在“ 包裝標(biāo)簽 ”中指定了“[RECT]
” ,則矩形包裝將被完成(即將包裝標(biāo)簽設(shè)置為“[RECT] UI_Elements
”將強(qiáng)制直接包裝)。
該DefaultPackerPolicy
選項(xiàng)足以滿足大多數(shù)目的,但你也可以實(shí)現(xiàn)自己的定制包裝的政策,如果你需要。為此,您需要在編輯器腳本中為類實(shí)現(xiàn)UnityEditor.Sprites.IPackerPolicy接口。此界面需要以下方法:
DefaultPackerPolicy默認(rèn)使用rect打包(請(qǐng)參閱SpritePackingMode)。如果您正在進(jìn)行紋理空間效果或者想使用不同的網(wǎng)格渲染Sprite,這將非常有用。自定義策略可以覆蓋這一點(diǎn),而是使用緊密包裝。
using System;
using System.Linq;
using UnityEngine;
using UnityEditor;
using System.Collections.Generic;
public class DefaultPackerPolicySample : UnityEditor.Sprites.IPackerPolicy
{
protected class Entry
{
public Sprite sprite;
public UnityEditor.Sprites.AtlasSettings settings;
public string atlasName;
public SpritePackingMode packingMode;
public int anisoLevel;
}
private const uint kDefaultPaddingPower = 3; // Good for base and two mip levels.
public virtual int GetVersion() { return 1; }
protected virtual string TagPrefix { get { return "[TIGHT]"; } }
protected virtual bool AllowTightWhenTagged { get { return true; } }
protected virtual bool AllowRotationFlipping { get { return false; } }
public static bool IsCompressedFormat(TextureFormat fmt)
{
if (fmt >= TextureFormat.DXT1 && fmt <= TextureFormat.DXT5)
return true;
if (fmt >= TextureFormat.DXT1Crunched && fmt <= TextureFormat.DXT5Crunched)
return true;
if (fmt >= TextureFormat.PVRTC_RGB2 && fmt <= TextureFormat.PVRTC_RGBA4)
return true;
if (fmt == TextureFormat.ETC_RGB4)
return true;
if (fmt >= TextureFormat.ATC_RGB4 && fmt <= TextureFormat.ATC_RGBA8)
return true;
if (fmt >= TextureFormat.EAC_R && fmt <= TextureFormat.EAC_RG_SIGNED)
return true;
if (fmt >= TextureFormat.ETC2_RGB && fmt <= TextureFormat.ETC2_RGBA8)
return true;
if (fmt >= TextureFormat.ASTC_RGB_4x4 && fmt <= TextureFormat.ASTC_RGBA_12x12)
return true;
if (fmt >= TextureFormat.DXT1Crunched && fmt <= TextureFormat.DXT5Crunched)
return true;
return false;
}
public void OnGroupAtlases(BuildTarget target, UnityEditor.Sprites.PackerJob job, int[] textureImporterInstanceIDs)
{
List<Entry> entries = new List<Entry>();
foreach (int instanceID in textureImporterInstanceIDs)
{
TextureImporter ti = EditorUtility.InstanceIDToObject(instanceID) as TextureImporter;
TextureFormat desiredFormat;
ColorSpace colorSpace;
int compressionQuality;
ti.ReadTextureImportInstructions(target, out desiredFormat, out colorSpace, out compressionQuality);
TextureImporterSettings tis = new TextureImporterSettings();
ti.ReadTextureSettings(tis);
Sprite[] sprites =
AssetDatabase.LoadAllAssetRepresentationsAtPath(ti.assetPath)
.Select(x => x as Sprite)
.Where(x => x != null)
.ToArray();
foreach (Sprite sprite in sprites)
{
Entry entry = new Entry();
entry.sprite = sprite;
entry.settings.format = desiredFormat;
entry.settings.colorSpace = colorSpace;
// Use Compression Quality for Grouping later only for Compressed Formats. Otherwise leave it Empty.
entry.settings.compressionQuality = IsCompressedFormat(desiredFormat) ? compressionQuality : 0;
entry.settings.filterMode = Enum.IsDefined(typeof(FilterMode), ti.filterMode)
? ti.filterMode
: FilterMode.Bilinear;
entry.settings.maxWidth = 2048;
entry.settings.maxHeight = 2048;
entry.settings.generateMipMaps = ti.mipmapEnabled;
entry.settings.enableRotation = AllowRotationFlipping;
if (ti.mipmapEnabled)
entry.settings.paddingPower = kDefaultPaddingPower;
else
entry.settings.paddingPower = (uint)EditorSettings.spritePackerPaddingPower;
#if ENABLE_ANDROID_ATLAS_ETC1_COMPRESSION
entry.settings.allowsAlphaSplitting = ti.GetAllowsAlphaSplitting ();
#endif //ENABLE_ANDROID_ATLAS_ETC1_COMPRESSION
entry.atlasName = ParseAtlasName(ti.spritePackingTag);
entry.packingMode = GetPackingMode(ti.spritePackingTag, tis.spriteMeshType);
entry.anisoLevel = ti.anisoLevel;
entries.Add(entry);
}
Resources.UnloadAsset(ti);
}
// First split sprites into groups based on atlas name
var atlasGroups =
from e in entries
group e by e.atlasName;
foreach (var atlasGroup in atlasGroups)
{
int page = 0;
// Then split those groups into smaller groups based on texture settings
var settingsGroups =
from t in atlasGroup
group t by t.settings;
foreach (var settingsGroup in settingsGroups)
{
string atlasName = atlasGroup.Key;
if (settingsGroups.Count() > 1)
atlasName += string.Format(" (Group {0})", page);
UnityEditor.Sprites.AtlasSettings settings = settingsGroup.Key;
settings.anisoLevel = 1;
// Use the highest aniso level from all entries in this atlas
if (settings.generateMipMaps)
foreach (Entry entry in settingsGroup)
if (entry.anisoLevel > settings.anisoLevel)
settings.anisoLevel = entry.anisoLevel;
job.AddAtlas(atlasName, settings);
foreach (Entry entry in settingsGroup)
{
job.AssignToAtlas(atlasName, entry.sprite, entry.packingMode, SpritePackingRotation.None);
}
++page;
}
}
}
protected bool IsTagPrefixed(string packingTag)
{
packingTag = packingTag.Trim();
if (packingTag.Length < TagPrefix.Length)
return false;
return (packingTag.Substring(0, TagPrefix.Length) == TagPrefix);
}
private string ParseAtlasName(string packingTag)
{
string name = packingTag.Trim();
if (IsTagPrefixed(name))
name = name.Substring(TagPrefix.Length).Trim();
return (name.Length == 0) ? "(unnamed)" : name;
}
private SpritePackingMode GetPackingMode(string packingTag, SpriteMeshType meshType)
{
if (meshType == SpriteMeshType.Tight)
if (IsTagPrefixed(packingTag) == AllowTightWhenTagged)
return SpritePackingMode.Tight;
return SpritePackingMode.Rectangle;
}
}
using System;
using System.Linq;
using UnityEngine;
using UnityEditor;
using UnityEditor.Sprites;
using System.Collections.Generic;
// TightPackerPolicy will tightly pack non-rectangle Sprites unless their packing tag contains "[RECT]".
class TightPackerPolicySample : DefaultPackerPolicySample
{
protected override string TagPrefix { get { return "[RECT]"; } }
protected override bool AllowTightWhenTagged { get { return false; } }
protected override bool AllowRotationFlipping { get { return false; } }
}
using System;
using System.Linq;
using UnityEngine;
using UnityEditor;
using UnityEditor.Sprites;
using System.Collections.Generic;
// TightPackerPolicy will tightly pack non-rectangle Sprites unless their packing tag contains "[RECT]".
class TightRotateEnabledSpritePackerPolicySample : DefaultPackerPolicySample
{
protected override string TagPrefix { get { return "[RECT]"; } }
protected override bool AllowTightWhenTagged { get { return false; } }
protected override bool AllowRotationFlipping { get { return true; } }
}
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: