Skip to content

[UE] JavaScript/NodeJs在UE里面的文件系统访问机制 #2281

@llint

Description

@llint

我目前使用了protobufjs动态加载proto文件,代码如下:

import { toDelegate } from 'puerts';
import * as UE from 'ue'

import { load } from "protobufjs";

interface GM_NscmSessionTest_C extends UE.Game.TestMaps.GM_NscmSessionTest.GM_NscmSessionTest_C {}

class GM_NscmSessionTest_C {
    ReceiveBeginPlay() {
        load("Proto/HeartBeat.proto", function (err, root) {
            if (err)
                throw err;

            // Lookup types (no package name in your proto)
            const HeartBeatRequest  = root.lookupType("HeartBeatRequest");
            const HeartBeatResponse = root.lookupType("HeartBeatResponse");

            // ----------------------------
            // Encode HeartBeatRequest
            // ----------------------------
            const requestPayload = {
                key: "conn-12345",
                time: Date.now()          // int64
            };

            // Optional but recommended
            const reqErr = HeartBeatRequest.verify(requestPayload);
            if (reqErr)
                throw Error(reqErr);

            const requestMessage = HeartBeatRequest.create(requestPayload);
            console.log("requestMessage =", requestMessage);

            const requestBuffer = HeartBeatRequest.encode(requestMessage).finish();
            console.log("requestBuffer =", Array.prototype.toString.call(requestBuffer));

            // ----------------------------
            // Decode HeartBeatRequest
            // ----------------------------
            const decodedRequest = HeartBeatRequest.decode(requestBuffer);
            console.log("decodedRequest =", decodedRequest);

            // Convert to plain object (important for int64)
            const requestObject = HeartBeatRequest.toObject(decodedRequest, {
                longs: String,
                defaults: true
            });
            console.log("requestObject =", requestObject);

            // ----------------------------
            // Encode HeartBeatResponse
            // ----------------------------
            const responsePayload = {
                key: requestObject.key,
                time: Date.now()
            };

            const responseMessage = HeartBeatResponse.create(responsePayload);
            const responseBuffer = HeartBeatResponse.encode(responseMessage).finish();

            // ----------------------------
            // Decode HeartBeatResponse
            // ----------------------------
            const decodedResponse = HeartBeatResponse.decode(responseBuffer);
            const responseObject = HeartBeatResponse.toObject(decodedResponse, {
                longs: String,
                defaults: true
            });

            console.log("responseObject =", responseObject);
        });
    }

    ReceiveTick() {
        console.log("ReceiveOnTick ...")
    }

    ReceiveEndPlay() {
    }
}

export { GM_NscmSessionTest_C }

可以看到上面的protobufjs.load方法尝试加载“Proto/HeartBeat.proto”文件,the Proto目录位于UE项目"CoreGame/Content" 目录下。

实际运行的时候, 出现下面的错误信息:

Puerts: Error: (0x000001BC0ADB2E30) uv_run throw: Error: ENOENT: no such file or directory, open 'C:\Program Files\Epic Games\UE_5.7\Engine\Binaries\Win64\Proto\HeartBeat.proto' Error: ENOENT: no such file or directory, open 'C:\Program Files\Epic Games\UE_5.7\Engine\Binaries\Win64\Proto\HeartBeat.proto'

所以看起来在PuerTS/UE环境下,protobufjs貌似仍然使用了JavaScript的原生文件系统访问方式,这里是在当前运行目录CWD下寻找下属相对目录。

当然,我可以使用${UE.BlueprintPathsLibrary.ProjectContentDir()}/Proto/HeartBeat.proto来获取到绝对路径,并且把路径改成这个以后是可以正确加载对应的proto文件的,但是我不知道这个路径在Packaged Game下是否能正常工作?因为在Packaged Game下,Content目录的内容其实是在UE的虚拟文件系统下管理,但是protubufjs.load应该是使用了NodeJs原生的文件系统访问方式,我不知道PuerTS是否有机制在底层替换了NodeJs的原生文件系统访问方式重定向到UE的虚拟文件系统访问方式?

我还没有Package来测试,但是觉得这个问题可以抛出来讨论一下。感谢

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions