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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions