游戲開發熱更新流程——打包篇


這篇總結主要是總結下資源的熱更新

前段時間閑來無事,狂擼了下項目的熱更新代碼,寫個筆記總結下吧

 

打包其實比較簡單,主要是項目結構的設計和文件目錄的處理比較麻煩。

先設計一個文件結構

--ABResource -- 所有資源打包的主目錄

  //這些目錄是資源的大類

  --UI -圖集,圖片icon資源等

    --Module1

    --Module2

    --Module3

  -Animation  動畫 animator等資源

    --Module1

    --Module2

    --Module3

  --Sound  聲音資源

    --Module1

    --Module2

    --Module3

  --Model  模型資源

  --Map    地圖資源,場景相關的超級大圖

  --Effect  特效類

  --Audio    視頻類

 

  文件結構的設計直接影響后期的開發效率,打包方式流程其實都知道,但是文件目錄結構設計的好,對項目的開發效率提升非常大,所有模塊對應的子文件夾名字盡量統一,方便開發的時候使用統一命名存取資源。減少邏輯成本!

  打包唯一復雜的地方就是文件夾讀取,后綴名的轉換

  關鍵是對這個結構體字段的理解 AssetBundleBuild

  首先,每一個AssetBundleBuild都代表將要生成的一個ab文件

  一個ab文件里面可以關聯N個資源,至於多少個資源,由AssetBundleBuild里面的assetNames決定,Unity會根據名字找到當前這個文件夾里面的資源,注意這里面的路徑都是Unity Asset開始的相對路徑,而C#的Path、Directory這些路徑獲取工具拿到的都是全局路徑,需要自己做轉換

  

AssetBundleBuild里面只有2個字段是比較重要的

 AssetBundleBuild.assetBundleName  --------這個字段決定了你這份ab文件生成的名字

AssetBundleBuild.assetNames            --------這個字段決定了你這份ab文件里面包含了多少個資源

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;
using UnityEditor;
using System.Linq;
using System;
public class BundelTest  {

   private static Dictionary<string,AssetBundleBuild> modulAbDic = new Dictionary<string, AssetBundleBuild>();
   Dictionary<string,AssetBundle> AllAb = new Dictionary<string, AssetBundle>();
   /// <summary>
   /// 解析每個模塊
   /// </summary>
   /// <param name="path"></param>
   public static void BuildAllBundle(string path)
   {
    //這里是采用上述的文件結構,所以做的3層遍歷,也可以做成遞歸的方式,讓其適用多個層級
      // 判斷這個路徑是否存在
      if (Directory.Exists(path)) 
      {
          Directory.CreateDirectory(path);
      }
      string realPath  = Path.Combine(Application.dataPath,path);
      string[] floderList =   Directory.GetDirectories(realPath);//這個只能獲取當前層級的子層級,不能獲取嵌套的

   
      for (int i = 0; i < floderList.Length; i++)
      {
        
        string[] fileNames =   Directory.GetDirectories(floderList[i]);//這個文件夾下的所有的子文件夾     
        for (int a = 0; a < fileNames.Length; a++)
        {
            getBundls(fileNames[a]);//第一層文件夾下面的文件。不包括里面文件夾
        }
      }
   }




    /// <summary>
    /// 解析模塊內的資源
    /// </summary>
    /// <param name="path"></param>
   public static void getBundls(string modulePath)
   {
        modulePath = modulePath.Replace("\\","/"); //合並的路徑都是\\需要轉義
       
        string[] flies =  Directory.GetFiles(modulePath);
    
        if  (flies.Length > 0 )
        {
           for (int i = 0; i < flies.Length; i++)
           {
               //處理模塊內文件
               string assetBundleName  = flies[i].Replace(Application.dataPath+"/","");
                string ralativePath = getRelativePah(flies[i]);
                string _abPath =ralativePath;
                string ext =  Path.GetExtension(ralativePath);
                assetBundleName = assetBundleName.Replace(ext,"")+".ab";
                if (ext != ".meta")
                {
                    string name = Path.GetDirectoryName(ralativePath)+"/"+Path.GetFileNameWithoutExtension(ralativePath); //包的名字,這個名字包含了資源的路徑。
                    AssetBundleBuild build = new AssetBundleBuild() ;
                    if (modulAbDic.ContainsKey(_abPath))
                    {
                        if (modulAbDic.TryGetValue(_abPath,out build))
                        {
                            build.assetBundleName = assetBundleName;
                            build.assetNames = new string[]{ralativePath}; --這里是一個資源對應一個build 所以是固定的
                            modulAbDic[_abPath] = build;
                        }
                    }
                    else
                    {
                        build.assetBundleName = assetBundleName;
                        build.assetNames = new string[]{ralativePath};
                        modulAbDic.Add(_abPath,build);
                    }
                }
           }
        }
       
    }
    
    
    /// <summary>
    /// 打包所有資源,每個資源打一份ab,方便進行差異化分析
    /// </summary>
    public static  void BuildAssetBundleForDic()
    {
        AssetBundleBuild[] builds = modulAbDic.Values.ToArray();
      //輸出路徑可以自行選擇,這里是默認輸出在桌面 BuildPipeline.BuildAssetBundles(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory),
"bundle"),builds,BuildAssetBundleOptions.DeterministicAssetBundle ,BuildTarget.StandaloneWindows64); } /// <summary> /// 獲取asset下的相對位置 /// </summary> public static string getRelativePah(string path) { string _path = path.Replace("\\","/"); return _path.Replace(Application.dataPath,"Assets"); } }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM