Skip to content

Commit 48e5e01

Browse files
committed
网上找的一个不错的AssetBundle框架
1 parent 7276f59 commit 48e5e01

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+3131
-0
lines changed

HotUpdate/AssetBundleFramework/Assets/Editor.meta

+10
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,273 @@
1+
using System.Collections;
2+
using System.Collections.Generic;
3+
using UnityEngine;
4+
using UnityEditor;
5+
using System.IO;
6+
using System;
7+
using System.Text;
8+
using System.Security.Cryptography;
9+
10+
public class BuildeAssets
11+
{
12+
static List<AssetImporter> Bundle_Name = new List<AssetImporter>();
13+
14+
static void Init()
15+
{
16+
Bundle_Name.Clear();
17+
AssetDatabase.RemoveUnusedAssetBundleNames(); //移除没有用的assetbundlename
18+
}
19+
20+
[MenuItem("Tools/BuildeAsset")]
21+
static void Build()
22+
{
23+
Init();
24+
SetAssetBundleName();//设置选中物体的assetbundle名字
25+
BuildPipeline.BuildAssetBundles(GetBundleDirectory(), BuildAssetBundleOptions.ChunkBasedCompression, BuildTarget.StandaloneWindows);
26+
// SetManifestVersion();
27+
SetBundleVersionInfo();
28+
AssetDatabase.Refresh();
29+
}
30+
static string GetBundleDirectory()
31+
{
32+
string path = Application.streamingAssetsPath;
33+
if (!Directory.Exists(path))
34+
Directory.CreateDirectory(path);
35+
return path;
36+
}
37+
38+
static void SetAssetBundleName()
39+
{
40+
UnityEngine.Object[] objs = Selection.objects;
41+
string[] path = new string[objs.Length];
42+
for (int i = 0; i < objs.Length; i++)
43+
{
44+
path[i] = AssetDatabase.GetAssetPath(objs[i]);
45+
SelectionVerifyResult(path[i]);
46+
}
47+
48+
}
49+
static void SelectionVerifyResult(string strpath) //验证选中的东西,是不是包含.
50+
{
51+
string[] strs = strpath.Split('.'); //如果包含.的话,分割
52+
int idex = strs[0].LastIndexOf('/'); //得到这个包含.的选中的文件系统的父级所在的索引
53+
string parentDir = strs[0].Substring(0, idex);//父级目录
54+
DirectoryInfo directory = new DirectoryInfo(parentDir);
55+
FileSystemInfo[] fileSystemInfo = directory.GetFileSystemInfos(); //得到父级目录下的所有文件系统
56+
//将unity自动生成的.mete 文件剔除
57+
foreach (var item in fileSystemInfo)
58+
{
59+
if (!item.Name.Contains(".meta"))
60+
{
61+
//list.Add(item);
62+
if ((item as DirectoryInfo) != null) //是文件夹
63+
{
64+
//strpath是从Assets下级目录开始的,需要做一下处理
65+
if (item.FullName.Contains(WorkPathName(strpath)))//是刚刚选中的这个文件夹,查询他的子目录
66+
{
67+
68+
CheckChildFileSystem(item.FullName);
69+
}
70+
}
71+
else //是文件
72+
{
73+
Debug.LogError("是文件==>" + item);
74+
SetAssetBuildName(item.FullName);
75+
}
76+
}
77+
}
78+
79+
}
80+
81+
static string WorkPathName(string strpath)
82+
{
83+
string[] strs = strpath.Split('/');
84+
85+
return strs[strs.Length - 1];
86+
}
87+
88+
/// <summary>
89+
/// 判断是否包含文件夹
90+
/// </summary>
91+
/// <param name="suf"></param>
92+
/// <returns></returns>
93+
static bool IsContainsDrictory(string suf) //判断是否包含文件夹
94+
{
95+
bool isSuf = false;
96+
if (suf.Contains("/")) //如果里边还包含文件夹
97+
{
98+
isSuf = true;
99+
}
100+
else
101+
{
102+
isSuf = false;
103+
}
104+
return isSuf;
105+
}
106+
107+
static void CheckChildFileSystem(string pathname) //检查目录下的子目录
108+
{
109+
DirectoryInfo directoryInfo = new DirectoryInfo(pathname);
110+
FileSystemInfo[] fileSystemInfo = directoryInfo.GetFileSystemInfos();
111+
foreach (var item in fileSystemInfo)
112+
{
113+
if (!item.FullName.Contains(".meta"))
114+
{
115+
if ((item as DirectoryInfo) != null)//如果是文件夹
116+
{
117+
CheckChildFileSystem(item.FullName);
118+
}
119+
else //如果是文件
120+
{
121+
SetAssetBuildName(item.FullName);
122+
}
123+
}
124+
}
125+
}
126+
127+
static void SetAssetBuildName(string pathname) //设置文件的bundle名字
128+
{
129+
//E:\Unity3Dproject\ManniuBlog\Assets\Prefab.s\Cube.prefab
130+
131+
string strs = Application.dataPath;
132+
int index = pathname.LastIndexOf(pathname);
133+
string path = pathname.Substring(strs.Length + 1);
134+
string name = string.Empty;
135+
int ind = path.LastIndexOf('.');
136+
name = path.Substring(0, ind);
137+
//Debug.LogError(name);
138+
//这里一定要在Assets开始,全名或者没有都不行
139+
AssetImporter asset = AssetImporter.GetAtPath("Assets/" + path);
140+
if (asset != null)
141+
{
142+
asset.SetAssetBundleNameAndVariant(name, "bytes");
143+
}
144+
else
145+
{
146+
Debug.LogError("空");
147+
}
148+
// Bundle_Name.Add(GetBundleDirectory() + "/" + asset.assetBundleName + "." + asset.assetBundleVariant);
149+
Bundle_Name.Add(asset);
150+
}
151+
152+
static void SetBundleVersionInfo()
153+
{
154+
AllBundleInfo allBundleInfo = new AllBundleInfo();
155+
allBundleInfo.BundleInfoList = new List<SingleBundleInfo>();
156+
foreach (var item in Bundle_Name)
157+
{
158+
allBundleInfo.BundleInfoList.Add( ComputeHashAndCRC(item));
159+
}
160+
161+
162+
allBundleInfo.BundleInfoList.Insert(0, ComputeManifestHashAndCRC(GetBundleDirectory() +"/"+GetBundleDirectory().Split('/')[GetBundleDirectory().Split('/').Length - 1]));
163+
string json = JsonUtil.Instance.ObjectToJson<AllBundleInfo>(allBundleInfo);//序列化为json
164+
WriteManifestJsonConfig(json);//写入配置文件
165+
}
166+
167+
//static void SetManifestVersion()
168+
//{
169+
// string outPaht = GetBundleDirectory();
170+
// int index = outPaht.LastIndexOf('/');
171+
// string manifest = outPaht.Substring(index + 1);
172+
// string md5 = ComputeMD5(outPaht + "/" + manifest);
173+
// ComputeHashAndCRC(outPaht + "/" + manifest);
174+
// SingleBundleInfo info = new SingleBundleInfo();
175+
// info.bundleName = manifest;
176+
// // info.bundleMD5 = md5;
177+
// string json = JsonUtil.Instance.ObjectToJson<SingleBundleInfo>(info);
178+
// WriteManifestJsonConfig(json);
179+
//}
180+
181+
//static string ComputeMD5(string fileName) //计算文件的MD5,网上直接摘得
182+
//{
183+
// string hashMD5 = string.Empty;
184+
// //检查文件是否存在,如果文件存在则进行计算,否则返回空值
185+
// if (File.Exists(fileName))
186+
// {
187+
// using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read))
188+
// {
189+
// //计算文件的MD5值
190+
// MD5 calculator = MD5.Create();
191+
// Byte[] buffer = calculator.ComputeHash(fs);
192+
// calculator.Clear();
193+
// //将字节数组转换成十六进制的字符串形式
194+
// StringBuilder stringBuilder = new StringBuilder();
195+
// for (int i = 0; i < buffer.Length; i++)
196+
// {
197+
// stringBuilder.Append(buffer[i].ToString("x2"));
198+
// }
199+
// hashMD5 = stringBuilder.ToString();
200+
// }//关闭文件流
201+
// }//结束计算
202+
// return hashMD5;
203+
//}
204+
205+
///// <summary>
206+
///// 计算指定文件的SHA1值
207+
///// </summary>
208+
///// <param name="fileName">指定文件的完全限定名称</param>
209+
///// <returns>返回值的字符串形式</returns>
210+
//static String ComputeSHA1(String fileName)
211+
//{
212+
// String hashSHA1 = String.Empty;
213+
// //检查文件是否存在,如果文件存在则进行计算,否则返回空值
214+
// if (File.Exists(fileName))
215+
// {
216+
// using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read))
217+
// {
218+
// //计算文件的SHA1值
219+
// SHA1 calculator = SHA1.Create();
220+
// Byte[] buffer = calculator.ComputeHash(fs);
221+
// calculator.Clear();
222+
// //将字节数组转换成十六进制的字符串形式
223+
// StringBuilder stringBuilder = new StringBuilder();
224+
// for (int i = 0; i < buffer.Length; i++)
225+
// {
226+
// stringBuilder.Append(buffer[i].ToString("x2"));
227+
// }
228+
// hashSHA1 = stringBuilder.ToString();
229+
// }//关闭文件流
230+
// }
231+
// return hashSHA1;
232+
//}
233+
234+
static SingleBundleInfo ComputeHashAndCRC(AssetImporter asset)
235+
{
236+
237+
SingleBundleInfo info = new SingleBundleInfo();
238+
Hash128 hash128 = new Hash128();
239+
string fileName = GetBundleDirectory() + "/" + asset.assetBundleName + "." + asset.assetBundleVariant;
240+
if (BuildPipeline.GetHashForAssetBundle(fileName, out hash128))
241+
info.bundleHash128 = hash128.ToString();
242+
uint crc = new uint();
243+
if (BuildPipeline.GetCRCForAssetBundle(fileName, out crc))
244+
info.bundleCRC = crc;
245+
info.bundleName = asset.assetBundleName + "." + asset.assetBundleVariant;
246+
return info;
247+
}
248+
249+
static SingleBundleInfo ComputeManifestHashAndCRC(string manifestName)
250+
{
251+
SingleBundleInfo info = new SingleBundleInfo();
252+
Hash128 hash128 = new Hash128();
253+
if (BuildPipeline.GetHashForAssetBundle(manifestName, out hash128))
254+
info.bundleHash128 = hash128.ToString();
255+
uint crc = new uint();
256+
if (BuildPipeline.GetCRCForAssetBundle(manifestName, out crc))
257+
info.bundleCRC = crc;
258+
info.bundleName = GetBundleDirectory().Split('/')[GetBundleDirectory().Split('/').Length-1];
259+
return info;
260+
}
261+
262+
static void WriteManifestJsonConfig(string json)
263+
{
264+
string path = GetBundleDirectory() + "/ABconfig.json";
265+
byte[] bytes = Encoding.UTF8.GetBytes(json);
266+
FileStream fileStream = new FileStream(path, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite);
267+
fileStream.BeginWrite(bytes, 0, bytes.Length,new AsyncCallback( delegate (IAsyncResult ar)
268+
{
269+
fileStream.EndWrite(ar);
270+
}) ,fileStream);
271+
}
272+
273+
}

HotUpdate/AssetBundleFramework/Assets/Editor/BuildeAssets.cs.meta

+13
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

HotUpdate/AssetBundleFramework/Assets/Images.meta

+10
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Loading

HotUpdate/AssetBundleFramework/Assets/Images/1151.jpg.meta

+77
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

HotUpdate/AssetBundleFramework/Assets/Materials.meta

+10
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)