
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class AssetPathDefine
{
public const string fileRes = "/BundleResources";
//打包Assetbundle源文件
public static string resPath = Application.dataPath + fileRes;
//public static string outPath = Application.streamingAssetsPath + "/AssetBundle/";
//datapath:F:/Unity/AssetBundleFrame/AssetBundleFrame/NewTest/New Unity Project/Assets
//打包Assetbundle输出文件
public static string GetOutPath()
{
return Application.dataPath.Replace("/Assets","")+"/AssetBundle";
}
public static string GetCurrentVersionTextFilePath()
{
return Application.dataPath+"/Version.txt";
}
}
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using UnityEditor;
using UnityEngine;
public class AssetBundleData
{
public string path; /// 路径
public string version; /// 版本
public string allAssetNames; /// 所有资源名
public Hash128 hash;
public AssetBundle bundle;
public override string ToString()
{
return $"{path},{version},{allAssetNames},{hash}";
}
}
public class AssetBundleManager
{
private List _datas;
public List datas {
get { return _datas; }
}
private string _configFileName;
public string configFileName {
get { return _configFileName; }
}
public AssetBundleManager()
{
_datas = new List();
_configFileName = "AssetBundleConfig";
}
public AssetBundleData GetDataAt(string path)
{
for (int i = 0; i < _datas.Count; i++)
{
if (_datas[i].path == path)
{
return _datas[i];
}
}
return null;
}
public void AddData(AssetBundleData data)
{
IsAdd(data);
}
public string GetAssetBundleAt(string assetName)
{
for (int i = 0; i < _datas.Count; i++)
{
string[] names = _datas[i].allAssetNames.Split('|');
if (names.ToList().Contains(assetName))
{
return _datas[i].path;
}
}
return string.Empty;
}
private bool IsAdd(AssetBundleData data)
{
for (int i = 0; i < _datas.Count; i++)
{
if (_datas[i].path == data.path)
{
Debug.LogError($"重复添加:" + data.path);
return false;
}
}
_datas.Add(data);
return true;
}
StringBuilder builder = new StringBuilder();
public void WriteTextFile(string path)
{
builder.Clear();
foreach (var data in datas)
{
builder.AppendLine(data.ToString());
}
WriteTextFile(path+"/FileInfo.txt", builder.ToString());
}
private void WriteTextFile(string path, string text)
{
if (File.Exists(path))
{
File.Delete(path);
}
StreamWriter sw = File.CreateText(path);
sw.Write(text);
sw.Close();
sw.Dispose();
//AssetDatabase.Refresh();
}
}
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
public class AssetBundleLoad
{
private AssetBundleManifest manifest;
private static AssetBundleLoad instance;
private Dictionary allAsset = new Dictionary();
public static AssetBundleLoad Instance {
get {
if (instance == null)
{
instance = new AssetBundleLoad();
}
return instance;
}
}
private AssetBundle ab;
public AssetBundleManifest GetAssetBundleManifest()
{
ab = AssetBundle.LoadFromFile(string.Format("{0}AssetBundle", AssetPathDefine.GetOutPath()));
AssetBundleManifest manifest = (AssetBundleManifest)ab.LoadAsset("AssetBundleManifest");
ab.Unload(false);
return manifest;
}
private AssetBundleLoad()
{
manifest = GetAssetBundleManifest();
}
public void AddAsset(AssetBundleData assetName)
{
if (!allAsset.ContainsKey(assetName.path))
{
allAsset.Add(assetName.path, assetName);
}
else
{
Debug.LogError("重复添加:" + assetName.path);
}
}
public AssetBundleData GetAssetBundle(string path)
{
if (allAsset.ContainsKey(path))
{
return allAsset[path];
}
else
{
var abundle = AssetBundle.LoadFromFile(string.Format("{0}{1}", AssetPathDefine.GetOutPath(), path));
if (abundle == null)
{
Debug.LogError("加载AsseBundle不存在:" + string.Format("{0}{1}", AssetPathDefine.GetOutPath(), path));
}
AssetBundleData data = new AssetBundleData();
data.path = path;
data.bundle = abundle;
data.allAssetNames = string.Join("|", abundle.GetAllAssetNames());
data.hash = manifest.GetAssetBundleHash(path);
AddAsset(data);
return data;
}
}
public T LoadAsset(string path) where T : Object
{
path = path.ToLower();
AssetBundleData bundle = GetAssetBundle(path);
string[] dependencies = manifest.GetAllDependencies(bundle.path);
foreach (var item in dependencies)
{
GetAssetBundle(item);
}
//Debug.Log(bundle.allAssetNames);
T LoadAsset = bundle.bundle.LoadAsset(bundle.allAssetNames);
return (T)LoadAsset;
}
public void UnLoadAll()
{
foreach (var item in allAsset.Values)
{
var bundle = item.bundle;
if (bundle != null)
{
bundle.Unload(false);
}
}
manifest = null;
allAsset.Clear();
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text;
using UnityEngine;
public class UtilEditor
{
public static void CopyAssetBundleToTargetDir(string buildPath, string targetPath)
{
DirectoryInfo abDirectoryInfo = new DirectoryInfo(targetPath);
if (abDirectoryInfo.Exists)
{
DeleteDirectory(abDirectoryInfo);
}
DirectoryInfo directoryInfo = new DirectoryInfo(targetPath);
if (!directoryInfo.Exists)
{
Directory.CreateDirectory(targetPath);
}
FileInfo abFileInfo = new FileInfo(targetPath);
if (abFileInfo.Exists)
{
abFileInfo.Delete();
}
abFileInfo = new FileInfo(buildPath + "/AssetBundle");
if (abFileInfo.Exists)
{
AssetBundle ab = AssetBundle.LoadFromFile(string.Format("{0}/AssetBundle", buildPath));
AssetBundleManifest manifest = (AssetBundleManifest)ab.LoadAsset("AssetBundleManifest");
CopyFile(buildPath + "/AssetBundle", targetPath + "/AssetBundle");
CopyFile(buildPath + "/AssetBundle.manifest", targetPath + "/AssetBundle.manifest");
string[] abNames = manifest.GetAllAssetBundles();
foreach (string str in abNames)
{
CopyFile(string.Format("{0}/{1}", buildPath, str), targetPath + "/" + str);
CopyFile(string.Format("{0}/{1}.manifest", buildPath, str), targetPath + "/" + str + ".manifest");
}
ab.Unload(false);
manifest = null;
Resources.UnloadUnusedAssets();
}
}
public static void CopyAssetBundleToStreamingAssets(string buildPath)
{
DirectoryInfo abDirectoryInfo = new DirectoryInfo(Application.dataPath + "/StreamingAssets/AssetBundle");
if (abDirectoryInfo.Exists)
{
DeleteDirectory(abDirectoryInfo);
}
FileInfo abFileInfo = new FileInfo(Application.dataPath + "/StreamingAssets/AssetBundle.meta");
if (abFileInfo.Exists)
{
abFileInfo.Delete();
}
abFileInfo = new FileInfo(buildPath + "/AssetBundle");
if (abFileInfo.Exists)
{
AssetBundle ab = AssetBundle.LoadFromFile(string.Format("{0}/AssetBundle", buildPath));
AssetBundleManifest manifest = (AssetBundleManifest)ab.LoadAsset("AssetBundleManifest");
CopyFile(buildPath + "/AssetBundle", Application.dataPath + "/StreamingAssets/AssetBundle/AssetBundle");
CopyFile(buildPath + "/AssetBundle.manifest", Application.dataPath + "/StreamingAssets/AssetBundle/AssetBundle.manifest");
string[] abNames = manifest.GetAllAssetBundles();
foreach (string str in abNames)
{
Debug.Log(string.Format("{0}/StreamingAssets/AssetBundle/{1}", Application.dataPath, str));
CopyFile(string.Format("{0}/{1}", buildPath, str), string.Format("{0}/StreamingAssets/AssetBundle/{1}", Application.dataPath, str));
CopyFile(string.Format("{0}/{1}.manifest", buildPath, str), string.Format("{0}/StreamingAssets/AssetBundle/{1}.manifest", Application.dataPath, str));
}
ab.Unload(false);
manifest = null;
Resources.UnloadUnusedAssets();
}
}
public static void DeleteDirectory(DirectoryInfo directoryInfo)
{
DirectoryInfo[] directoryInfos = directoryInfo.GetDirectories();
FileInfo[] fileInfos = directoryInfo.GetFiles();
for (int i = 0; i < directoryInfos.Length; i++)
{
DeleteDirectory(directoryInfos[i]);
}
for (int i = 0; i < fileInfos.Length; i++)
{
fileInfos[i].Delete();
}
directoryInfo.Delete();
}
///
/// 获取文件中的数据
///
///
public static string ReadTxt(string filePath)
{
StringBuilder builder = new StringBuilder();
if (File.Exists(filePath))
{
try
{
string line;
// 创建一个 StreamReader 的实例来读取文件 ,using 语句也能关闭 StreamReader
using (System.IO.StreamReader sr = new System.IO.StreamReader(filePath))
{
// 从文件读取并显示行,直到文件的末尾
while ((line = sr.ReadLine()) != null)
{
builder.AppendLine(line);
}
}
}
catch (Exception e)
{
Debug.Log(e.ToString());
}
}
return builder.ToString();
}
public static void DeleteFile(string path)
{
FileInfo fileInfo = new FileInfo(path);
if (File.Exists(path))
{
fileInfo.Delete();
}
}
public static void CopyFile(string sourcePath, string targetPath)
{
FileInfo fileinfo = new FileInfo(targetPath);
if (File.Exists(sourcePath))
{
if (!fileinfo.Directory.Exists)
{
fileinfo.Directory.Create();
}
File.Copy(sourcePath, targetPath, true);
}
}
public static void WriteTextFile(string path, string text)
{
if (File.Exists(path))
{
File.Delete(path);
}
StreamWriter sw = File.CreateText(path);
sw.Write(text);
sw.Close();
sw.Dispose();
}
public static void CopyDirectory(string srcPath, string targetPath)
{
try
{
DirectoryInfo dir = new DirectoryInfo(srcPath);
FileSystemInfo[] fileinfo = dir.GetFileSystemInfos(); //获取目录下(不包含子目录)的文件和子目录
foreach (FileSystemInfo i in fileinfo)
{
if (i is DirectoryInfo) //判断是否文件夹
{
if (!Directory.Exists(targetPath + "\\" + i.Name))
{
Directory.CreateDirectory(targetPath + "\\" + i.Name); //目标目录下不存在此文件夹即创建子文件夹
}
CopyDirectory(i.FullName, targetPath + "\\" + i.Name); //递归调用复制子文件夹
}
else
{
File.Copy(i.FullName, targetPath + "\\" + i.Name, true); //不是文件夹即复制文件,true表示可以覆盖同名文件
}
}
}
catch (Exception e)
{
Debug.LogError(e.ToString());
}
}
}
5、核心类Assetbundle打包,版本号的生成、拷贝升级资源文件至指定文件夹 |
|
|
|
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using UnityEditor;
using UnityEngine;
public class BuildBundler
{
//dataPath:F:/Unity/AssetBundleFrame/AssetBundleFrame/NewResTest/Assets
//streamingAssetsPath:F:/Unity/AssetBundleFrame/AssetBundleFrame/NewResTest/Assets/StreamingAssets
//public static string resPath = Application.dataPath + fileRes;
//public const string fileRes = "/BundleResources";
//public static string outPath = Application.streamingAssetsPath + "/AssetBundle/";
public static int FrontVersion = 1; //大版本号
[MenuItem("MyTools/CopyAssetBundleToStreamingAssets", false, 0)]
static void CopyAssetBundleToStreamingAssets()
{
if (EditorApplication.isCompiling)
{
return;
}
//UtilEditor.CopyAssetBundleToStreamingAssets(AssetPathDefine.GetOutPath());
//UtilEditor.CopyAssetBundleToTargetDir(AssetPathDefine.GetOutPath(), Application.streamingAssetsPath + "/AssetBundle");
UtilEditor.CopyDirectory(AssetPathDefine.GetOutPath(), Application.streamingAssetsPath + "/AssetBundle");
AssetDatabase.Refresh();
}
[MenuItem("MyTools/BuildAssetBundle", false, 0)]
static void BuildBundle()
{
if (EditorApplication.isCompiling)
{
return;
}
Build(AssetPathDefine.resPath, AssetPathDefine.GetOutPath(), BuildTarget.StandaloneWindows);
int currentVersion = ReadVersion();
//F:\Unity\AssetBundleFrame\AssetBundleFrame\NewTest\UpdateAsset
string scrPath = AssetPathDefine.GetOutPath();
string targetPath = @"F:\Unity\AssetBundleFrame\AssetBundleFrame\NewTest\UpdateAsset";
CopyUpdateAsset(currentVersion, scrPath, targetPath);
AssetDatabase.Refresh();
}
public static void CopyUpdateAsset(int version, string scrPath, string OutPath)
{
Debug.Log("计算更新文件CopyUpdateAsset---CurrentVersion:" + version);
bool isHaveUpdateFile = false;
OutPath = OutPath.Replace(@"\", @"/");
string TargetPath = OutPath + "/" + (version);
List unSame = new List();///不包含的情况
AssetBundleManager manager = new AssetBundleManager();
AssetBundle newAb = AssetBundle.LoadFromFile(string.Format("{0}/AssetBundle", AssetPathDefine.GetOutPath()));
AssetBundleManifest newManifest = (AssetBundleManifest)newAb.LoadAsset("AssetBundleManifest");
newAb.Unload(false);
string endOldOutPath = OutPath + "/" + (version - 1);
//Debug.Log("老版本中Manifest1:" + endOldOutPath + "/AssetBundle");
if (File.Exists(endOldOutPath + "/AssetBundle"))
{
//Debug.Log("老版本中Manifest2:是存在的" + endOldOutPath + "/AssetBundle");
AssetBundle oldAb = AssetBundle.LoadFromFile(endOldOutPath + "/AssetBundle");
AssetBundleManifest oldManifest = (AssetBundleManifest)oldAb.LoadAsset("AssetBundleManifest");
oldAb.Unload(false);
if (oldManifest.GetHashCode() != newManifest.GetHashCode())
{
//foreach (var oldItem in oldManifest.GetAllAssetBundles())
//{
// if (!newManifest.GetAllAssetBundles().ToList().Contains(oldItem))
// {
// unSame.Add(oldItem);
// Debug.Log($"删除了文件{version}:" + oldItem);
// }
//}
foreach (var tempnewItem in newManifest.GetAllAssetBundles())
{
string[] oldManifestName = oldManifest.GetAllAssetBundles();
if (!oldManifestName.ToList().Contains(tempnewItem))
{
Debug.Log($"变更文件{version}:" + tempnewItem);
unSame.Add(tempnewItem);
}
AssetBundle newAssetBund = AssetBundle.LoadFromFile(AssetPathDefine.GetOutPath() + "/" + tempnewItem);
newAssetBund.Unload(false);
foreach (var tempolditem in oldManifestName)
{
if (tempnewItem == tempolditem)
{
if (newManifest.GetAssetBundleHash(tempnewItem) != oldManifest.GetAssetBundleHash(tempnewItem))
{
Debug.Log($"变更文件{version}:" + tempnewItem);
unSame.Add(tempolditem);
break;
}
}
}
}
Debug.Log("更新文件至文件夹:" + TargetPath);
}
else
{
Debug.LogError("变更了版本号,但是没有文件变更:" + version);
}
}
else
{
Debug.Log("老版本中Manifest3:是不存在的:" + endOldOutPath + "/AssetBundle");
Debug.Log("第一个版本,或者上一个文件为空:" + (scrPath, OutPath + "/" + version));
UtilEditor.CopyDirectory(scrPath, OutPath + "/" + version);
UtilEditor.CopyFile(AssetPathDefine.GetCurrentVersionTextFilePath(), OutPath + "/" + version + "/Version.txt");
WriteVersion();
return;
}
if (unSame.Count == 0)
{
Debug.LogWarning("没有文件变更,请从新打包");
return;
}
UtilEditor.CopyFile(AssetPathDefine.GetCurrentVersionTextFilePath(), TargetPath + "/Version.txt");
UtilEditor.CopyFile(string.Format("{0}/AssetBundle", AssetPathDefine.GetOutPath()), TargetPath + "/" + "AssetBundle");
foreach (var str in unSame)
{
var abundle = AssetBundle.LoadFromFile(string.Format("{0}/{1}", AssetPathDefine.GetOutPath(), str));
AssetBundleData data = new AssetBundleData();
data.path = str;
data.allAssetNames = string.Join("|", abundle.GetAllAssetNames());
data.hash = newManifest.GetAssetBundleHash(str);
data.version = (version).ToString();
abundle.Unload(false);
manager.AddData(data);
UtilEditor.CopyFile(string.Format("{0}/{1}", AssetPathDefine.GetOutPath(), str), TargetPath + "/" + data.path);
}
manager.WriteTextFile(TargetPath);
WriteVersion();
}
public static int ReadVersion()
{
//UtilEditor.DeleteFile(AssetPathDefine.GetCurrentVersionTextFilePath());
//写入版本文件
string read = UtilEditor.ReadTxt(AssetPathDefine.GetCurrentVersionTextFilePath());
string[] content = read.Split('\n');
int upVer = 0;
int downVer = 0;
int currentVer = 0;
List AddList = new List();
foreach (var item in content)
{
if (!string.IsNullOrEmpty(item))
{
string[] temp = item.Split('.');
if (temp.Length == 2)
{
upVer = int.Parse(temp[0]);
downVer = int.Parse(temp[1]);
AddList.Add(item);
}
}
}
Debug.Log("读取版本号:" + upVer + "'." + downVer);
currentVer = downVer = ++downVer;
return currentVer;
}
public static void WriteVersion()
{
//UtilEditor.DeleteFile(AssetPathDefine.GetCurrentVersionTextFilePath());
//写入版本文件
string read = UtilEditor.ReadTxt(AssetPathDefine.GetCurrentVersionTextFilePath());
string[] content = read.Split('\n');
int upVer = 0;
int downVer = 0;
int currentVer = 0;
List AddList = new List();
foreach (var item in content)
{
if (!string.IsNullOrEmpty(item))
{
string[] temp = item.Split('.');
if (temp.Length == 2)
{
upVer = int.Parse(temp[0]);
downVer = int.Parse(temp[1]);
AddList.Add(item);
}
}
}
Debug.Log("读取版本号:" + upVer + "'." + downVer);
currentVer = downVer = ++downVer;
string AddVersion = FrontVersion + "." + downVer;
AddList.Add(AddVersion);
Debug.Log("AddVersion:" + AddVersion);
StringBuilder builder1 = new StringBuilder();
foreach (var item in AddList)
{
var temp = item.Replace("\n", "");
builder1.AppendLine(temp);
}
UtilEditor.WriteTextFile(AssetPathDefine.GetCurrentVersionTextFilePath(), builder1.ToString());
}
public static void Build(string resPath, string outPath, BuildTarget target)
{
Debug.Log("AssetBundle OutPath:" + outPath);
SetAssetBundleName(new DirectoryInfo(resPath));
Caching.ClearCache();
DirectoryInfo directoryInfo = new DirectoryInfo(outPath);
if (!directoryInfo.Exists)
{
Directory.CreateDirectory(outPath);
}
BuildPipeline.BuildAssetBundles(outPath, BuildAssetBundleOptions.None, target);
AssetBundleManager manager = new AssetBundleManager();
FileInfo abFileInfo = new FileInfo(outPath + "/AssetBundle");
Debug.Log("abFileInfo.Exists:" + abFileInfo.Exists);
if (abFileInfo.Exists)
{
AssetBundle ab = AssetBundle.LoadFromFile(string.Format("{0}/AssetBundle", outPath));
AssetBundleManifest manifest = (AssetBundleManifest)ab.LoadAsset("AssetBundleManifest");
ab.Unload(false);
string[] abNames = manifest.GetAllAssetBundles();
try
{
StringBuilder builder = new StringBuilder();
foreach (var str in abNames)
{
//Debug.Log("LoadBundlePath:"+string.Format("{0}{1}", outPath, str));
var abundle = AssetBundle.LoadFromFile(string.Format("{0}/{1}", outPath, str));
AssetBundleData data = new AssetBundleData();
data.path = str;
data.allAssetNames = string.Join("|", abundle.GetAllAssetNames());
data.hash = manifest.GetAssetBundleHash(str);
data.version = "0";
abundle.Unload(false);
manager.AddData(data);
}
Debug.Log("build Assebundle Completed");
manager.WriteTextFile(outPath);
manifest = null;
}
catch (Exception e)
{
Debug.LogError(e.ToString());
}
Resources.UnloadUnusedAssets();
}
AssetDatabase.Refresh();
}
[MenuItem("MyTools/ClearAssetBundleName", false, 0)]
static void ClearAssetBundleName()
{
if (EditorApplication.isCompiling)
{
return;
}
ClearAssetBundleName(new DirectoryInfo(AssetPathDefine.resPath));
Debug.Log("删除了所有AssetBundleName:" + AssetPathDefine.resPath);
AssetDatabase.Refresh();
}
private static void SetAssetBundleName(DirectoryInfo directoryInfo)
{
DirectoryInfo[] directoryInfos = directoryInfo.GetDirectories();
FileInfo[] fileInfos = directoryInfo.GetFiles();
for (int i = 0; i < directoryInfos.Length; i++)
{
SetAssetBundleName(directoryInfos[i]);
}
for (int i = 0; i < fileInfos.Length; i++)
{
FileInfo info = fileInfos[i];
if (info.Extension != ".meta" && info.Extension != ".cs")
{
string path = info.FullName.Replace(@"\", @"/").Replace(Application.dataPath.Replace(@"\", @"/"), "");
path = "Assets" + path;
//TODO
string assetbundleName = path.Replace("Assets" + AssetPathDefine.fileRes + "/", "").Replace(info.Extension, "");
AssetImporter assetImporter = AssetImporter.GetAtPath(path);
assetImporter.assetBundleName = assetbundleName;
}
}
}
public static void ClearAssetBundleName(DirectoryInfo directoryInfo)
{
DirectoryInfo[] directoryInfos = directoryInfo.GetDirectories();
FileInfo[] fileInfos = directoryInfo.GetFiles();
for (int i = 0; i < directoryInfos.Length; i++)
{
ClearAssetBundleName(directoryInfos[i]);
}
for (int i = 0; i < fileInfos.Length; i++)
{
if (!fileInfos[i].Extension.Contains(".meta") && !fileInfos[i].Extension.Contains(".cs"))
{
string path = fileInfos[i].FullName.Replace(@"\", @"/").Replace(Application.dataPath.Replace(@"\", @"/"), "");
path = "Assets" + path;
AssetImporter assetImporter = AssetImporter.GetAtPath(path);
assetImporter.assetBundleName = string.Empty;
}
}
}
}