开发平台:Unity 2020 版本以上
编程平台:Visual Studio 2020 版本
编程语言:CSharp
前言
Unity 开发者不仅是要求在面对开发需求上有着预见性的目光与能力去应对各种功能实现。更加注重的是通过各个项目的开发类型与过程,总结一套利于缩短开发流程的重要工具链。本文将重点关于 Unity 开发流程中,如何缩短外部导入纹理配置这一过程进行设计分享与思路解读。
思考:为什么要优化 Texture 外部导入流程?
Texture 是 Unity 使用频率高且参与重要的资产类对象。决定工程将以何种画面风格呈现于玩家用户。而实际上,并非所有的 Texture 资产均准备完毕。开发的过程往往伴随 已有Texture 基础上进行开发。且为区别各类 Texture 的应用场景,分别放置于不同子目录下。那么,为什么会认为 Texture 外部导入流程是如此麻烦?
- 一套标准的 Texture 导入流程
- 导入 Texture 资源
- 选中 Texture 资源
- 配置 Texture 相关参数并应用
- 每一次新的 Texture 资源导入,都需要重新配置。对异常的 Texture 还需更多调整与应用。
思考:如何优化 Texture 外部导入流程?
Unity 开发者最重要的是保持一种 程序 思维。例如:打开工程目录 —— 右键 Project/Show In Browsers 菜单项。我们同样可以仿照该方法去简化这一流程。于是如何获取外部导入资产成为了当前解决问题的首要目标!(不用想了,Unity 提供了 TextureImporter 的可序列化资产!那必然是有关于 TextureImporter 类可声明使用!)
什么是 Texture Importer ?
答:Unity 引擎针对外部 Texture 导入配置的管理类。其内容匹配资产目录下Texture对应的详细配置信息。
如何创建 Texture Importer 资产 与 配置默认预设 ?
为什么还需要开发 批处理 工具?Texture Importer 的已有配置不应满足本文目的?
并非每一次的预设都是绝对无问题的。对于部分 PNG类型的 Texture 对象,仅支持 RGB32位,对于这部分的纹理处理,Unity 的 Auto 选项并不会择优处理。仍需要开发者手动完成调节。因此,考虑到 Texture Importer 预设 类型的多样性。开发批处理工具是显得尤为必要的。
工具开发的宗旨是便利化开发过程,缩短开发工时。而非复杂化开发过程。既然是一键完成任务目标的功能,应当考虑开放样式配置内容。与一键应用预设的功能。最常见的是 右键扩展菜单 完成所有操作。工具栏开放菜单,以更好配置预设内容。
程序:实现 Mune 扩展
[MenuItem("Assets/资产管理/一键 Texture 转 Sprite", false, 0)]
public static void DoTexture2Sprite()
{
// Texture 转 Sprite 方法内容
}
- 核心API:
MenuItem()
—— 更多解释见 Unity 中文文档解释。 - 注意项:应用于资产管理,期望于修改 Project 目录下内容,选择 “Assets” 作为路径头。
程序:核心API
第一步:思考 - 获取 需参与转变 的 资产对象
AssetImporter.GetAssetAtPath(string path);
在 Unity 中,所有参与的资产对象,均可通过 AssetDatabase
访问,但对于一些需要处理后运用于场景内对象的部分资产,需要 AssetImporter.GetAssetAtPath(string path)
以转换为可用的 AssetImporter 类型以便处理。于是,如何获取路径下资产对象路径是接下来重要解决的问题。
关于 Asset Importer 的更多说明
解释:这是 Unity 针对导入 Unity Editor 的特定资源的基类。基于该基类,派生出 PluginImporter、TextureImporter 等资源导入类。在后面为解决 Texture 转 Sprite 提供保障。
第二步:思考 - 获取 目录下所有资产路径
System.IO.Directory.GetFils(string path, string filter, SearchOption thisOption);
在获取资产路径上,Unity 并未提供可用的检索资产目录的API。但并不妨碍我们使用 System.IO
作为替代方式,获取目录下所有路径信息。该 API 提供 Dirctory.GetFiles()
方法,针对使用需求,帅选需求类型的文件,并返回路径。并且在处理子嵌套目录路径文件上,提供 SearchOption.AllDirectories
项获取目录路径下所有子文件(根子文件与非根子文件)的路径信息。
第三步:思考 - 判断资产对象是否为期望修改资产对象?
public bool IsTextureAsset()
{
var thisAsset = AssertImporter.GetAtPath("This is a example text");
return thisAsset as TextureImporter == null
}
TextureImporter
作为 AssetImporter
的派生类,负责 Texture 资产的导入工作。类似 UnityWebRequest
中针对 Texture、Audio 等类型的资源下载,有 DownloadHandlerBuffer、DownloadHandlerTexture、DownloadHandlerAudioClip、DownloadHandlerAssetBundle、DownloadHandlerScript 的下载类型。
如果该类型资源不属于 转换对象 资源类型,将会返回 Null
以区分。
第四步:应用 Texture Importer 预设
public void OnApplyToThis(TextureImporter thisImporter)
{
thisImporter.textureType = TextureType.Sprite;
// ......
}
预设 API 参考 文档:TextureImporter API 中文文档 。 在 API 选择上,建议参考 Editor 中 Inspector 面板展示的元素项。值得注意:在不同 Unity 版本中,TextureImporter 的 API 或多少的存在变动。一切以实际版本中 TextureImporter 预设视图展示元素为主。
TextureImporter.SaveAndReimport();
仅修改 预设文件,是无法使用新样式设计。需要存储后才可使用。毕竟在 Inspector 窗口进行预设调整后,也需要 ”Apply“ 已完成与应用预设。换在程序中,也应当添加上述行设计。
回顾:关于此类设计的拓展
使用程序化配置设定集,在针对普通 Texture 上足以应付。但真的合适吗?我们注意到 TextureImporter 预设窗展示格式是存在一定关联的属性对象群体。根据其选项,衍生出符合或与之匹配的选项,在应对极端情况下的 Texture 处理,显得捉襟见拙。有没有什么方式,拓展其内容的可视化配置?
答:使用 EditorWindow 视窗建立可配置项。
public class TextureImporterEditorWindow : EditorWindow
{
[MenuItem("Tools/Texture Importer/Open Custom Windown")]
private static void CreateWindow()
{
var thisWindow = GetWindow<TextureImport>();
thisWindow.textContent.text = "Texture Importer";
thisWindow.Show();
}
static TextureImporterType TIType;
public override void OnInspectorGUI()
{
TIType = EditorGUILayout.EnumFlagsField("This is a enum flag title", TIType);
//...
if (GUILayout.Button("一键转换")) { //...应用于设 }
}
}
编写 Editor Window 需要了解 EditorGUILayout
、GUILayout
、EditorGUI
、GUI
这四类 API,以更好的优化编辑窗口。搭配此窗口灵活修改预设信息以更好解决 Texture 导入需求。
设计中的不足点
或许应对需求情况,Editor Window 与 右键快捷菜单 提供了较为方便的设置与预设应用。但存在仍然需要部署至少一个默认配置项,有时候期望的预设项并非适用于个人期望。制作类似 Texture Importer 资产形式以应用预设或许是更加方便的事情。那么 SriptablObject
将无疑是最佳最优秀的预设设计。参考 Unity 默认 Texture Importer 提供的设定 default 的快捷入口,可否直接建立 多类型资产预设,直接应用反而比程序设计更好,但对已导入 Texture 或许程序设计的工具更合适。