在游戏开发或UI设计过程中,我们经常需要处理大量图片资源。最近我在制作一个2D像素风游戏时,就遇到了一个典型问题:美术提供的原始素材尺寸和像素风格不统一,有的图片分辨率过高导致像素感不足,有的则存在边缘锯齿问题。手动一张张调整不仅效率低下,还容易出错。
Unity虽然内置了图片导入设置,但面对上百张素材时,逐个配置Texture Type、Filter Mode等参数依然是个体力活。更麻烦的是,不同用途的图片需要不同的压缩设置——角色精灵图需要保持锐利边缘,背景图则可以适当模糊。这时候就需要一套自动化方案来批量处理图片像素。
经过对比测试,我最终确定了基于Unity Editor脚本的解决方案。相比外部工具(如Photoshop脚本),直接在Unity中处理有以下优势:
核心处理流程分为三个步骤:
在Unity中控制图片像素表现的核心参数包括:
对于像素风游戏,通常建议配置:
csharp复制textureImporter.textureType = TextureImporterType.Sprite;
textureImporter.filterMode = FilterMode.Point;
textureImporter.textureCompression = TextureImporterCompression.Uncompressed;
在Unity项目中创建Editor/PixelArtProcessor.cs:
csharp复制using UnityEditor;
using UnityEngine;
using System.IO;
public class PixelArtProcessor : EditorWindow
{
[MenuItem("Tools/批量处理像素图片")]
static void Init()
{
var window = GetWindow<PixelArtProcessor>();
window.Show();
}
void OnGUI()
{
if (GUILayout.Button("处理选中文件夹"))
{
ProcessSelectedFolder();
}
}
static void ProcessSelectedFolder()
{
// 获取选中的文件夹路径
string folderPath = AssetDatabase.GetAssetPath(Selection.activeObject);
if (!Directory.Exists(folderPath)) return;
// 遍历所有图片文件
string[] files = Directory.GetFiles(folderPath, "*.*", SearchOption.AllDirectories)
.Where(f => f.EndsWith(".png") || f.EndsWith(".jpg")).ToArray();
foreach (string file in files)
{
ProcessSingleTexture(file);
}
AssetDatabase.Refresh();
Debug.Log($"处理完成,共修改{files.Length}张图片");
}
}
csharp复制static void ProcessSingleTexture(string path)
{
TextureImporter importer = AssetImporter.GetAtPath(path) as TextureImporter;
if (importer == null) return;
// 基础设置
importer.textureType = TextureImporterType.Sprite;
importer.spriteImportMode = SpriteImportMode.Single;
importer.mipmapEnabled = false;
importer.filterMode = FilterMode.Point;
importer.textureCompression = TextureImporterCompression.Uncompressed;
// 根据用途设置不同参数
if (path.Contains("/Characters/"))
{
importer.spritePixelsPerUnit = 32;
importer.maxTextureSize = 512;
}
else if (path.Contains("/Backgrounds/"))
{
importer.spritePixelsPerUnit = 16;
importer.maxTextureSize = 1024;
}
EditorUtility.SetDirty(importer);
importer.SaveAndReimport();
}
对于像素风游戏,保持统一的像素密度至关重要。我们可以添加自动计算功能:
csharp复制int CalculateOptimalSize(Texture2D tex, int baseSize)
{
// 取较小边作为基准
int minSide = Mathf.Min(tex.width, tex.height);
// 计算最接近baseSize的整数倍
return Mathf.RoundToInt(minSide / (float)baseSize) * baseSize;
}
对于需要真正修改像素数据的场景(而不仅是导入设置),可以使用Texture2D的API:
csharp复制Texture2D ResampleTexture(Texture2D source, int newWidth, int newHeight)
{
RenderTexture rt = RenderTexture.GetTemporary(newWidth, newHeight);
Graphics.Blit(source, rt);
Texture2D result = new Texture2D(newWidth, newHeight);
RenderTexture.active = rt;
result.ReadPixels(new Rect(0, 0, newWidth, newHeight), 0, 0);
result.Apply();
RenderTexture.ReleaseTemporary(rt);
return result;
}
修改未生效:
SaveAndReimport()内存不足:
EditorUtility.UnloadUnusedAssetsImmediate()边缘锯齿:
AssetDatabase.StartAssetEditing()和AssetDatabase.StopAssetEditing()包裹批量操作重要提示:处理前务必备份项目!批量操作不可撤销,建议先在测试项目验证效果。
最近一个2D平台游戏项目中,我们使用这套方案处理了387张美术资源,将处理时间从预估的6小时人工操作缩短到3分钟自动执行。关键配置如下:
| 资源类型 | Pixels Per Unit | Max Size | Filter Mode | 压缩格式 |
|---|---|---|---|---|
| 角色精灵 | 32 | 512 | Point | RGBA32 |
| 场景元素 | 16 | 1024 | Point | RGB24 |
| UI图标 | 64 | 256 | Bilinear | RGBA32 |
实施后发现两个意外收获:
这套方案后来被团队标准化,作为新项目的初始化流程之一。根据项目需求,我们还扩展了自动生成Sprite Atlas的功能,进一步优化运行时性能。