项目内存占用比较高,前期并没有设置图片的压缩格式,想写一个方法批量修改,参考网上的文章,在自己做的过程中遇到些问题在这里记录一下
1、路径里面Replace("/",@"\")替换原来路径中的反斜杠,不然找不到资源
2、我用的Unity2019.4 需要用TextureImporterPlatformSettings来设置相应属性,这里遇到个坑,我直接New一个对象出来,结果 Override for Android始终不会设置为true
下面是我完整的代码,顺便实现了图片导入时自动设置压缩格式,目前只测了Android环境的部分。
参考文章:
https://www.cnblogs.com/sanyejun/p/10259766.html
https://www.xuanyusong.com/archives/4663
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using UnityEditor;
using UnityEngine;
public class AutoSetTexture : EditorWindow
{
[MenuItem("Tools/批量设置选中节点下图片压缩格式")]
static void AutoSetASTC()
{
string[] guidArray = Selection.assetGUIDs;
foreach (var item in guidArray)
{
string selectFloder = AssetDatabase.GUIDToAssetPath(item);
DirectoryInfo root = new DirectoryInfo(selectFloder);
GetFloder(root);
}
}
static void GetFloder(DirectoryInfo root)
{
GetFile(root);
//查找子文件夹
DirectoryInfo[] array = root.GetDirectories();
//Debug.Log(root);
foreach (DirectoryInfo item in array)
{
GetFloder(item);
}
}
static void GetFile(DirectoryInfo root)
{
//DirectoryInfo root = new DirectoryInfo(path);
FileInfo[] fileDic = root.GetFiles();
foreach (var file in fileDic)
{
//Debug.Log(file);
if (file.FullName.EndsWith(".png") || file.FullName.EndsWith(".jpg") || file.FullName.EndsWith(".tga") ||
file.FullName.EndsWith(".psd") || file.FullName.EndsWith(".PSD") || file.FullName.EndsWith(".exr") ||
file.FullName.EndsWith(".tif"))
{
//Debug.Log("-------------" + file.FullName);
//Debug.Log(Application.dataPath);
//Debug.Log(Application.dataPath.Replace("Assets", ""));
SetPicFormat(file.FullName.Replace(Application.dataPath.Replace("Assets", "").Replace("/",@"\"), ""));
}
}
}
static void SetPicFormat(string path)
{
//Debug.Log(path);
TextureImporter importer = AssetImporter.GetAtPath(path) as TextureImporter;
//判断图片大小
Texture2D texture = AssetDatabase.LoadAssetAtPath<Texture2D>(path);
if (texture != null)
{
int textureSize = Mathf.Max(texture.height, texture.width);
//Debug.Log(textureSize);
int SizeType = FitSize(textureSize);
//设置图片压缩格式
SetPlatformSettings(importer, SizeType);
}
else
{
Debug.Log("Texture2D为null:" + path);
}
}
/// <summary>
/// 设置图片平台压缩格式
/// </summary>
/// <param name="importer">导入对象</param>
/// <param name="sizeType">尺寸类型(512,1024...)</param>
public static void SetPlatformSettings(TextureImporter importer, int sizeType)
{
//参考 https://www.xuanyusong.com/archives/4663
TextureImporterPlatformSettings setParam = new TextureImporterPlatformSettings();
TextureImporterFormat defaultAlpha;
TextureImporterFormat defaultNotAlpha;
#if UNITY_IOS
//ios版本
setParam = importer.GetPlatformTextureSettings("iOS");
setParam.maxTextureSize = sizeType;
bool isPowerOfTwo = IsPowerOfTwo(importer);
defaultAlpha = isPowerOfTwo ? TextureImporterFormat.PVRTC_RGBA4 : TextureImporterFormat.ASTC_RGBA_4x4;
defaultNotAlpha = isPowerOfTwo ? TextureImporterFormat.PVRTC_RGB4 : TextureImporterFormat.ASTC_RGB_6x6;
setParam.overridden = true;
setParam.format = importer.DoesSourceTextureHaveAlpha() ? defaultAlpha : defaultNotAlpha;
importer.SetPlatformTextureSettings(setParam);
#endif
#if UNITY_ANDROID
//安卓版本
setParam = importer.GetPlatformTextureSettings("Android"); //必须用Get方法得到,否则Override for Android不会被设为true
setParam.maxTextureSize = sizeType;
setParam.overridden = true;
setParam.allowsAlphaSplitting = false;
bool divisible4 = IsDivisibleOf4(importer);
defaultAlpha = divisible4 || importer.textureType == TextureImporterType.Sprite ? TextureImporterFormat.ETC2_RGBA8 : TextureImporterFormat.ASTC_RGBA_4x4;
defaultNotAlpha = divisible4 || importer.textureType == TextureImporterType.Sprite ? TextureImporterFormat.ETC2_RGB4 : TextureImporterFormat.ASTC_RGB_6x6;
setParam.format = importer.DoesSourceTextureHaveAlpha() ? defaultAlpha : defaultNotAlpha;
importer.SetPlatformTextureSettings(setParam);
#endif
importer.SaveAndReimport();
//AssetDatabase.ImportAsset(path);
}
static int[] formatSize = new int[] { 32, 64, 128, 256, 512, 1024, 2048, 4096 };
public static int FitSize(int picValue)
{
foreach (var one in formatSize)
{
if (picValue <= one)
{
return one;
}
}
return 1024;
}
//被4整除
public static bool IsDivisibleOf4(TextureImporter importer)
{
Vector2Int size = GetTextureImporterSize(importer);
return (size.x % 4 == 0 && size.y % 4 == 0);
}
//2的整数次幂
public static bool IsPowerOfTwo(TextureImporter importer)
{
Vector2Int size = GetTextureImporterSize(importer);
return (size.x == size.y) && (size.x > 0) && ((size.x & (size.x - 1)) == 0);
}
//贴图不存在、meta文件不存在、图片尺寸发生修改需要重新导入
public static bool IsFirstImport(TextureImporter importer, string assetPath)
{
Vector2Int size = GetTextureImporterSize(importer);
Texture tex = AssetDatabase.LoadAssetAtPath<Texture2D>(assetPath);
bool hasMeta = File.Exists(AssetDatabase.GetAssetPathFromTextMetaFilePath(assetPath));
return tex == null || !hasMeta || (tex.width != size.x && tex.height != size.y);
}
//获取导入图片的宽高
public static Vector2Int GetTextureImporterSize(TextureImporter importer)
{
Vector2Int result = Vector2Int.zero;
if (importer != null)
{
object[] args = new object[2];
MethodInfo mi = typeof(TextureImporter).GetMethod("GetWidthAndHeight", BindingFlags.NonPublic | BindingFlags.Instance);
mi.Invoke(importer, args);
return (new Vector2Int((int)args[0], (int)args[1]));
}
return result;
}
}
// 继承 AssetPostprocessor 资源管理,用于接收事件
public class AutoSetTextureImport : AssetPostprocessor
{
// 当导入图片资源时,触发该事件
void OnPreprocessTexture()
{
TextureImporter importer = assetImporter as TextureImporter;
if (importer != null)
{
if (AutoSetTexture.IsFirstImport(importer, assetPath))
{
if (importer.mipmapEnabled == true)
{
importer.mipmapEnabled = false;
}
if (assetImporter.assetPath.Contains("Assets/Art/UI"))
{
//UI的图片导入时都设置为sprite
importer.textureType = TextureImporterType.Sprite;
}
Vector2Int tSize = AutoSetTexture.GetTextureImporterSize(importer);
int textureSize = Mathf.Max(tSize.y, tSize.x);
int SizeType = AutoSetTexture.FitSize(textureSize);
//设置压缩格式
AutoSetTexture.SetPlatformSettings(importer, SizeType);
}
}
}
}
-------------------------------------------------------------------------------------------------------
实际运用遇到的问题:
1、Selected texture format 'Unsupported' for platform 'Android' is not valid with the current texture type 'Default'. 有些图报错,暂时跳过
2、在android环境把图片压缩后,profiler中看,内存反而增加了,原来场景贴图4096*4096的图,默认Default的自动压缩,内存占用是16m,现在用etc2压缩,MaxSize设置4096,内存占用是64M,
原来2048*2048内存占用5.3m,maxsize设置2048压缩后内存占用16m,另外cup原来大部分时间在16ms左右,现在都接近66了
3、我将maxsize设置降低一档,比如4069设置为2048,1024设为512,这样再查看profiler,内存确实降下来了,cpu也降下来了,但是图片质量太低,惨不忍睹。
目前我暂时放弃压缩了,使用unity默认设置,有大神知道问题所在,请留言指点,谢谢!
