Unity的Puerts框架接入流程
参考文献
Puerts的官方仓库: 链接
Puerts for Unity 基本接入: 链接
视频教程: 链接
导入puerts
- 从 Releases 页面下载对应版本的 Puerts ,并解压;
lugins_V8_verx.tgz
,编译好的 V8 文件。Sources_code(zip)
,Puerts 源码。
- 拷贝源码
puerts-x.x.x.zip
解压出来的unity/Assets/Puerts/
目录到项目/Assets/
目录下; - 拷贝
Plugins_V8_verx.tgz
解压出来的Plugins/
目录到项目/Assets/
目录下;
创建入口文件
- 在 Assets/Cs/ 创建Main.cs入口文件,绑定到场景节点中。
//Main.cs
using UnityEngine;
using Puerts; // 引用 Puerts
using System.IO;
class Main : MonoBehaviour
{
public bool isDebug = false; // 是否开启调试
public int debugPort = 43990; // 调试端口号
public JsEnv jsEnv; // 定义 jsEnv
private Loader loader;
private string scriptsDir = Path.Combine(Application.streamingAssetsPath, "Scripts");
async void Start()
{
loader = new Loader(scriptsDir);
jsEnv = new JsEnv(loader, debugPort); // 实例化 js 虚拟机
if (isDebug)
{
// 启用调试
await jsEnv.WaitDebuggerAsync();
}
jsEnv.Eval("require('main')");
}
void Update()
{
jsEnv.Tick();
}
}
- 增加 StreamingAssets/Scripts/ 文件夹,创建main.js文件。
//main.js
var _csharp = require("csharp");
_csharp.UnityEngine.Debug.Log('Hello World');
StreamingAssets
是 Unity 规定的 流媒体资源存放目录。
在该目录下的资源不会参与引擎编译,也方便使用 AssetBundle 资源热更新方法进行资源热更。
自此可以用JavaScript开发unity项目了。
自定义Loader
- 在 Assets/Cs/ 创建 Loader.cs 的 c# 文件,代码如下:
//Loader.cs
using System.IO;
using UnityEngine;
using Puerts;
public class Loader : ILoader
{
// 限制 debugRoot 属性外部只可访问,不可设置
public string debugRoot {
get; private set; }
/// <summary>
/// 获取 Puerts 自带模块路径
/// </summary>
/// <param name="filePath">Puerts 自带模块名称</param>
/// <returns>模块完整路径</returns>
private string GetPuertsModulePath(string filePath)
{
return PathUnified(Application.dataPath, "Puerts/Src/Resources/", filePath) + ".txt";
}
/// <summary>
/// 判断模块是否为 Puerts自带模块
/// </summary>
/// <param name="filePath">模块名称</param>
/// <returns>true/false</returns>
private bool IsPuertsModule(string filePath)
{
return filePath.StartsWith("puerts/");
}
/// <summary>
/// 构造方法
/// </summary>
/// <param name="debugRoot">Js 脚本存放目录</param>
public Loader(string debugRoot)
{
this.debugRoot = debugRoot;
}
/// <summary>
/// * 接口要求实现
/// 判断文件是否存在
/// </summary>
/// <param name="filePath">文件路径</param>
/// <returns>true/false</returns>
public bool FileExists(string filePath)
{
// Puerts 需要调用到其目录下的一些 js 文件,这里通通判为存在
if (IsPuertsModule(filePath)) return true;
#if UNITY_EDITOR
return File.Exists(PathUnified(debugRoot, filePath));
#else
return true;
#endif
}
private string PathToUse(string filepath)
{
return
// .cjs asset is only supported in unity2018+
filepath.EndsWith(".cjs") || filepath.EndsWith(".mjs") ?
filepath.Substring(0, filepath.Length - 4) :
filepath;
}
/// <summary>
/// * 接口要求实现
/// 文件内容读取
/// </summary>
/// <param name="filePath">模块路径</param>
/// <param name="debugPath">文件完整路径</param>
/// <returns>文本内容</returns>
public string ReadFile(string filePath, out string debugPath)
{
bool isPuerts = IsPuertsModule(filePath);
debugPath = isPuerts ? GetPuertsModulePath(filePath) : PathUnified(debugRoot, filePath);
string pathToUse = this.PathToUse(filePath);
// Puerts 本身调用的 Js 存放在 Resource 目录下,所以可以直接用 Resources.Load 获取
return isPuerts ? Resources.Load<TextAsset>(pathToUse).text : File.ReadAllText(debugPath);