ue4+html5动态加载pak,GitHub - emrahgunduz/unrealEngine-html-pak-downloader: Unreal Engine - HTML5 Downlo...

UnrealEngine-HTML-PakDownloader

Unreal Engine - HTML5 Download Paks on the fly

So, I've been trying to understand how HTML packaging's "Download maps on the fly" works underneath, and make sure that it works for me. Currently this feature is marked as experimental. If enabled, it keeps created pak files in a folder near your binaries and only packages the minimum necessities into your data file. But it has a problem.

If you have multiple levels, and want them to be downloaded by this feature, it will not work. Currently on-the-fly only downloads and mounts your first map from the game. Rest is currently up to you.

I wanted this feature badly. As the current project required multiple huge levels with all different assets inside. Creating a single data file resolves in GB's of file. Only option was to keep the pak files (that were simply 20-100 mbs) and download them in background, mount them then use if loaded correctly. Also it would be possible to download them while the user was changing levels (by adding a between-levels map to make sure that everything gets downloaded, if not already).

If you check the engine source, you'll find the responsible class is "MapPakDownloader". Which does its job perfectly and is really easy to read and understand. I simply got what I needed from this code, created a blueprintable class for the simple purpose of a working download-on-the-fly feature. Remember that this code is actually a prettified, and ripped-what-i-needed version of the "MapPakDownloader".

This repository contains a first person shooter game with multiple levels + the source code of the PAK downloader. Game is created in version 4.10 of UE but c++ code works in 4.9 also.

What is what.

In the H file, you can see that I've three delegates for download "progress", "error" and "completed" events.

DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FPackageDownloader_OnDownloadComplete, FString, mapName);

DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FPackageDownloader_OnDownloadError, FString, mapName);

DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FPackageDownloader_OnDownloadProgress, FString, mapName, int32, progress);

A static string array to keep track of mounted maps (as I was not able to find something in the core to check mounted pak files).

static TArray MountedMaps;

A static method to get a refence to a PackageDownloader

UFUNCTION(BlueprintPure, Category = "Package Downloader")

static UPackageDownloader* GetPackageDownloader(bool& IsValid);

Delegate methods, and a bunch of public methods, & private variables.

CPP file includes a few other things. Two delegates for passing methods as event callbacks, a class to start the download and call those event callbacks. Also the main downloader for making everything work together.

What does the code do?

First there is the FEmscriptenPAKHttpFileRequest class. This class is responsible for calling the emscripten wget2 method to download the pak file, and make the calls to delegates on any occuring events. It simply returns itself to static event methods to be able to call them. You can duplicate this process for most of the emscripten methods, which is a magical place :)

#ifdef EMSCRIPTEN

emscripten_async_wget2(

TCHAR_TO_ANSI(*(Url + FString(TEXT("?rand=")) + FGuid::NewGuid().ToString())),

TCHAR_TO_ANSI(*FileName),

TCHAR_TO_ANSI(TEXT("GET")),

TCHAR_TO_ANSI(TEXT("")),

this,

&FEmscriptenPAKHttpFileRequest::OnLoad,

&FEmscriptenPAKHttpFileRequest::OnError,

&FEmscriptenPAKHttpFileRequest::OnProgress

);

#endif

I had to define compiler arguments where emscripten (and import for emscripten.h file) are needed. This was because Visual Studio was not able to find the file (source listed in project does not include emcc source folder) and is already available in compile time. You can add a search path for emcc but this is sufficient enough for me.

UPackageDownloader has just a few methods. One to set the map name, and another to start downloading. You can see that there are a few lambda methods in there. These are passed to FEmscriptenPAKHttpFileRequest as event callbacks. You can think lambda methods as collapsed modules in the blueprint area (not the same but can be imagined as similar things).

How about the blueprint side?

The sample game is the original first person shooter template, coming with UE4. I just copied everything from the original map to 3 others. There is a blueprint actor, which works as a gate between maps. These gates are also responsible for downloading the required pak file.

687474703a2f2f656d72616867756e64757a2e636f6d2f77702d636f6e74656e742f75706c6f6164732f6769746875622f612e6a7067

The gate is a box that contains a collision box to detect player's entrance. A door to keep player outside until the map is mounted. Name of the map that the door loads and the current progress of the download. Plus a light so that inside can be seen :)

687474703a2f2f656d72616867756e64757a2e636f6d2f77702d636f6e74656e742f75706c6f6164732f6769746875622f622e6a7067

Gate variable "Travel to map" is public which can be set from editor in map. So it is really easy to drag-drop a working downloader in the game. A construction script was built to show the name.

687474703a2f2f656d72616867756e64757a2e636f6d2f77702d636f6e74656e742f75706c6f6164732f6769746875622f632e6a7067

Event Graph has a few parts in it, that are commented.

First, we listen for a gate entrance with an overlap test for the player.

687474703a2f2f656d72616867756e64757a2e636f6d2f77702d636f6e74656e742f75706c6f6164732f6769746875622f642e6a7067

Second part gets reference to a package downloader and sets the map to download. If the map is already downloaded, the gate door opens. If not download starts.

687474703a2f2f656d72616867756e64757a2e636f6d2f77702d636f6e74656e742f75706c6f6164732f6769746875622f652e6a7067

We need to assign our callback events before the download.

If we were unable to download the map, we change the text on the gate.

Progress is printed on gate door, too.

687474703a2f2f656d72616867756e64757a2e636f6d2f77702d636f6e74656e742f75706c6f6164732f6769746875622f662e6a7067

687474703a2f2f656d72616867756e64757a2e636f6d2f77702d636f6e74656e742f75706c6f6164732f6769746875622f682e6a7067

687474703a2f2f656d72616867756e64757a2e636f6d2f77702d636f6e74656e742f75706c6f6164732f6769746875622f692e6a7067

When the download completes, gate door opens.

687474703a2f2f656d72616867756e64757a2e636f6d2f77702d636f6e74656e742f75706c6f6164732f6769746875622f6a2e6a7067

687474703a2f2f656d72616867756e64757a2e636f6d2f77702d636f6e74656e742f75706c6f6164732f6769746875622f672e6a7067

That's all. Package the game and test it for yourself.

Do not forget to check the "list of maps" for packaging. You must define your maps (project properties -> packaging).

687474703a2f2f656d72616867756e64757a2e636f6d2f77702d636f6e74656e742f75706c6f6164732f6769746875622f6b2e6a7067

Also, remember to enable the "download maps on the fly" (project properties -> html)

687474703a2f2f656d72616867756e64757a2e636f6d2f77702d636f6e74656e742f75706c6f6164732f6769746875622f6c2e6a7067

Some warnings:

You can download a few maps at the same time. But be careful, as the downloads are async you may download a single map twice. I wrote a simple check for this occasion, if the same map gets downloaded twice, the second time it does not get mounted. Trying to mount the same map will crash the game in browser. You can also add a few lines of code to check the array if the current map is already downloaded in the OnFileDownloadProgress callback, cancel the download and raise an OnPackageDownloadCompleted event.

If the internet connection breaks while a download continues, currently it crashes the game. In the eyes of UE4, this is a fatal issue. Simply add another if-else statement in window.onerror definition in the html file, to get rid of this fatal issue, or your game will be removed from the scene and downloader will not issue an error (I left the html file as-is, you must change it if you need it).

Currently the code does not work with "Level Transition - Delta packs". You'll need to keep track of where user is and which map he/she is going to go. Merge those to something like "LevelOne_LevelTwo" and check if you can download that map. If you cannot, use the "LevelTwo" file instead. As I do not need transition deltas in my game I removed the code from my version. Check "MapPakDownloader" if you need deltas, and implement to the code.

You may need to right click the project file and click "Generate Visual Studio project files" as the repository does not contain the Intermediate folder to save space.

The code and blueprint can be improved vastly. I just wanted to show a way for understanding how downloading and mounting a package for HTML games can be accomplished.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
引用中提到了一些jQuery的核心函数,包括选择器函数、创建对象函数和回调函数等。其中,jQuery(expression, [context])函数用于在全局范围或指定的上下文范围内选择元素;jQuery(html, [lownerDocument])函数用于根据HTML创建jQuery对象;jQuery(elements)函数可以将DOM对象转换为jQuery对象;jQuery(callback)函数是$(document).ready()的缩写,用于在文档加载完毕后执行回调函数。 引用提到,在jQuery库中,可以使用jQuery = window.jQuery = window.$来创建jQuery对象的引用。此外,还有两个备份用的变量_$和_jQuery,以便在需要时使用noConflict()方法来交还使用权。 引用中列举了一些jQuery对象常用的函数,例如size()可以返回jQuery对象中元素的个数,length也可以用于返回元素个数。另外,selector可以返回jQuery对象的选择器,context可以返回jQuery对象的上下文,get()函数可以返回所选中的jQuery对象的DOM数组,get(index)可以返回指定索引的DOM元素。 根据以上引用内容的相关信息,file:///C:/Users/liyji/AppData/Local/Temp/LogiUI/Pak/js/jquery-1.3.2.min.js是一个文件路径,可能是指向一个包含jQuery库的文件。这个文件可能包含了jQuery的核心代码,包括选择器和函数的实现。这个文件可能是一个旧版本的jQuery库,具体版本是1.3.2。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [jQuery-1.3.2.js学习笔记](https://blog.csdn.net/cch345/article/details/4621516)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值