在 Unity 專案中,部分 texture 的 .meta 檔案每次開啟 Editor 後都會自動出現變動,即使執行 git discard 還原,下次開啟 Unity 仍然會重新產生相同的 diff。

變動內容固定是在 platformSettings 區塊新增一段 Android override:

- serializedVersion: 4
  buildTarget: Android
  maxTextureSize: 2048
  resizeAlgorithm: 0
  textureFormat: -1
  textureCompression: 1
  compressionQuality: 50
  crunchedCompression: 0
  allowsAlphaSplitting: 0
  overridden: 0
  ignorePlatformSupport: 0
  androidETC2FallbackOverride: 0
  forceMaximumCompressionQuality_BC6H_BC7: 0

這個 overridden: 0 代表這段 override 並沒有自訂任何值,全是預設,這點微妙。

本地還有個環境沒有這個問題,但兩個都是 clone 相同 repo,并且 unity 版本號一致,後面開始做檢查。

1. 初步懷疑:Active Build Target

第一個懷疑的方向是 Active Build Target 被切到 Android,因為 Unity 在切換平台時會對所有 texture 重新 import 並寫入平台設定。

排除: 確認 File → Build Settings 中 active platform 是 Windows Standalone,並非 Android。

2. 對照實驗:同機器、同版本的另一個專案

在同一台電腦上有另一個 clone(HSLR_5),使用完全相同的 Unity 版本(6000.0.58f2),看起來沒有這個問題。

實際結果: HSLR_5 也有相同問題,只是數量較少(1~3 個 vs 36 個)。差異在於被觸發 reimport 的資源數量不同。

3. 然後忽然發現一件事情,並非所有 .meta 都受影響,這點尤爲重要

比較受影響和不受影響的 .meta 檔:

檔案 git 中的 platformSettings 會被自動修改?

big_item_2.png.meta DefaultTexturePlatform, Standalone 不會
big_item_3.png.meta DefaultTexturePlatform, Standalone, WebGL 會

規律:只有已經存在非預設 platform override(如 WebGL)的 .meta 檔,才會被 Unity 自動補上 Android override。

只有 DefaultTexturePlatform + Standalone 的檔案不受影響。

4. 測試了修改 buildTarget、ProjectSetting...等,比對兩項目始終沒有太大進展,後來想到查看 Editor.log

從 Unity 的 Editor.log 可以看到啟動時的 import 行為:

Asset File Changes: new=0, changed=11, moved=0, deleted=0
Imports: total=11 (actual=11, local cache=0, cache server=0)

Unity 在啟動時主動判定這 11 個檔案為「changed」並觸發 reimport,但使用者並沒有修改任何東西。每個檔案都經過 TextureImporter 重新處理,這就很有趣了,并不是 TextureImporter 造成的,一開始我還以爲是新寫的 BC7 轉換器造成的。

Start importing Assets/Resources/game/ui/atlas/big_item_3.png
using Guid(...) (TextureImporter) -> (artifact id: '...') in 0.229 seconds

根因分析

完整觸發流程:

Unity Editor 啟動
  → 比對 .meta 的 import settings 和 Library cache 中的 artifact
  → 發現 .meta 中有 WebGL platform override
  → 但 Library artifact 缺少 Android 平台資訊(因為安裝了 Android Build Support module)
  → 判定 artifact 過期,觸發 reimport
  → TextureImporter 執行,將所有已安裝平台的 override 補齊
  → Android override 被寫入 .meta
  → git 偵測到 .meta 變動

這就造成我不管 discard 多少次,永遠都會回復造成變動,那好,大概也有思路了,應該是某次我爲了打包 webgl 版本後來可能連帶添加了 android module 支持造成的,至於爲什麽某些檔案才有問題,我們就不深究了

解決方案

既然問題出在項目執行曾經加入過 android module,那就索性移除 android module,後來測試發現確實有效果,變動的檔案discard掉之後不會再次添加 android 支持了。

我沒有選擇清除 library cache 主要在於,這個情況并非一致性的,如果全部檔案都會因此變動那是可以統一項目的狀態,并且更新 .meta 上去,但問題在於是否修改 .meta 這件事有點複雜,如果即不能保證最終所有成員的檔案變更一致,那何必追求 unity module 的一致呢。

好的問題到此也解決就好。

無標籤

新增評論