02 Puerts for Unity 加载独立 Js 文件

Puerts for Unity 加载独立.js文件

在上一节中,完成了 Puerts 的基本接入,但是 JavaScrip (后称为 Js)代码还是以字符串的形式存在 c# 代码之中。

在实际项目中,肯定不能是这样。所有的 Js 一定都是以独立文件的形式存在。

所以,需要通过自定义 Puerts Loader 告诉 Puerts 该从磁盘什么位置加载 Js 文件。

创建入口 Js 代码文件

先将上一节的 Js 代码字符复制出来并创建为 main.js,并保存到 Assets/StreamingAssets/Scripts/ 目录中(下一节中,Ts 编译输出目录也将指向此地)。

// Assets/StreamingAssets/Scripts/main.js 文件内容
const CS = require('csharp');
let gameObject = new CS.UnityEngine.GameObject('test');
CS.UnityEngine.Debug.Log(gameObject.name);

为什么要保存在此目录?

StreamingAssets 是 Unity 规定的 流媒体资源存放目录。

在该目录下的资源不会参与引擎编译,也方便使用 AssetBundle 资源热更新方法进行资源热更。

自定义 Loader

Assets/Cs/ 创建 Loader.cs 的 c# 文件,代码如下:

using System.IO;
using UnityEngine;
using Puerts;

public class Loader : ILoader{
    // 限制 debugRoot 属性外部只可访问,不可设置
    public string debugRoot {get; private set;}

    /// 
    /// 获取 Puerts 自带模块路径
    /// 
    /// Puerts 自带模块名称
    /// 模块完整路径
    private string GetPuertsModulePath(string filePath) {
        return PathUnified(Application.dataPath,"Puerts/Src/Resources/",filePath) + ".txt";
    }

    /// 
    /// 判断模块是否为 Puerts自带模块
    /// 
    /// 模块名称
    /// true/false
    private bool IsPuertsModule(string filePath){
        return filePath.StartsWith("puerts/");
    }

    /// 
    /// 构造方法
    /// 
    /// Js 脚本存放目录
    public Loader(string debugRoot){
        this.debugRoot = debugRoot;
    }

    /// 
    /// * 接口要求实现
    /// 判断文件是否存在
    /// 
    /// 文件路径
    /// true/false
    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
    }

    /// 
    /// * 接口要求实现
    /// 文件内容读取
    /// 
    /// 模块路径
    /// 文件完整路径
    /// 文本内容
    public string ReadFile(string filePath,out string debugPath){
        bool isPuerts = IsPuertsModule(filePath);
        debugPath = isPuerts ? GetPuertsModulePath(filePath) : PathUnified(debugRoot, filePath);

        // Puerts 本身调用的 Js 存放在 Resource 目录下,所以可以直接用 Resources.Load 获取
        return isPuerts ? Resources.Load(filePath).text : File.ReadAllText(debugPath);
    }

    /// 
    /// 纠正路径(Windows下路径斜杠不正确的问题)
    /// 
    /// 
    /// 纠正之后的路径
    private string PathUnified(params string[] args){
        return Path.Combine(args).Replace("\\","/");
    }
}

调整入口文件

现在需要对 Assets/Cs/Main.cs 进行些许改造,增加调试开关、调试通信端口号,再把定义好的 Loader 传进去并调用 js 入口文件。

最终代码如下:

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");
    void Start(){
        loader = new Loader(scriptsDir);
        jsEnv = new JsEnv(loader,debugPort);        // 实例化 js 虚拟机
        if(isDebug){                                // 启用调试
            jsEnv.WaitDebugger();
        }
        jsEnv.Eval("require('main')");
    }
    void Update(){ 
        jsEnv.Tick();
    }
}

最后,回到游戏场景中再次运行游戏。看 Js 文件应该有被正确执行。

你可能感兴趣的:(02 Puerts for Unity 加载独立 Js 文件)