FishPlayer

一个喜欢摸鱼的废物

0%

Unity Library Artifacts 目录下的文件初看!

Library 目录下有大量的缓存文件。其中包含着导入进项目里的资源文件以及一些导入资源后产生的用于文件(可能是用于记录关系或是一些关于资源的额外的缓存数据?)。

每当有资源导入/刷新修改时,Library 都会有文件发生变更(增删改)。

Artifacts 目录

Unity 提供了一个工具可以把 Artifacts 里的文件转成人话

C:\Program Files\Unity\Hub\Editor\UNITY_VERSION\Editor\Data\Tools\binary2text.exe

Artifacts 目录下存放各个资源在导入阶段后期生成的缓存文件。似乎这些文件由资产的哈希值作为键来命名。这些文件在 Unity 内部被称为 producedFiles (在 Log 中使用改名字称呼这些文件;但在AssetV2中似乎已经没有这个东西)。

为什么 Libraray 目录会比 Asset 大很多,其中一个原因是这样的。以脚本文件举例,在这个缓存文件中,不仅仅有该脚本的代码文本,同时还以文本的形式记录着该资产相关的一些ID,以及资产的存储类型?。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
ID: 3 (ClassID: 1035) MonoImporter
m_ObjectHideFlags 0 (unsigned int)
m_CorrespondingSourceObject (PPtr<EditorExtension>)
m_FileID 0 (int)
m_PathID 0 (SInt64) // signed long?
m_PrefabInstance (PPtr<PrefabInstance>)
m_FileID 0 (int)
m_PathID 0 (SInt64)
m_PrefabAsset (PPtr<Prefab>)
m_FileID 0 (int)
m_PathID 0 (SInt64)
m_Name "" (string)
m_ExternalObjects (map)
size 0 (int)

m_UsedFileIDs (set)
size 1 (int)
data (SInt64) #0: 11500000
m_DefaultReferences (vector)
size 0 (int)

executionOrder 0 (SInt16)
icon (PPtr<Texture2D>)
m_FileID 0 (int)
m_PathID 0 (SInt64)
m_UserData "" (string)
m_AssetBundleName "" (string)
m_AssetBundleVariant "" (string)


ID: 11500000 (ClassID: 115) MonoScript
m_ObjectHideFlags 0 (unsigned int)
m_CorrespondingSourceObject (PPtr<EditorExtension>)
m_FileID 0 (int)
m_PathID 0 (SInt64)
m_PrefabInstance (PPtr<PrefabInstance>)
m_FileID 0 (int)
m_PathID 0 (SInt64)
m_PrefabAsset (PPtr<Prefab>)
m_FileID 0 (int)
m_PathID 0 (SInt64)
m_Name "IntEqualBehaviour" (string)
m_Script "using UnityEngine;

" (string) // 资产的存储类型?
m_DefaultReferences (map)
size 0 (int)

m_Icon (PPtr<Object>)
m_FileID 0 (int)
m_PathID 0 (SInt64)
m_ExecutionOrder 0 (int)
m_ClassName "IntEqualBehaviour" (string)
m_Namespace "Core.UI" (string)

这是一条导入的Log.

[Worker0] Start importing Assets/Script/UI/Core/PrimitiveBehaviour/IntEqualBehaviour.cs using Guid(ce9400962fc00544a89e0e69c863b84c) Importer(815301076,1909f56bfc062723c751e8b465ee728b) [Worker0] -> (artifact id: ‘840ab621654cd480e1699784fa88cf93’) in 0.005725 seconds

‘ce9400962fc00544a89e0e69c863b84c’ 是该脚本作为资产的GUID,和meta文件中的GUID一致。
Importer(815301076,1909f56bfc062723c751e8b465ee728b) 猜测为指向倒入该资源使用的导入器类型,以及该导入器作为 Asset 时候的GUID。

如下代码用于追踪某个资产在 Artifacts 中的键名和位置。

1
2
3
string guidString = AssetDatabase.AssetPathToGUID(assetPath);
string hash = AssetDatabaseExperimental.GetArtifactHash(guidString);
AssetDatabaseExperimental.GetArtifactPaths(hash, out var paths);

缓存损坏处理

这个问题造成的原因很多,但是基本就是 Artifacts 里的关于资产的缓存文件坏了。其表现就是那个资产的图标变成白纸,然后无法使用了。
但是有时候对着这个资产点击 Reimport 并不能解决问题。

我认为正确的思路就是把这个坏的缓存杀掉,再生成一个新的

  1. 只有几个资产的缓存坏掉的情况,可以把这几个资产从项目中拿出来。刷新项目,再把资产放回去,重新生成缓存。
  2. 有多个资产缓存爆炸的情况,需要先收集资产列表,然后用上面的代码追溯所有坏掉的缓存并杀掉,再重新导入这些资产。(只是猜测,并未实践过。因为这个情况很少见,感觉不如直接把Library杀了全部重刷下班吃饭)

资料来源

网上找到的活爹