输出ab包
他会把你创建的ab包都打包
也就是在这里的创建的都打包
string assetBundleDirectory = Path.Combine(Application.streamingAssetsPath, "OutAssetBundles");
if (!Directory.Exists(assetBundleDirectory))
{
Directory.CreateDirectory(assetBundleDirectory);
}
BuildPipeline.BuildAssetBundles(assetBundleDirectory,BuildAssetBundleOptions.None,BuildTarget.StandaloneWindows);
加载ab包里的文本文件
文本类型是 UnityEngine.TextAsset
c# 输出类型是 ab.LoadAsset( xxx ).GetType()
string str = Path.Combine(Application.streamingAssetsPath, "OutAssetBundles", "myab2");
var ab = AssetBundle.LoadFromFile(str);
if (ab == null)
{
Debug.Log("Failed to load AssetBundle!");
return;
}
UnityEngine.TextAsset a = ab.LoadAsset<UnityEngine.TextAsset>("Main.mjs");
Debug.Log(a.text);
官方的Asset Bundle Browser工具有一个bug
如果你的ab包删掉了 并且Browser工具里还引用着 就会报错
需要重启ide
设置ab包 可以直接设置在文件夹里
如果你直接输出ab包里的 GetAllAssetNames 名字
那么会输出路径 我看到的名字也会小写
不过用你自己的名字也是可以获得的
UnityEngine.TextAsset 也可以放在属性里
可以把文本文件拖进去
puerts引擎会加载这些文本
所以自定义loader也必须加进来
热更新的话 可以把mjs文件放到ab包里
debugpath = "";//这个一般输出完整路径
filepath = Path.GetFileName(filepath);
return Main.ab.LoadAsset<UnityEngine.TextAsset>(filepath).text;
就可以运行了!
怎么断点呢?
.vscode里创建一个文件launch.json
{
"version": "0.2.0",
"configurations": [{
"name": "Puerts Debug",
"type": "node",
"request": "attach",
"protocol": "inspector",
"port": 18080
}]
}
port 就是调式的接口 创建JsEnv的时候用
private int JavaScriptDebugPort = 18080;
jsEnv = new JsEnv(new MyLoader(), JavaScriptDebugPort);
还记得 debugpath 吗
务必让他是绝对路径 不然调试不了
在c#里直接 写 \路径是不行的 可以直接在前面加一个 @
举个例子 @“aaaa\bbb\ccc”
直接上代码
好 逻辑分三类
1 puerts自己的js文件 在Resources里这个就不动了 也许以后升级会用到
2 ab包的 这个是热更新用的
3 本地的 设计到调试 所以要把路径正确转换
using System.Collections.Generic;
using System.IO;
using Puerts;
using UnityEditor;
using UnityEngine;
public class MyLoader : ILoader, IModuleChecker
{
public bool FileExists(string filepath)
{
return true;
}
public string ReadFile(string filepath, out string debugpath)
{
debugpath = filepath;
if (filepath.StartsWith("puerts/"))
{
var textAsset = Resources.Load<UnityEngine.TextAsset>(filepath.Replace(".mjs", ""));
if (textAsset != null)
{
// Debug.Log("读的Resources里的:" + filepath);
return textAsset.text;
}
}
if (Application.platform == RuntimePlatform.Android || Application.platform == RuntimePlatform.IPhonePlayer)
{
// Debug.Log("加载ab包里的:" + filepath);
//手机上则直接加载ab包里的
string abPath = "assets/src/tsproj/js/" + filepath;
return Main.ab.LoadAsset<UnityEngine.TextAsset>(abPath).text;
}
else
{
string path = Path.Combine("Assets", "src", "tsproj", "js", filepath);
FileInfo fileInfo = new FileInfo(path);
debugpath = fileInfo.FullName;
using (StreamReader sr = fileInfo.OpenText())
{
string res = sr.ReadToEnd();
sr.Close();
return res;
}
}
}
public bool IsESM(string filepath)
{
return true;
}
}
调试前的时候要设置 Application.runInBackground 看下面代码
Application.runInBackground = true;
jsEnv = new JsEnv(new MyLoader(), JavaScriptDebugPort);
jsEnv.WaitDebugger();
jsEnv.ExecuteModule("Main.mjs");
好 现在开始调试
第一步先运行unity
这个 jsEnv.WaitDebugger();
运行到这里的时候 unity就卡死了
这时候你就可以打开vscode的调试了 就是下面这个 点那个绿箭头
接下来就可以在vscode里断点了
WaitDebugger 是同步的
他的要求是
必须先启动unity 然后再运行vscode调试
他的优点是 可以断点任何一行代码
WaitDebuggerAsync 是异步的
两种情况
1 使用 await
await jsEnv.WaitDebuggerAsync();
运行到这里时还是会卡住 但是他的好处是 不规定启动顺序 先unity 还是先vscode 都行 随便整
2 不使用 await
如果你不需要 WaitDebuggerAsync 卡住
那么可以把 await 去掉
因为 WaitDebuggerAsync 需要时间 断点第一时间不会起作用
这个也不规定启动顺序
所以日常开发 除非要求前面的代码断点 否则用这个是最合适的
在vscode里调试 需要手动写 WaitDebugger 代码
但是在chrome里调试 是不需要写任何代码的 比如 WaitDebugger
用chrome调试
打开Chrome浏览器地址栏,输入
chrome://inspect
加入你自己的地址
18080就是unity里自己输入的端口
点done
然后点
Open dedicated DevTools for Node
就可以了
直接断点就行了 非常方便
手机远程调试在这里
ab包药注意的几点
1.
ab包 分平台 window 和 android 不一样 所以要做区分
2.
ab包加载有一个特点
要么你输入完全的路径
也就是遍历 ab.GetAllAssetNames(); 里输出的那个
要么就只输入名字 不管你文件在哪个路径下 她都能找到
绝对不能只有半个路径 或者 相对路径
所以 最好的办法是全路径