编辑器脚本,用于打包资源文件
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System.IO;
using System;
using System.Security.Cryptography;
using System.Text;
using LitJson;
/// <summary>
/// 编辑器脚本
/// </summary>
public class BuildBundle : Editor {
[MenuItem("Tools/build")]
public static void Build()
{
//生成bundle包
BuildAB();
//拷贝lua文件
HandleLuaFile();
//生成版本文件
GenFileText();
}
//拷贝lua文件
private static void HandleLuaFile()
{
string path = Application.dataPath + "/Lua/";
string[] files = Directory.GetFiles(path, "*.lua");//搜索所有的lua文件
string desPath = Application.streamingAssetsPath + "/";
if (!Directory.Exists(desPath))
{
Directory.CreateDirectory(desPath);
}
for (int i = 0; i < files.Length; i++)
{
string fileName = Path.GetFileName(files[i]);
string des = desPath + "/" + fileName;
File.Copy(files[i], des);
}
}
//生成bundle包
private static void BuildAB()
{
string path = Application.streamingAssetsPath;
if (Directory.Exists(path))
{
//递归删除字目录
Directory.Delete(path, true);
}
//创建目录
Directory.CreateDirectory(path);
//资源打包
BuildPipeline.BuildAssetBundles(path, 0, BuildTarget.StandaloneWindows64);
}
//获取文件夹中所有文件
static List<string> files = new List<string>();
static void Recusive(string path)
{
string[] fs = Directory.GetFiles(path);
files.AddRange(fs);
string[] dires = Directory.GetDirectories(path);
foreach (var item in dires)
{
Recusive(item);
}
}
//生成版本文件
private static void GenFileText()
{
Dictionary<string, string> filesMd5 = new Dictionary<string, string>();
string path = Application.streamingAssetsPath;
files.Clear();
Recusive(path);
foreach (var item in files)
{
if (Path.GetFileName(item) != ".meta")
{
string md5 = Md5File(item);
string fileName = Path.GetFileName(item);
filesMd5.Add(fileName, md5);
}
}
//将文件名和文件MD5值写入版本文件
StreamWriter writer = File.CreateText(path + "/file.txt");
writer.Write(JsonMapper.ToJson(filesMd5));
writer.Close();
//刷新文件夹
AssetDatabase.Refresh();
}
//计算文件的MD5值
private static string Md5File(string file)
{
FileStream fs = new FileStream(file, FileMode.Open);
MD5 md5 = MD5CryptoServiceProvider.Create();
byte[] retVal = md5.ComputeHash(fs);
fs.Close();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < retVal.Length; i++)
{
sb.Append(retVal[i].ToString("x2"));
}
return sb.ToString();
}
}
资源下载解压与加载
在Android和IOS中streamingAssets文件夹是只读的,不可以写入,所有资源文件统一拷贝到persistentDataPath下使用
PC路径为C:\Users\Robyn\AppData\LocalLow\DefaultCompany\项目名\
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using LitJson;
//检查更新
public class ABUpdateManager : MonoBehaviour {
string streamingPaht;
string dataPath;
string baseUrl = "http://192.168.108.19/StreamingAssets/";
public static event System.Action Complete;
void Start () {
streamingPaht = Application.streamingAssetsPath + "/";
dataPath = Application.persistentDataPath + "/";
Debug.Log(dataPath);
Debug.Log("检测本地沙盒目录");
if (File.Exists(dataPath + "file.txt"))
{
Debug.Log("沙盒目录不为空");
//开启协程,检查更新
StartCoroutine(CheckUpdate());
}else
{
Debug.Log("沙盒目录为空");
//首次运行,拷贝StreamingAsset到PersistentDatapath
CheckCompress();
}
}
private IEnumerator CheckUpdate()
{
Debug.Log("获取远程file.txt文件");
WWW www = new WWW(baseUrl + "file.txt");
yield return www;
if (www.error != null)
{
Debug.Log(www.error);
yield return 0;
}
//获取远程本版文件
Dictionary<string, string> fileMd5 = JsonMapper.ToObject<Dictionary<string, string>>(www.text);
//获取本地版本文件
string filePath = dataPath + "file.txt";
Dictionary<string, string> localMd5 = JsonMapper.ToObject<Dictionary<string, string>>(File.ReadAllText(filePath));
//比较差异
foreach (var item in fileMd5)
{
Debug.Log("检测更新" + item.Key);
if (localMd5.ContainsKey(item.Key))
{
if (localMd5[item.Key] != fileMd5[item.Key])
{
Debug.Log("MD5不同,更新:" + item.Key);
//删除本地文件
File.Delete(dataPath + item.Key);
//下载远程文件
StartCoroutine(DownloadFile(item.Key));
}
}
else
{
//本地文件缺失,下载服务器文件
Debug.Log("文件缺失,直接下载" + item.Key);
StartCoroutine(DownloadFile(item.Key));
}
}
//更新file
File.Delete(dataPath + "file.txt");
File.WriteAllText(dataPath + "file.txt", www.text);
Debug.Log("解压更新完成");
if (Complete != null)
{
Complete();
}
}
//下载更新文件
private IEnumerator DownloadFile(string fileName)
{
WWW download = new WWW(baseUrl + fileName);
yield return download;
File.WriteAllBytes(dataPath + fileName, download.bytes);
Debug.LogFormat("更新文件{0}成功", fileName);
}
//拷贝文件到沙盒
private void CheckCompress()
{
string[] files = Directory.GetFiles(streamingPaht);
foreach (var item in files)
{
string targetPath = dataPath + Path.GetFileName(item);
//如果文件存在,拷贝会失败
if (File.Exists(targetPath))
{
File.Delete(targetPath);
}
File.Copy(item, targetPath);
}
//解压完成,检测更新
StartCoroutine(CheckUpdate());
}
}
使用
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
public class LoadAB_Dependence : MonoBehaviour {
//保存加载过的bundle包
Dictionary<string, AssetBundle> loadedBundles = new Dictionary<string, AssetBundle>();
Button createBtn;
void Start () {
createBtn = GetComponent<Button>();
createBtn.onClick.AddListener(CreatePrefabs);
}
private void CreatePrefabs()
{
var perfab1 = LoadAB("perfabs.unity3d", "Cube");
var perfab2 = LoadAB("perfabs.unity3d", "Capsule");
Instantiate(perfab1);
Instantiate(perfab2);
TestLoadLua();
}
void TestLoadLua()
{
LuaLoader loader = new LuaLoader();
string luastring = loader.LoadLua("hello.lua");
Debug.Log(luastring);
}
//解压资源与寻找依赖包
public GameObject LoadAB(string abName, string prefabName)
{
//加在总配置
AssetBundle ab = GetBundle("StreamingAssets");
AssetBundleManifest abm = ab.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
//加载依赖
string[] depends = abm.GetAllDependencies(abName);
for (int i = 0; i < depends.Length; i++)
{
GetBundle(depends[i]);
}
//加载ab包
AssetBundle asset = GetBundle(abName);
return asset.LoadAsset<GameObject>(prefabName);
}
//缓存bundle
AssetBundle GetBundle(string bundName)
{
if (loadedBundles.ContainsKey(bundName))
{
return loadedBundles[bundName];
}
AssetBundle ab = AssetBundle.LoadFromFile(Path + bundName);
loadedBundles.Add(bundName, ab);
return ab;
}
string path;
public string Path
{
get
{
if (path == null)
{
path = Application.persistentDataPath + "/";
}
return path;
}
}
}
public class LuaLoader
{
public string LoadLua(string luaName)
{
//string path = Application.persistentDataPath + "/Lua/";
string path = Application.persistentDataPath + "/";
string str = File.ReadAllText(path + luaName);
return str;
}
}