UGUI研究院之针对IOS平台设置某些图不打图集
在处理大图片的时候,为了保证每张图片都会压缩,所以我会自动给每个图片添加一个packingTag,如此一来即使美术出的图片不是2的幂次方,unity也会将它拉成2的幂次方,在ios平台会自动变成正方形,这样就能保证每张图片都可以进行压缩。
Android采用的是这个方式,单个的大图我都会设置一个packingTag 保证每张图片都可以压缩,效果确实还可以。
IOS的大图就就略显尴尬,因为有些透明渐变的图片,Android使用上述的压缩方式是没问题的,但是IOS如果直接用pvrtc 4来压缩,效果就不太好了。这时候android可以保持原样,ios希望采取 rgba 16bit 的格式,但是因为前面我们给这个图片设置了packingTag ios上会被拉成正方形,那么rgba 16bit就会比图片原始尺寸更加的占内存。可是如果我把packingTag清空,那么android ios两边无法保持一致,如果打包预处理的话,svn就会发生变化。
所以希望,如果图集中只有一张图片,并且设置了非压缩格式,那么即使设置了packingTag也不对它打图集。研究了一下unity图集的打包过程,可以通过代码来处理。把如下代码放在Editor目录下即可 ,注意代码中注释的部分。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
|
using
System
;
using
System
.
Linq
;
using
UnityEngine
;
using
UnityEditor
;
using
System
.
Collections
.
Generic
;
public
class
CustomPackerPolicySample
:
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
string
TagPrefix
{
get
{
return
"[RECT]"
;
}
}
protected
bool
AllowTightWhenTagged
{
get
{
return
true
;
}
}
protected
bool
AllowRotationFlipping
{
get
{
return
true
;
}
}
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
=
false
;
entry
.
settings
.
enableRotation
=
AllowRotationFlipping
;
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
)
{
//已经设置了非压缩的图,不做成图集,避免拉成图集占内存。
bool
skipAtlas
=
(
settingsGroup
.
Count
(
)
==
1
&&
!
IsCompressedFormat
(
settingsGroup
.
ElementAt
(
0
)
.
settings
.
format
)
)
;
if
(
skipAtlas
)
{
Debug
.
Log
(
settingsGroup
.
ElementAt
(
0
)
.
sprite
.
name
)
;
continue
;
}
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
;
}
}
|
图片如果控制不好,还是很占内存的。我们游戏默认就把所有图片全部压缩,如果美术觉得某些图片效果不好,那么就对它单独处理一下即可。
版本unity5.5.2
最后欢迎大家在下面留言一起讨论。。