[Unity3D] Asset Bundle คืออะไร? by

31
Jan
1

Screenshot_2015-01-31-13-35-02

ปกติเราเคยเล่นเกม แล้วเห็นเกมอื่นเขาสั่ง Download Content มาเพิ่มตอนเข้าเกมครั้งแรกไหม? แล้วทำไมเขาถึงไม่รวมเข้าไปให้ดาวน์โหลดตั้งแต่อยู่ใน Store เลยล่ะ? ทำไมต้องแยกให้ผู้เล่นรอโหลดสองรอบ? จริงๆ แล้วส่วนที่ Download เพิ่มก็คือ Asset Bundle นี่เองซึ่งเป็น Content เพิ่มเติมของเกมเช่น ตัวละครใหม่ ไอเท็มใหม่ ด่านใหม่ สำหรับสาเหตุที่จำเป็นต้องใช้ asset bundle คือ

  1. Google Play มีการจำกัดขนาดไฟล์ apk ที่จะให้เอาขึ้น Store ได้ 50 MB และส่วนที่เหลือต้องแยก expansion file ส่วน ios จะจำกัดที่ตัว .app ไม่เกิน 60MB ซึ่งจะทำให้ flow การทำงานไม่เหมือน ios และ android ไม่เหมือนกัน การใช้ Asset Bundle จะมาช่วยจัดการความต่างตรงนี้ได้
  2. เมื่อเรา update เกมเพื่อแก้ไข bug แต่ content รูปภาพต่างๆ ยังเหมือนเดิม ผู้เล่นจะต้อง download ใหม่แค่เพียงตัว app ไม่ต้อง Download content ใหม่ทั้งหมด เพียงเพื่อแก้ไขข้อผิดพลาดเล็กๆ น้อยๆ จาก 500 MB(app รวม content model 3 มิติ รูปภาพ) ลดเหลือ 50 MB (ตัว app อย่างเดียว) จะเป็นจุดต่างอย่างมาก
  3. สามารถเพิ่ม content ใหม่ๆ ได้โดยไม่ต้องเอาขึ้น app store/google play store ซึ่งปกติเวลา approve ของ app store จะเฉลี่ยที่ 7 วัน ทำให้ไม่ต้องรอเวลาตรงนี้ถึงจะปล่อย patch update เกมด่านใหม่ๆ ได้ เพิ่มความสะดวกเป็นอย่างมาก

จะเห็นได้ว่ามีประโยชน์มากจริงๆ ดังนั้นเรามาดูกันว่าจะสร้าง Asset Bundle มาใช้งานได้อย่างไร


// C# Example
// Builds an asset bundle from the selected objects in the project view.
// Once compiled go to "Menu" -> "Assets" and select one of the choices
// to build the Asset Bundle
using UnityEngine;
using UnityEditor;
public class ExportAssetBundles {
   [MenuItem("Assets/Build AssetBundle From Selection - Track dependencies")]
   static void ExportResource () {
      // Bring up save panel
      string path = EditorUtility.SaveFilePanel ("Save Resource", "", "New Resource", "unity3d");
      if (path.Length != 0) {
         // Build the resource file from the active selection.
         Object[] selection = Selection.GetFiltered(typeof(Object), SelectionMode.DeepAssets);
         BuildPipeline.BuildAssetBundle(Selection.activeObject, selection, path,
                      BuildAssetBundleOptions.CollectDependencies | BuildAssetBundleOptions.CompleteAssets, BuildAssetBundleOptions.CollectDependencies , BuildTarget.Android);
         Selection.objects = selection;
      }
   }
   [MenuItem("Assets/Build AssetBundle From Selection - No dependency tracking")]
   static void ExportResourceNoTrack () {
      // Bring up save panel
      string path = EditorUtility.SaveFilePanel ("Save Resource", "", "New Resource", "unity3d");
      if (path.Length != 0) {
         // Build the resource file from the active selection.
         BuildPipeline.BuildAssetBundle(Selection.activeObject, Selection.objects, path, BuildAssetBundleOptions.CollectDependencies , BuildTarget.Android);
      }
   }
}

ให้เรา Copy Code ข้างบนไปเซพไฟล์ใหม่ชื่อ AssetBundleCreator.cs (หรือชื่ออื่นก็ได้) แล้วสร้าง Folder ใหม่ใน Folder Assets ใน project ของเราชื่อว่า Editor นำไฟล์ AssetBundleCreator.cs ไปใส่ด้านใน จากนั้น ให้คลิกเลือก Resource รูปภาพที่จะนำมาสร้างใน tab project ด้านล่าง ต่อด้วยคลิกที่เมนู Asset จะเห็นดังภาพ

AssetBundleMenuOptions

1. Build AssetBundle From Selection – Track dependencies คือสร้าง asset bundle โดยพ่วงเอาทุกอย่างที่เลือกแถมมาด้วย เช่นเลือกรูปภาพ 1 รูปแล้วเลือกเมนูนี้จะได้ Texture2D และ Sprite มาทั้งคู่ใน bundle (แน่นอนว่าขนาดไฟล์ที่ได้จะใหญ่กว่า)
2. Build AssetBundle From Selection – No dependency tracking คือสร้าง asset bundle โดยสร้างแค่เฉพาะของที่ใส่ลงไปใน bundle เช่นเลือกรูปภาพ 1 รูปแล้วเลือกเมนูนี้จะได้ Texture2D อย่างเดียวมาใน bundle

สิ่งที่ต้องระวังในการใช้งาน asset bundle คือตอนสร้างเราจะต้องเลือกสร้างบน platform ใด platform หนึ่งเช่น สั่งสร้าง asset bundle for android ก็จะใช้ได้กับ android เท่านั้น ใช้กับ ios ไม่ได้ ดังนั้นหากต้องการ update content เกมทั้งสอง os จะต้องสร้าง bundle มา 2 ไฟล์แยกกัน โดยแก้ไขส่วนของ BuildTarget.Android เป็น BuildTarget.iPhone ตามแต่ os

สำหรับวิธีเรียกไปใช้งานก็ตาม code ด้านล่าง

using UnityEngine;
using System.Collections;
public class BundleLoader : MonoBehaviour{
    public string url;
    public int version;
    public IEnumerator LoadBundle(){
        using(WWW www = WWW.LoadFromCacheOrDownload(url, version){
            yield return www;
            AssetBundle assetBundle = www.assetBundle;
            GameObject gameObject = assetBundle.mainAsset as GameObject;
            Instantiate(gameObject );
            assetBundle.Unload(false);
        }
    }
    void Start(){
        StartCoroutine(LoadBundle());
    }
}

ขอให้สนุกกับการทำเกมนะครับ :)

Enjoy this article?

Consider subscribing to our RSS feed!

1 ความเห็น

ใส่ความเห็น

RSS feed for comments on this post