---
# System prepended metadata

title: Addressable & SpriteAtlas
tags: [Unity, Addressable, SpriteAtlas]

---

# Addressable & SpriteAtlas
來分享最近 Unity 的一個小小 SpriteAtlas & Addressable 的測試結果


## 先說結論：
如果你的專案要用 SpriteAtlas，且 SpriteAtlas 是使用 Addressable or AssetBundle 來打包
"絕對不要勾選" SpriteAtlas 的 Include In Build，這很有可能使你的包出來的檔案有兩份圖檔

Unity 在打包程執行檔的時候
會根據你的場景等會使用的素材
自動去連結所需要的圖檔
當有場景 or UI 需要用到某一張圖時
Unity 會去判斷是否此圖所在的 SpriteAtlas 有勾選 Include In Build
"並不會去判斷是否存在於 Addressable 的包中"
很有可能造成有兩份相同的檔案
且如果遇到需要 Hot Update 的時候執行檔中的檔案
無法做替換檔案

## 解決方法
以下圖為例子
![](https://i.imgur.com/VNVPf7b.png)
目前看到有兩種解決辦法：
1. (不推薦) 
把 Scene A & UI Image A 等，所有有用到 SpriteAtlas 的物件，全部拉到 Adderssable 中
這樣在找關聯的時候，執行檔就不會包到圖檔(因為沒有關聯)

優點：絕對不會，有重複包的問題，也不用對 SpriteAtlasManager 做多餘的處理
缺點：只要有一個東西有漏，就有可能造成兩份資料

2. (推薦)
直接取消勾選 SpriteAtlas 的 Include In Build
在遊戲的一開始使用 註冊以下事件
```C#
void Awake()
{
    SpriteAtlasManager.atlasRegistered += AtlasRegistered;
}
void OnDestroy()
{
    SpriteAtlasManager.atlasRegistered -= AtlasRegistered;
}
void AtlasRegistered(string name, Action<SpriteAtlas> callBack)
{
    // Addressable Name
    AsyncOperationHandle<SpriteAltas> handle = Addressable.LoadAssetAsync<SpriteAltas>(name);
    yield return handle;
    if(handle.Status == AsyncOperationStatus.Succeeded)
        callBack(handler.Result);
}
```
當執行檔執行到需要這張圖，且不在執行黨內，Load 圖的時候，就會去呼叫 AtlasRegistered
就會跑去 Addressable 把圖載下來


優點：不需要手動管理所有需要用到 SpriteAtlas 的檔案，方便許多
缺點：從 adb logcat or xcode上，會先跳出一些 Warnning (可忽略)

## 實際案例
遊戲中的圖檔總共有 276 MB，Addressable 打包完是 88.4 MB(內含多張 SpriteAtlas & 場景)
以下是遊戲檔案 可以差到 **50MB !!** 
(使用 Include In Build 為 181 MB，使用方法2為下方的 134 MB)
![](https://i.imgur.com/3Qqk3cG.png)


###### tags: `Unity` `Addressable` `SpriteAtlas`