一個(gè)項(xiàng)目在發(fā)布成WebGL后,其體積至關(guān)重要,體積太大,用戶加載會(huì)經(jīng)歷一個(gè)漫長的等待…輕則罵娘,重則用腳把電腦踢爛(扣質(zhì)保金)…
那么如何減少發(fā)布后的體積呢,本文從圖片的壓縮開始入手。
前傳回顧:
Unity減少發(fā)布打包文件的體積(一)——獲取精靈圖片的信息限制它的大小
一、徒手設(shè)置每張圖片的壓縮方法
在assets文件夾里選中一個(gè)Image,在Inspector底部有一個(gè)各發(fā)布平臺(tái)的壓縮設(shè)置,如下圖中4的部分。
在此處設(shè)置壓縮格式時(shí),只針對發(fā)布時(shí)進(jìn)行壓縮,不會(huì)修改工程資源的原始文件,這樣如果你發(fā)布成exe時(shí),可以用高清的設(shè)置(而如果直接改了原始圖片,則發(fā)布成exe時(shí),畫質(zhì)被降低)。
1、壓縮格式Format的說明(來源Claude.ai):
-
ASTC (Adaptive Scalable Texture Compression): 這是一個(gè)非常靈活的紋理壓縮格式,可以提供一系列不同的壓縮比,以適應(yīng)各種不同的應(yīng)用需求。ASTC由ARM開發(fā),旨在為各種不同的2D和3D內(nèi)容提供優(yōu)質(zhì)的可壓縮性能。它被廣泛用于移動(dòng)設(shè)備,特別是那些使用ARM集成電路的設(shè)備。
-
ETC (Ericsson Texture Compression): ETC是一種開放的、有損的紋理壓縮格式,使用在OpenGL和OpenGL ES。ETC1版本不支持alpha通道,而ETC2支持alpha通道。由于其廣泛的設(shè)備支持和合理的壓縮效果,ETC被廣泛應(yīng)用于移動(dòng)設(shè)備。
-
DXT (DirectXTex): 也被稱為S3TC,這是一種有損的紋理壓縮格式,主要應(yīng)用在DirectX場景。DXT格式為紋理提供5:1的壓縮比率且支持alpha通道,對于PC和一些游戲主機(jī)上的3D應(yīng)用,通常采用DXT格式。
-
BC (Block Compression): BC是一系列DirectX的一部分提供的紋理壓縮方法,這其中包括DXT。BC系列(包括BC1-BC7)是幾種特殊用途的格式,它們在紋理分辨率、細(xì)節(jié)和壓縮比率上提供多種選擇,但并非所有設(shè)備都支持。
-
EAC (Ericsson Alpha Compression): 這是ETC2壓縮方法的一部分,用于對alpha通道進(jìn)行壓縮。EAC提供了更好的顏色和alpha通道保真度,特別適合那些需要用到透明效果的游戲或者帶有alpha混合的特效。
2、MaxSize的計(jì)算
Unity中如果你不單獨(dú)設(shè)置,它的默認(rèn)值大概就是2048,你可以寫一個(gè)函數(shù),根據(jù)分辨力來計(jì)算maxSize的值。
/// <summary>
/// 獲取圖片的分辨率,取分辨率中高寬的最大值,然后返回圖片的【MaxSize】
/// MaxSize的定義:assets->Image->【Texture2D ImportSettings】->【Override For WebGL】->【Max Size】
/// 區(qū)間:16,32,64,128,256,512,1024,2048,4096,8192,16384
///
/// 舉例:圖片分辨率 = 12 * 24,那么圖片的MaxSize = 32
/// </summary>
/// <param name="texture"></param>
/// <returns></returns>
public static int GetMaxSize(Texture2D texture)
{
//分辨率區(qū)間的預(yù)備
var start = new List<int> { 0, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384 };
var end = new List<int> { 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 100000 };
var zones = start.Zip(end, (item1, item2) => (startIdx: item1, endIdx: item2)).ToList();
//取分辨率高寬的最大值
var size = new List<int> { texture.width, texture.height }.Max(); //取【寬】【高】中的最大值
//判斷所屬的區(qū)間
var maxSize = zones.First(x => x.startIdx <= size && size <= x.endIdx).endIdx;
//Debug.Log($"圖的分辨率 = {texture.width} * {texture.height} size = {size}, MaxSize = {maxSize}");
return maxSize;
}
3、 Format的設(shè)置:
Unity面板上提供的各種壓縮算法:
自己親自指揮親自部署時(shí),代碼中可選的壓縮格式:
4、提問:所有的圖片能不能一鍵設(shè)置呢?
可以的,你可以自己寫一個(gè)編輯器腳本(俗稱插件),也可以讓AI幫你寫一個(gè)…然后自己慢慢改
二、一鍵設(shè)置所有圖片的Build時(shí)的壓縮選項(xiàng)
1、快捷菜單入口
右鍵全選圖片 -> 【設(shè)置發(fā)布WebGL時(shí)貼圖的壓縮格式】
處理中…
2、壓縮效果
壓縮結(jié)束后,發(fā)現(xiàn)包的大小從230M減少到138兆。
3、實(shí)現(xiàn)的基本思路
- (1)找到所有的全選物體
Object[] textures = Selection.GetFiltered(typeof(Texture2D), SelectionMode.DeepAssets);
注意:上述寫法容易爆內(nèi)存,假如我選取了2000多張圖,有的圖還是4k的,當(dāng)圖片加載的時(shí)候,內(nèi)存暴漲,然后就是程序崩潰,電腦死機(jī)。使用場景就是只能選取少量的圖片。
自動(dòng)獲取圖片并處理:
- 獲取所有圖片的信息
string[] guids = AssetDatabase.FindAssets("t:texture2d");
- 獲取圖片路徑
string path = AssetDatabase.GUIDToAssetPath(guid);//guid是guids的items
- 通過路徑加載圖片
Texture2D texture = AssetDatabase.LoadAssetAtPath<Texture2D>(path);
- 圖片設(shè)置
......
-
(2)單個(gè)物體的壓縮選項(xiàng)設(shè)定
創(chuàng)建特定平臺(tái)壓縮實(shí)例 勾選壓縮 設(shè)置參數(shù) Apply
// 創(chuàng)建特定平臺(tái)壓縮實(shí)例
TextureImporterPlatformSettings platformSettings = new TextureImporterPlatformSettings();
platformSettings.overridden = true;
platformSettings.name = "WebGL";
// 設(shè)置為壓縮
platformSettings.textureCompression = TextureImporterCompression.Compressed;
// 設(shè)置壓縮格式
platformSettings.format = format; //TextureImporterFormat.ASTC_12x12;
platformSettings.compressionQuality = compressionQuality; //40
platformSettings.maxTextureSize = GetMaxSize(texture as Texture2D); //32
//設(shè)置importSettings
TextureImporter importer = AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(texture)) as TextureImporter;
importer.SetPlatformTextureSettings(platformSettings);
//Apply 設(shè)置
importer.SetPlatformTextureSettings(platformSettings);
//保存資源
importer.SaveAndReimport();
三、附錄(代碼)
運(yùn)行方式,放到任何Editor文件里文章來源:http://www.zghlxwxcb.cn/news/detail-767240.html
1、選中圖片后右鍵菜單處理方式
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEditor;
public class SetTextureCompression
{
//****************************************參數(shù)設(shè)置區(qū)**********begin
//TODO 做成EditWindow類型
private static TextureImporterFormat format = TextureImporterFormat.ASTC_12x12; //圖片壓縮格式
private static int compressionQuality = 60; //壓縮比例
private static string platform = "WebGL"; //發(fā)布的平臺(tái)
//************************************************************end
/// <summary>
/// 設(shè)置貼圖在build時(shí)的壓縮選項(xiàng)
/// </summary>
[MenuItem("Assets/設(shè)置發(fā)布WebGL時(shí)貼圖的壓縮格式")]
static void SetCompression()
{
int count = 0;
Object[] textures = Selection.GetFiltered(typeof(Texture2D), SelectionMode.DeepAssets);
if (textures.Length > 0)
{
foreach (Object texture in textures)
{
// 創(chuàng)建特定平臺(tái)壓縮實(shí)例
TextureImporterPlatformSettings platformSettings = new TextureImporterPlatformSettings();
platformSettings.overridden = true;
platformSettings.name = platform;
// 設(shè)置為壓縮
platformSettings.textureCompression = TextureImporterCompression.Compressed;
// 設(shè)置壓縮格式
platformSettings.format = format; //TextureImporterFormat.ASTC_12x12;
platformSettings.compressionQuality = compressionQuality; //40
platformSettings.maxTextureSize = GetMaxSize(texture as Texture2D); //32
//設(shè)置importSettings
TextureImporter importer = AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(texture)) as TextureImporter;
importer.SetPlatformTextureSettings(platformSettings);
//Apply 設(shè)置
importer.SetPlatformTextureSettings(platformSettings);
//保存資源
importer.SaveAndReimport();
count++;
}
//Debug.Log("Texture Compression Set!");
}
else
{
Debug.LogWarning("沒有選中圖片!");
}
Debug.Log($"一共處理了{count}張圖片!");
}
/// <summary>
/// 獲取圖片的分辨率,取分辨率中高寬的最大值,然后返回圖片的【MaxSize】
/// MaxSize的定義:assets->Image->【Texture2D ImportSettings】->【Override For WebGL】->【Max Size】
/// 區(qū)間:16,32,64,128,256,512,1024,2048,4096,8192,16384
///
/// 舉例:圖片分辨率 = 12 * 24,那么圖片的MaxSize = 32
/// </summary>
/// <param name="texture"></param>
/// <returns></returns>
static int GetMaxSize(Texture2D texture)
{
//分辨率區(qū)間的預(yù)備
var start = new List<int> { 0, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384 };
var end = new List<int> { 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 100000 };
var zones = start.Zip(end, (item1, item2) => (startIdx: item1, endIdx: item2)).ToList();
//取分辨率高寬的最大值
var size = new List<int> { texture.width, texture.height }.Max(); //取【寬】【高】中的最大值
//判斷所屬的區(qū)間
var maxSize = zones
.First(x => x.startIdx <= size && size <= x.endIdx)
.endIdx;
//Debug.Log($"圖的分辨率 = {texture.width} * {texture.height} size = {size}, MaxSize = {maxSize}");
return maxSize;
}
}
2、自動(dòng)獲取圖片一鍵處理方式
關(guān)鍵代碼【編輯器腳本使用】:文章來源地址http://www.zghlxwxcb.cn/news/detail-767240.html
using System;
using UnityEngine;
using UnityEditor;
using System.Linq;
using System.IO;
using System.Collections.Generic;
class Example : EditorWindow
{
#if UNITY_EDITOR
[MenuItem("模型處理/查找項(xiàng)目中所有的texture 2d對象并壓縮")]
#endif
static void FindAllTexture2D()
{
//****************************************參數(shù)設(shè)置區(qū)**********begin
//TODO 做成EditWindow類型
TextureImporterFormat format = TextureImporterFormat.ASTC_12x12; //圖片壓縮格式
int compressionQuality = 60; //壓縮比例
string platform = "WebGL"; //發(fā)布的平臺(tái)
//************************************************************end
//查找工程文件中的所有精靈圖片
string[] guids = AssetDatabase.FindAssets("t:texture2d");
Debug.Log($"Found {guids.Length} Texture2d assets.");
foreach (string guid in guids)
{
try
{
string path = AssetDatabase.GUIDToAssetPath(guid);
Debug.Log($"{path}");
// 使用AssetDatabase加載Texture2D
Texture2D texture = AssetDatabase.LoadAssetAtPath<Texture2D>(path);
//Debug.Log($"{texture.name}");
if (texture == null) continue;
// 創(chuàng)建特定平臺(tái)壓縮實(shí)例
TextureImporterPlatformSettings platformSettings = new TextureImporterPlatformSettings();
platformSettings.overridden = true;
platformSettings.name = platform;
// 設(shè)置為壓縮
platformSettings.textureCompression = TextureImporterCompression.Compressed;
// 設(shè)置壓縮格式
platformSettings.format = format; //TextureImporterFormat.ASTC_12x12;
platformSettings.compressionQuality = compressionQuality; //40
platformSettings.maxTextureSize = GetMaxSize(texture as Texture2D); //32
//設(shè)置importSettings
TextureImporter importer =
AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(texture)) as TextureImporter;
if (importer == null) continue;
importer.SetPlatformTextureSettings(platformSettings);
//Apply 設(shè)置
importer.SetPlatformTextureSettings(platformSettings);
//保存資源
importer.SaveAndReimport();
}
catch (Exception ex)
{
Debug.Log( $" ~~~~~error~~~~~ 設(shè)置報(bào)錯(cuò):{ex.Message}");
}
}
}
/// <summary>
/// 獲取圖片的分辨率,取分辨率中高寬的最大值,然后返回圖片的【MaxSize】
/// MaxSize的定義:assets->Image->【Texture2D ImportSettings】->【Override For WebGL】->【Max Size】
/// 區(qū)間:16,32,64,128,256,512,1024,2048,4096,8192,16384
///
/// 舉例:圖片分辨率 = 12 * 24,那么圖片的MaxSize = 32
/// </summary>
/// <param name="texture"></param>
/// <returns></returns>
static int GetMaxSize(Texture2D texture)
{
//分辨率區(qū)間的預(yù)備
var start = new List<int> { 0, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384 };
var end = new List<int> { 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 100000 };
var zones = start.Zip(end, (item1, item2) => (startIdx: item1, endIdx: item2)).ToList();
//取分辨率高寬的最大值
var size = new List<int> { texture.width, texture.height }.Max(); //取【寬】【高】中的最大值
//判斷所屬的區(qū)間
var maxSize = zones
.First(x => x.startIdx <= size && size <= x.endIdx)
.endIdx;
//Debug.Log($"圖的分辨率 = {texture.width} * {texture.height} size = {size}, MaxSize = {maxSize}");
return maxSize;
}
}
到了這里,關(guān)于Unity減少發(fā)布打包文件的體積(二)——設(shè)置WebGL發(fā)布時(shí)每張圖片的壓縮方式的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!