在UE5中使用python脚本打包,并将UE嵌入到移动项目项目总结。

第一部分:打包

需求分析

项目的客户端主主体是App,其中包含了游戏功能;为了降低用户使用门槛,App主体只包含UE基本的功能(core),其余大部分游戏资源和游戏功能使用Pak的方式来进行下载和加载。游戏的DS的包包含全部资源,运营根据玩法来部署玩法DS:比如BallServer,ShootServer等等。

所以可以总结出打包脚本的需求和目标:
1.打包DSServer,包含当前游戏版本的全量资源,有几个玩法就打包几个DSServer。
2.打包客户端,包含当前版本的基本功能(core),分Android 和 IOS。
3.使用HotPatcher插件打包Pak包,包含每个游戏的游戏资源(空间包),基础资源包(包含公共游戏资源和Lua脚本)

其实项目依照现在的设计,还有如下问题:
如果有需求导致底层程序框架(c++.修改),那么App就需要更新So/framework或者main.obb中的资源发生了改变,App也需要升级,否则链接线上服务器会导致崩溃等错误。并且安卓很多渠道不支持强制版本更新。理想的情况下,App中应只包含一个通用的UE动态库/framework,这个动态库应该是经过抽象和总结的,包含UE与移动端相互通信的所有函数并且短期内不会更新(统一接口)

客户端,DS,Pak包的版本匹配等详细业务逻辑再次不一一赘述

修改Config文件

在脚本打包过程中,需要修改config文件中的配置来满足我们打包某端时进行特定的设置的的需求,例如:打包Server时根据打包的是哪个玩法的Server来设置DS默认地图,打包客户端时动态的将不需要打包的文件夹(玩法的资源)添加到NeverCook的设置中等。

我写了一个BlueprintLibrary的插件,来在打包脚本中调用插件的函数来操作UE的.ini文件,仅供参考:
https://github.com/BPXXX/UEScriptPackageHelper

打包脚本

有了上述插件之后,我们脚本打包的思路就梳理出来了,其实一共就两步:
1.根据打包的平台和Target设置ini文件的配置。
2.运行UAT命令进行打包

下面用打包客户端的代码举例:
打包客户端函数:


def PackageClientCore(pConfig,pPlatform) :
    FixClientCoreConfig()
    OutDir = OutputRoot + f"/ClientCore/"+pPlatform
    LogDir = LogRoot + f"/Client/"+pPlatform + ".txt"
    RunUATPackage("Client",pPlatform,pConfig,OutDir,LogDir)

修改打包配置

def FixClientCoreConfig():
    #添加基础设置
    for setting in BaseSettings:
        unreal.ScriptPackageHelperBPLibrary.set_string_array(GameIniPath,setting["Section"],setting["Key"],setting["Paths"])
    
    unreal.ScriptPackageHelperBPLibrary.add_array_item(GameIniPath,"/Script/UnrealEd.ProjectPackagingSettings","DirectoriesToNeverCook",MakeConfigFolderPath("/Game/sensen/Patches"))
    #覆盖客户端的两个ServerUrl
    unreal.ScriptPackageHelperBPLibrary.set_string_value(GameIniPath,"/Script/GameplayModule.SenSenGameInstance","ServerURL",IniConfig.ClientServiceUrl)
    unreal.ScriptPackageHelperBPLibrary.set_string_value(GameIniPath,"/Script/ViewDynamicLoadRuntime.CharacterViewComponent","ServerURL",IniConfig.ClientServiceUrl)

运行UAT命令进行打包

def RunUATPackage(pTarget,pPlatform,pConfig,pOutDir,pLogDir):

 

    ProjectDir              =   ProjectPath + "sensen_ue_mobile.uproject" 
    Platform                = "Android"
    PackageConfig            = pConfig
    Unrealexe               = EditorExePath
    EditorIOPort            = "52540"

    UATFileDir     =  UATPath
    if pTarget == 'Client':
        target = "sensen_ue_mobile"
        Platform = pPlatform
        cmd = ""
        if Platform == "Android":
            cmd = f"{UATFileDir}  -ScriptsForProject={ProjectDir} Turnkey -command=VerifySdk -platform={Platform} -UpdateIfNeeded -EditorIO -EditorIOPort={EditorIOPort}  -project={ProjectDir} BuildCookRun -nop4 -utf8output -nocompileeditor -skipbuildeditor -cook  -project={ProjectDir} -target={target}  -unrealexe={Unrealexe} -platform=Android  -cookflavor=ASTC -stage -archive -package -build -pak -compressed -prereqs -archivedirectory={pOutDir} -manifests -clientconfig={PackageConfig} -nocompile -nocompileuat"
        elif Platform == "IOS":
            cmd = f"{UATFileDir}  -ScriptsForProject={ProjectDir} Turnkey -command=VerifySdk -platform={Platform} -UpdateIfNeeded -EditorIO -EditorIOPort={EditorIOPort}  -project={ProjectDir} BuildCookRun -nop4 -utf8output -nocompileeditor -skipbuildeditor -cook  -project={ProjectDir} -target={target}  -unrealexe={Unrealexe} -platform=IOS -stage -archive -package -build -pak -compressed -prereqs -archivedirectory={pOutDir} -manifests -clientconfig={PackageConfig} -nocompile -nocompileuat"
        
    elif  pTarget == 'Server':
        target = "sensen_ue_mobileServer"
        Platform = "Linux"
        cmd = f"{UATFileDir}   -ScriptsForProject={ProjectDir} Turnkey -command=VerifySdk -platform={Platform} -UpdateIfNeeded -EditorIO -EditorIOPort={EditorIOPort}  -project={ProjectDir} BuildCookRun -nop4 -utf8output -nocompileeditor -skipbuildeditor -cook  -project={ProjectDir} -target={target}  -unrealexe={Unrealexe} -platform=Linux -stage -archive -package -build -pak -compressed -prereqs -archivedirectory={pOutDir} -manifests -server -noclient -serverconfig={PackageConfig} -nocompile -nocompileuat"
    


    # 创建文件夹
    output_folder = os.path.dirname(pLogDir)
    os.makedirs(output_folder, exist_ok=True)

    print(f"cmd: {cmd}")

    cmd = f"{cmd} >> {pLogDir}"
    #ret = os.system(cmd)
    ret = subprocess.run(cmd, shell=True, check=True)

    if ret.returncode == 0:
        print(f"Package Success Platform:{Platform} PackageConfig:{PackageConfig}")
    else:
        print(f"Package Failed Platform:{Platform} PackageConfig:{PackageConfig}")
        raise Exception("project build faild!")

打包产物

本项目的DSServer部署在Linux上的,具体的部署方案不在此赘述,下面重点讨论客户端。

IOS
想要UE项目打包为framework,嵌入到移动端IOS工程里,需要勾选Build project as a framework。
在这里插入图片描述

打包后,会发现打包文件下有一个Wrapper文件夹,里面的xcode工程就是UE生成的默认工程
在这里插入图片描述
Android

第一部分:嵌入到移动项目中

IOS

IOS平台下,UE项目作为framework的一些坑,我都记录在另外一篇博客里:https://blog.csdn.net/weixin_43866011/article/details/136842291

下面简述一下工作流程中有用的信息。

设置路径:
可以修改烘焙内容或者framework的路径等等(如下图)
在这里插入图片描述

添加Include路径:
因为是混合开发的项目,所以会有OC端调用UE函数的情况,需要在Header Search Paths添加对应的.h文件。比如在我的项目里写了一个UIOSFunctionLibrary,里面实现了一些让OC端调用UE函数的函数,那么我就需要在路径里加上这个.h文件的路径就好了。需要注意的是UE作为framework这个功能是实验性的,起码我使用UE5.1生成出来的xcode工程,searchPaths是不全的,需要自己补全

在这里插入图片描述

下面我们看看xcode工程里在Build的时候发生了什么:

打开xcode工程,点击Product -> Scheme ->Edit Scheme-> Build Phases

将烘焙好的UE资源拷贝到build目录里。

在这里插入图片描述

将framework拷贝并签名
在这里插入图片描述
所以每次IOS项目的UE的内容(资源或者framework)修改时,只需要替换对应文件夹下的内容重新Build打包就好了。

Android

安卓端的UE混合开发相较于IOS端就没有那么复杂,我写过一篇安卓的混合开发的博客,包括JNI调用的例子:
https://blog.csdn.net/weixin_43866011/article/details/129535092

先这样记录一下,后续针对一些细节再详细更新,如果有问题或者不够详细的地方请大家指正和提出。

  • 7
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值