• 【游戏编程扯淡精粹】UE5 蓝图


    【游戏编程扯淡精粹】UE5 蓝图

    最近新学蓝图编程。。还没看蓝图VM代码,有些点不保证准确

    本文主要是从使用角度,分析你为什么需要学习蓝图,蓝图适合做什么,不适合做什么

    最后 Bonus,跟一下 Blueprint Pipeline,梳理一下蓝图的知识结构

    在这里插入图片描述

    大纲

    • 蓝图是什么
    • 蓝图对非程序
    • 蓝图对程序
    • 蓝图适合用于
    • 蓝图不适合用于
    • 蓝图管线
    • 蓝图版本管理
    • 蓝图迁移 Lua

    蓝图是什么

    Blueprint - Wikipedia
    蓝图(英语:Blueprint),港澳地区又称“蓝本”或“蓝纸”,是工程制图的原图经过描图、晒图和薰图后生成的复制品,因为图纸是蓝色的,所以被称为“蓝图”。蓝图类似照相用的相纸,可以反复复制新图,而且易于保存,不会模糊,不会掉色,不易玷污。

    蓝图这个词的本义很接近 Prefab,预制体,蓝图描述一个东西的结构和行为,可以多次拷贝,实例化为具体的实体 Entity

    UE 蓝图是一种资源,把引擎暴功能以可视化脚本的形式暴露出来

    另外,UE3 时代的可视化脚本叫做 Kismet

    蓝图实现原理

    实现原理,基本综合了常见脚本方案的做法

    1. Lua,一般的脚本语言一样,跑解释器执行
    2. IL2Cpp,编译到C++
    3. GDScript,和引擎内核紧密结合

    说下第三点,主要是和 Lua 有区别

    Lua 是通用的,有自己的对象模型,但是接入每个引擎,都需要做一个类型映射,记录额外的类型信息,这是有开销的,想一想各种 SDK 的 XXXVector3 类

    蓝图是直接在 UE 内核上实现的,因此只能 UE 用,没有类型映射的开销

    如果需要 UE 蓝图编辑,在自家引擎跑,就需要实现一个 Compiler,把蓝图翻译成自己引擎的格式,工作量和坑不小

    蓝图对非程序

    脚本对非程序的游戏开发技能提升是有积极意义的

    脚本本质是把 Compiler 和 Linker 集成到 Engine Runtime,这样只要下载游戏就可以编程了,不需要装Visual Studio 或者某种编译工具链(一般很重型),对于UE蓝图,则是把 IDE 集成到 UE Editor

    蓝图目前的功能几乎覆盖了 Gameplay 开发,还包含联网,理论上开发玩法可以靠纯蓝图完成

    有一些纯蓝图开发的案例,作者是非程序,比如谌嘉诚的《死寂》

    总的来说,蓝图降低了编程的门槛

    蓝图对程序

    对程序员,理论上掌握 C++ 和 Lua,不需要学蓝图

    所以其实问题是,没时间学蓝图,怎么用最小成本,学到能看懂别人的蓝图的程度

    笔者采取的策略,是把蓝图翻译成熟悉的 Lua

    学习一门语言关键在于理解语言的语义,或者说VM是如何实现的

    蓝图适合用于

    1. 策划实现流程图,高阶的的逻辑设计,流程整合
    2. 单数据流,不要存数据,把 Input / Output 串联起来 // 局部变量,不要全局变量
    3. 单机流程,不要联网

    说白了,就是策划才写蓝图,蓝图节点由程序实现,不要搞得很复杂

    让策划写脚本,本质是程序和策划工作的解耦,策划提需求,策划自己实现,自己维护和迭代

    这个边界定在哪,其实取决于团队策划的平均水平,没有经验可以从简单做起,如前所说,这是一个机会

    蓝图不适合用于

    说白了,复杂的东西都不适合。。这里针对的是大型项目工程,需要 scale,需要快速定位问题,后期低成本解决性能问题

    反过来说,适合做 Demo,但是 Demo 无法 scale 到大项目

    选择脚本语言需要优先考虑的是性能上的 scale,VM 的性能决定了能承载多复杂的代码(指令吞吐量),开发写得很爽,性能不行,最后还是要 C++ 化

    然后是工程上的 scale,不解释了。。

    蓝图在这两点上和 Lua 基本没法比,所以蓝图 VM 也没有深入理解的必要,别用蓝图就完了

    蓝图问题案例1

    重构的问题,拿到 Lyra 的代码,把 C++ 代码的 “Lyra” 全局替换成自己项目前缀,Boom,蓝图爆炸了,因为蓝图里都还是引用的 LyraXXX 类型

    移植的问题,这和 UE 插件本身也有关系,但是可以看出,即使是很简单的情形,也很麻烦

    Lyra 要接入一个背包插件,要把插件中的 ExamplePlayerController(蓝图实现) 移植到 LyraPlayerController(C++实现) 上

    如果都是 C++,把 ExamplePlayerController 代码复制粘贴,合并到 LyraPlayerController 下面,再全局文本替换 ExamplePlayerController 为 LyraPlayerController,ez,10min 搞定

    蓝图呢?蓝图的属性和函数要拷贝过去吧,直接CV,Boom,编辑器 Crash,最后找了个插件拷贝过去了

    在这里插入图片描述

    拷贝过去还是编译不了,为什么呢,因为蓝图是有类型的,ExamplePlayerController.MyMethod 节点和 ExamplePlayerController 类绑定了,要把原来的节点删掉,再拖出来新节点 LyraPlayerController.MyMethod ,所有连线重新连一遍,有的节点要连五根线。。

    这样的操作,需要搜索引用,然后一个一个节点去改

    蓝图问题案例2

    项目用蓝图开发一个月了,补充一下多人开发的问题

    项目起点是一些 Demo 的混合,有大量蓝图脚本,多人在一个模块上开发时非常痛苦

    多人开发阻塞

    1. 拉新版本,点击 Play 发现蓝图编译不过
    2. 其他人在修改一个蓝图文件,我就不能修改了,UI 美术改控件蓝图基本半天以上

    Crash 率

    1. 不低,其他项目反馈到的,包括编辑时和运行时

    编辑效率

    1. 无法看 Diff,不知道某个提交改了什么
    2. 无法搜索某个符号的引用,哪里引用了这个变量 / 函数
    3. 没有文件列表,需要搜索+鼠标点击1-2次,才能跳转到某个蓝图

    这里说无法,确切的说是不可用,有蓝图 Diff,有全局搜索,效率低得没法用

    对比Lua的文件列表

    在这里插入图片描述

    蓝图问题小结

    1. 蓝图是二进制格式
    2. 版本管理,多人协作开发,分支并行开发不可用
    3. 重构困难,移植别人的代码困难
    4. 信息密度低,占据屏幕面积大
    5. 蓝图是有类型系统的,并且依赖于 UE Editor 打开加载整个项目
    6. 蓝图不是通用编程语言,缺乏其他脚本语言的基本特性
    7. 蓝图是为了解决可视化编程的问题,并为易用性做了妥协和阉割
    8. 蓝图编辑依赖于 UE Editor 作为 IDE,而这个 IDE,显然干不过 Visual Studio 和 JetBrain
    9. 蓝图编辑依赖于频繁的鼠标点击,编辑效率低
    10. 蓝图代码散落在工程各个地方,你需要一个一个用鼠标点开
    11. BUG 率 / ,不会比 Lua 更好

    说白了,可用性低,开发效率低

    语言 BUG 率要求很高,是程序员的 trust base,出了问题老是需要怀疑是不是语言出了 BUG,定位问题的效率会大打折扣

    蓝图管线

    Blueprint_poster_18x24

    BP 用于扩展

    1. BP Actor
    2. BP Component
    3. BP EventGraph

    Actor和Component其实也属于继承C++类,BP Actor对标Unity Prefab

    EventGraph对标Flow,是BP相比于C++和Lua最大的优势


    BP属性

    1. Variable
    2. Function
    3. Macro
    4. Event Dispatcher // BP <=> BP

    BP类别

    1. Actor
    2. Level
    3. Anim
    4. Sequencer
    5. UMG
    6. Niagara,特效

    C++ <=> BP

    1. 继承,BP可以继承C++类
    2. Event/Function/Var,C++定义,暴露给BP

    BP <=> BP

    1. 存BP类型的变量,然后调用
    2. 接口,类似Go
    3. 走C++做桥接
    4. Event Dispatcher

    标准库

    1. FuncLib,有C++实现的,也有BP实现的
    2. MacroLib,BP Macro

    蓝图版本管理

    • 本质是因为蓝图是二进制格式,同一文件同一时刻只能一个人修改,导致版本管理的并行开发失效
    • 所有人用 UE 集成的版本管理来 checkout 蓝图
      • 不要用 P4V 或者 P4 命令行绕开,UE checkout 并不会 p4 lock,只是 UE 里警告拦一下
    • 程序不要用蓝图编程,用 C++ 或者 Lua
    • 蓝图本地化生成 C++,不可用
    • 蓝图 Merge & Diff,不可用

    UE 里修改蓝图前点一下保存,有其他人 checkout 了就别改了(你被阻塞了)

    在这里插入图片描述

    蓝图本地化

    1. UE5 不支持
    2. 生成代码勉强可读,但是不能用于继续在C++上开发

    这个生成代码,更像是 IL2CPP,只是打包时用,开发还是蓝图编程

    蓝图 Merge

    经过测试,不好用,并不能自动 Merge,所以只是一个 Diff,而且 Diff 也很糟糕

    蓝图迁移 Lua / C++

    UnLua 可以完全替代蓝图,可以增量地把蓝图 Lua 化

    • 控件蓝图,因为使用蓝图编程,导致 UI 程序和 UI 美术无法并行开发,优先迁移
    • 团队里很多人都涉及修改的,容易冲突和编译不过的蓝图,优先迁移

    ----- 增加一些后续日常开发中的案例和问题

    节点和类型绑定导致难以重构

    一个Widget变量类型从UniformGrid 改成 Grid

    然后就break了,要全部重新连,哪怕两个类型都有ClearChildren接口(以及AddChildToUniformGrid
    AddChildToGrid),但是ClearChildren不是两个类的基类里的,就会break

    语言有类型系统本身是帮助重构的,但是这里却反而很麻烦
    在这里插入图片描述

    UE编辑器崩溃+蓝图没保存=寄

    实际开发中,编辑器崩溃率不低,一部分是UE引擎问题,一部分是项目人多了,用法可能超出UE的考虑

    蓝图搜索很慢,还有漏

    使用上,建立索引很慢,搜索相当于全局搜索字符串

    曾经查一个偶现的鼠标Cursor没了的问题,在蓝图里搜 PlayerController.bShowMouseCursor,非常痛苦,最后还是没有定位问题

    没有看过底层实现机制
    在这里插入图片描述

  • 相关阅读:
    Windows Server 2012 R2系统远程桌面的数字证书算法SHA1升级到SHA256
    Python 使用PIL读取图像自动旋转exif信息
    Linux之输入输出重定向和管道
    使用小程序制作一个音乐播放器
    VUE3中watch和watchEffect的用法
    ONLYOFFICE 8.1版本桌面编辑器测评
    Linux动静态库
    基于keras的疫情预测模型的设计与实现
    RabbitMQ配置
    面试~jvm(JVM内存结构、类加载、双亲委派机制、对象分配,了解垃圾回收)
  • 原文地址:https://blog.csdn.net/zolo_mario/article/details/127432045