UE4开发HTML5遇到的问题

最近要做一个基于UE4的HTML5仿真项目,没真正做过HTML5的小白,表示很无所畏惧。

首先,找一篇UE4下H5的教程,简单学习一遍:

    安装,环境,项目配置,(打包:不要pak;rendering:移动MSAA 选择NO MSAA;平台:HTML5,Packaging: 勾选Compress File during shipping package),最后下载一个X64的FireFox,或者Chrome。一个个搞下来,觉得已经七七八八了,信心满满。

二、拿个例子(“策略游戏”,又叫:StrategyGame)试验一下,StrategyGame本身不支持H5,不过难不倒我们,且如此来试试:

1、在支持的平台下拉框,勾选HTML5;

2、选择文件-->打包-->HTML5,选择一个目录,就开始等着吧,我这破机器,粗略估计花了20分钟;

3、在上一步选择的目录中,生成一个HTML5目录,进入该目录,找到HTML5LaunchHelper.exe,执行,启动了测试Web服务器,端口默认8000

4、打开FireFox, 浏览器中输入:http://localhost:8000/StrategyGame.html。看到开始下载进度条,稍等几秒钟,就可以开始游戏啦。

三、用NodeJS的Express框架写了一个简易数据提供服务,执行:Node Sat.js。端口在:8081。链接地址:http://127.0.0.1:8081/A。

四、在UE4中,生成一个Actor,在Actor的BeginPlay()中,用Http模块去访问http://127.0.0.1:8081/A,并将结果AddOnScreenDebugMessage(), Alt+P播放一下,正常显示。

这一切都还是挺正常、挺简单的,然鹅,问题还没开始。

五、当我打包成HTML5以后,再测试,哇塞,没结果。后面便开始了我的漫漫探索之路:

       1、可能是UE4的HTML5不支持“HTTP”请求,这个从之前的经验知道,HTML网页是用ajax请求数据的,又一百度,果然后人在说Emscripten,一个用来实现C语言和JavaScript相互调用的家伙,于是一骨脑的学了过了一遍Emscripten,学完了,也会一些你调我,我调你了。

       2、再找一篇JavaScript的快速入门学习一遍,几天下来,基本语法什么的,都弄得差不多了。

      3、于是:就跑到Actor中去,写一个ajax请求吧,于是,便有了:

#ifdef EMSCRIPTEN
extern "C" {
    EM_JS(void, call_alert, (), {
        alert('hello world!');
        //throw 'all done';
    });

    EM_JS(void, getsatcount, (), {
        $.ajax({
          url: "http://127.0.0.1:8081/a",
          data : {
            zipcode: 97201
          },
          success : function(result) {
            //$("#weather-temp").html("" + result + " degrees");
                console.log(result);
                //console.log('hello world!');
                //callback(result)
          },
          error : function(result) {
              console.log(result)
          }
        });
    })
}
#endif

void AHttpActor::BeginPlay()
{
    Super::BeginPlay();

#ifdef EMSCRIPTEN
    getsatcount();

#endif
}

4、打包HTML5,漫长的等待之后,结果出来了,还是挺好的。

接下来的问题是,如何把返回的结果回调啊,再度娘吧。。。就在漫无目的的求索中的时候,

突然发现,UE4中有HTML5的实现,有个文件叫:HTML5HTTP.cpp,啊,原来前面的猜测都是错误的吗?

于是,迫不及待的翻了翻UE4的源码:...\Epic Games\UE_4.23\Engine\Source\Runtime\Online\HTTP\Private\HTML5目录

翻完之后,便又有了这一段代码:

void AHttpActor::MyHttpCall()
{
#ifdef EMSCRIPTEN
    TSharedRef Request = TSharedRef(FHTML5PlatformHttp::ConstructRequest());
#else
    TSharedRef Request = Http->CreateRequest();
#endif

    Request->OnProcessRequestComplete().BindUObject(this, &AHttpActor::OnResponseReceived);
    //This is the url on which to process the request
    Request->SetURL("http://127.0.0.1:8081/a");
    Request->SetVerb(TEXT("GET"));
    Request->SetHeader(TEXT("User-Agent"), TEXT("X-UnrealEngine-Agent"));
    Request->SetHeader(TEXT("Content-Type"), TEXT("application/json;charset=utf8"));
    Request->ProcessRequest();

#ifdef EMSCRIPTEN

}

编译,打包成HTML5,浏览器又没出结果,伤心...哪儿错了...

这时,看到代码中有UE_Log(...),就想,这Log到哪儿去了呢,找啊找,原来在浏览器的F12中,唉,绕了一大圈,最后才绕回到超级无敌的F12,在Log中发现了问题:

已拦截跨源请求:同源策略禁止读取位于 http://127.0.0.1:8081/a 的远程资源。

对这个错误又是一无所知,唉,又一番尝试,一番折腾,捣鼓一会客户端,捣鼓一会Nodejs,再捣鼓一会UE,直到看到了这篇文章,https://www.jianshu.com/p/604f6d5b47d2,比较清晰的阐明了CORS的原理,才知道,原来B网站(UE4.StrategyGame),A网站(NodeJS),游戏页面(来自B网站)要访问A网站就存在跨域问题,要允许跨域,是要让A网站允许跨域,OK,明白之后,设置A网站的跨域就可以啦,如下:

//设置跨域访问
app.all('*', function(req, res, next) {
    // 这里应该是来自UE4的网址:http://localhost:8000
    if( req.headers.origin.toLowerCase() == 'http://localhost:8000'
        || req.headers.origin.toLowerCase() == 'http://127.0.0.1:8000' ) {
        //设置允许跨域的域名,*代表允许任意域名跨域
        res.header("Access-Control-Allow-Origin", req.headers.origin);//
    }
    else
        res.header("Access-Control-Allow-Origin", 'http://10.0.20.36:8000');

    res.header('Access-Control-Allow-Headers', "Content-Type");
    res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");    
    
    // if (req.method.toLowerCase() == 'options')
        // res.sendStatus(200);  //让options尝试请求快速结束
    // else    
    next();
});

最后:再介绍一下抓包工具:Fiddler, 很好用,下载后安装,即可使用,(通过使用代理,监听127.0.0.1:8888),实现抓包。

你可能感兴趣的:(编程语言,UE4,HTML5,跨域,抓包,JS)