ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Unity 的资源导入:为什么源文件“不能直接用“,以及 Library 里到底藏了什么

Unity 的资源导入:为什么源文件“不能直接用“,以及 Library 里到底藏了什么 从一个反常识的事实说起你把一张hero.png拖进 Unity 的 Assets 文件夹它出现在项目里你在场景里用上它一切看起来天经地义。但这里有个事实第一次听会觉得有点反常识你拖进去的那张 png游戏运行时其实根本没在用它。真正被加载进显存、渲染到屏幕上的是另一份你从来没直接见过的文件——它躺在Library/文件夹里。换句话说你在 Project 窗口里点的那个资源和引擎实际吃进去的东西是两码事。中间隔着一道叫Import导入的工序。这篇我想把这道工序讲透为什么源文件不能直接用导入到底做了什么那个神秘的Library/里装的是什么搞懂它你不仅能理解上一篇说的首次导入为什么那么慢还能明白一堆日常现象背后的原因——为什么.meta文件不能删、为什么Library不能提交、为什么改个贴图设置要等一下。核心矛盾源文件是给人用的引擎要的是给机器用的先回答最根本的问题png 好好的为什么引擎不认因为png、fbx、wav 这些格式是为人和通用软件设计的不是为游戏运行时设计的。两者的需求根本对不上。拿贴图举例。一张 png它是为了通用、为了无损存储、为了让 Photoshop 能打开而设计的它用的压缩算法PNG 的 DEFLATE是CPU 解压的GPU 根本读不懂游戏运行时GPU 需要的是它自己能直接采样的压缩格式——移动端是 ASTC/ETCPC 是 DXT/BC 这类。png 的世界给人/通用软件 无损、通用、Photoshop 能开、CPU 解压 ✗ 对不上 GPU 的世界给运行时 ASTC / ETC / DXTGPU 硬件直接采样无需 CPU 解压如果引擎直接用 png运行时每帧都得用 CPU 把它解压成原始像素、再传给 GPU——又慢又占内存。所以必须提前把 png 转成 GPU 原生的压缩格式。这个提前转换就是导入。模型fbx、音频wav也是同理fbx是给 3D 软件交换数据用的里面一堆运行时不需要的东西导入时要把它拆成引擎的网格Mesh、骨骼、动画数据还要做优化合并顶点、生成 LOD 等。wav是无压缩的原始波形体积巨大导入时要按你的设置转成 Vorbis/MP3 之类的压缩格式或者决定是否流式加载。一句话总结这个矛盾源文件优先考虑通用和可编辑运行时优先考虑高效和省资源。导入就是从前者到后者的翻译。导入做了什么一次翻译 归档理解了为什么再看导入具体干了什么。它其实做了两件事第一件格式转换翻译。就是上面说的把 png→GPU 压缩纹理fbx→引擎网格wav→压缩音频。转换的规则由你在 Inspector 里的导入设置决定——比如贴图选什么压缩格式、要不要生成 Mipmap、模型要不要导入动画。第二件分配一个永久身份证——GUID。这一步极其关键却最容易被忽略。导入一个资源时Unity 会给它生成一个全局唯一的 ID叫GUID并把它连同导入设置一起写进一个和源文件同名的.meta文件里。Assets/ ├── hero.png ← 你拖进来的源文件 └── hero.png.meta ← 导入时自动生成里面记着 · guid: 8f3a2b...这张图的唯一身份证 · 导入设置压缩格式、Mipmap 等为什么需要 GUID因为 Unity 内部所有的引用靠的都是 GUID而不是文件路径或文件名。想象一下一个预制体用了 hero.png。Unity 记录这个引用时记的不是Assets/hero.png这个路径而是 hero.png 的 GUID。这样带来一个巨大的好处你把 hero.png 改名成 player.png、或移到别的文件夹 → 路径变了、名字变了 → 但 .meta 里的 GUID 没变 → 所有引用它的地方照样找得到引用不断这就是为什么 Unity 里改名、移动资源不会导致引用丢失——引用绑的是 GUID不是路径。而 GUID 存在.meta文件里。这也直接解释了一条铁律.meta文件必须和源文件一起提交到 Git绝对不能删。你删了.metaUnity 会重新生成一个新的 GUID于是所有原来指向这个资源的引用全部失效——预制体上的贴图变成粉红、脚本上拖的引用变成 None。这是新手最常踩的坑之一。Library 里到底装了什么现在回答那个悬念Library/里到底是什么Library/装的就是导入的产物——那些转换后的、引擎运行时真正使用的文件。也就是本文开头说的你从没直接见过的那份文件。你的项目 ├── Assets/ ← 你操作的世界源文件 .meta │ ├── hero.png │ └── hero.png.meta │ └── Library/ ← 引擎的世界导入产物缓存 └── ...转换后的 GPU 纹理、网格数据等按 GUID 组织把这两个文件夹的关系理清很多事就通了Assets 是源Library 是编译结果。这个关系和编程里源代码 vs 编译产物一模一样源代码 → 编译 → 可执行文件 Assets → 导入 → Library由此推出几条重要结论结论一Library 可以随时删删了会自动重建。它就是缓存是能从 Assets 重新生成的产物。这也是为什么删掉 Library 重开 Unity是经典的排障手段——相当于清理后重新编译。代价就是上一篇说的重建 全量重新导入 首次那种漫长等待。结论二Library 绝不能提交到 Git。它是产物不是源而且体积巨大大项目几个 GB 到几十 GB、内容和机器/平台相关。提交它既臃肿又会引发冲突。.gitignore里必须屏蔽Library/。结论三这正是上一篇首次导入慢、之后免费的原因。首次打开项目Library 是空的所有资源都得从 Assets 现场编译进 Library之后 Library 有了缓存只有你改动过的资源才重新导入。结论四Cache Server / Accelerator 共享的就是 Library 的内容。团队里一个人导入过Library 产物上传到服务器别人打开项目直接下载现成的产物不用各自从头编译。这就是治首次导入慢的原理。什么时候会触发重新导入既然导入有缓存那什么情况下 Unity 会判定这个资源得重新导入搞懂这个你就能理解那些莫名其妙又开始导入了的时刻。主要有三种触发条件① 源文件变了 你在 Photoshop 改了 hero.png 存盘 → Unity 检测到文件内容变化 → 重新导入 ② 导入设置变了 你在 Inspector 把压缩格式从 ASTC 6x6 改成 4x4 → .meta 里的设置变了 → 用新设置重新导入 ③ 导入器本身变了 你升级了 Unity 版本或改了自定义的 AssetPostprocessor 脚本 → 导入逻辑变了 → 相关资源可能全部重新导入第③点尤其要注意升级 Unity 版本经常触发大规模重新导入因为新版本的导入器可能改了行为Unity 为保险起见会重导。这就是为什么升级引擎后第一次打开项目往往要等很久——不是升级慢是升级后的全量重导入慢。一张图收束整个机制┌─────────────── 你的世界Assets/────────────────┐ │ │ │ hero.png ←你拖进来、你在 PS 里改的、你能看见的 │ │ hero.png.meta ← GUID身份证 导入设置 │ │ │ └───────────────────────┬────────────────────────────┘ │ Import导入 翻译 归档 │ · 按 .meta 的设置转成 GPU 格式 │ · 结果按 GUID 存放 ▼ ┌─────────────── 引擎的世界Library/──────────────┐ │ │ │ 转换后的 GPU 纹理 / 网格 / 压缩音频 │ │ ← 运行时真正加载的是这些 │ │ ← 缓存可删可重建绝不提交 Git │ │ │ └────────────────────────────────────────────────────┘ 引用关系预制体/场景/脚本 ──靠 GUID──→ 找到资源 所以改名移动不断链结语回到开头那个反常识的事实——你用的从来不是那张 png 本身现在应该清楚它背后的完整机制了源文件不能直接用因为 png/fbx/wav 是给人和通用软件设计的而运行时需要 GPU 原生格式两者需求对立中间必须有导入来翻译。导入做两件事把源文件翻译成引擎格式以及给资源发一张叫 GUID 的身份证存在.meta里——后者让 Unity 的引用绑定到身份而非路径所以改名移动都不断链。Library 是导入的产物是编译结果而非源因此它可删可重建、绝不提交 Git也正是它承载了首次导入慢、之后免费的缓存机制。理解了这套Assets 是源、Library 是产物、.meta 存身份的三角关系一大堆 Unity 日常谜团就自动解开了为什么.meta不能删、为什么 Library 不进版本库、为什么删 Library 能排障、为什么升级引擎后要等半天、为什么 Cache Server 能加速团队协作。它们不是一堆需要死记的规则而是同一个机制在不同侧面的自然结果。看懂了导入你就从按教程操作升级成了理解 Unity 为什么这么设计。
返回列表