运行效果如下
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using DefaultNamespace;
using UnityEngine;
using UnityEngine.Networking;
public class LoadDll : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
StartCoroutine(this.DownLoadAssets(() =>
{
gameObject.AddComponent(ABManager.LoadScript("Script.dll.bytes", "CreateCube"));
}));
}
IEnumerator DownLoadAssets(Action action)
{
//找到对应目录
DirectoryInfo direction = new DirectoryInfo(Application.streamingAssetsPath);
//获取目录下所有文件
FileInfo[] files = direction.GetFiles("*", SearchOption.AllDirectories);
//把所有dll文件拷贝到s目录下
foreach (var item in files)
{
if (item.Name.EndsWith(".bytes"))
{
string dllPath = item.FullName.Replace("\\", "/");
UnityWebRequest www = UnityWebRequest.Get(dllPath);
yield return www.SendWebRequest();
if (www.result!=UnityWebRequest.Result.Success)
{
Debug.Log(www.error);
}
else
{
byte[] data = www.downloadHandler.data;
ABManager.assetDatas.Add(item.Name,data);
Debug.Log(item.Name);
}
}
}
action();
}
}
using System.Collections.Generic;
using System.IO;
using System.Linq;
using HybridCLR.Editor;
using UnityEditor;
using UnityEngine;
namespace DefaultNamespace
{
public class ABTool : Editor
{
static string dllpath=Application.dataPath+"/../"+HybridCLRSettings.Instance.hotUpdateDllCompileOutputRootDir;
[MenuItem("ABTool/生成AB包/Android")]
public static void CreatAB_Android()
{
var target = BuildTarget.Android;
CreatAB(target);
}
[MenuItem("ABTool/生成AB包/Windows64")]
public static void CreateAB_win64()
{
var target = BuildTarget.StandaloneWindows64;
CreatAB(target);
}
public static void CreatAB(BuildTarget target)
{
//找到对应目录
DirectoryInfo direction = new DirectoryInfo(dllpath + "/" + target);
//获取目录下所以文件
FileInfo[] files = direction.GetFiles("*", SearchOption.AllDirectories);
//把所有dll文件拷贝到目录下
foreach (var item in files)
{
if (item.Name.EndsWith(".dll"))
{
string dllpath = $"{ABTool.dllpath + "/" + target}/{item.Name}";
string dllBytesPath = $"{Application.streamingAssetsPath}/{item.Name}.bytes";
File.Copy(dllpath,dllBytesPath,true);
Debug.Log($"hotfix dll {dllpath} -> {dllBytesPath}");
}
}
//预制体
List<AssetBundleBuild> abs = new List<AssetBundleBuild>();
//找到预制体目录下的所有目录
string path = $"{Application.dataPath}/Prefabs/";
DirectoryInfo directoryInfo = new DirectoryInfo(path);
DirectoryInfo[] directions = directoryInfo.GetDirectories();
//每个目录打一个AB包
for (int i = 0; i < directions.Length; i++)
{
List<string> prefabAbssets = new List<string>();
Debug.Log("打包文件夹:"+directions[i].Name);
FileInfo[] fileinfos = directions[i].GetFiles("*", SearchOption.AllDirectories);
Debug.Log("目录下文件个数:"+files.Length);
foreach (var item in fileinfos)
{
if (item.Name.EndsWith(".meta"))
{
continue;
}
Debug.Log("打包文件:"+item.Name);
prefabAbssets.Add(item.FullName.Replace("\\","/"));
AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate);
}
AssetBundleBuild PrefabsAb = new AssetBundleBuild
{
assetBundleName = directions[i].Name,
assetNames = prefabAbssets.Select(s => ToReleateAssetPath(s)).ToArray(),
};
abs.Add(PrefabsAb);
}
//构建AB包放到S目录下
BuildPipeline.BuildAssetBundles(Application.streamingAssetsPath, abs.ToArray(),
BuildAssetBundleOptions.None, target);
AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate);
}
public static string ToReleateAssetPath(string s)
{
string path = s.Substring(s.IndexOf("Assets/"));
Debug.Log(path);
return path;
}
}
}
using System;
using System.Collections.Generic;
using System.Reflection;
using UnityEditor;
using UnityEngine;
namespace DefaultNamespace
{
public class ABManager
{
public static Dictionary<string, byte[]> assetDatas = new Dictionary<string, byte[]>();
public static byte[] GetAssetData(string dllName)
{
return assetDatas[dllName];
}
public static AssetBundle LoadAB(string dllName)
{
return AssetBundle.LoadFromMemory(GetAssetData(dllName));
}
public static T Load<T>(string abName, string assetName) where T : UnityEngine.Object
{
AssetBundle ab = LoadAB(abName);
return ab.LoadAsset<T>(assetName);
}
public static Type LoadScript(string abName, string assetName)
{
Assembly ass = Assembly.Load(GetAssetData(abName));
return ass.GetType(assetName);
}
}
}
将他俩放到同一个文件夹下面,同时CreateCube中可以写关于这个东西的脚本,热更会调用这个脚本,无需挂载