# UE 蓝图篇
蓝图作为 Unreal 的大杀器,为 Unreal 提供了可视化编程的能力,把一些代码层面的概念通过可视化形式实现,从而能够让艺术家和策划们实现更为复杂的逻辑。
一句话讲:让不会写代码的人,可以基于已有的内容,通过排列组合的形式实现复杂业务。
# 蓝图类型
Unreal 4 的蓝图目前有以下几种:
/** Enumerates types of blueprints. */ | |
UENUM() | |
enum EBlueprintType | |
{ | |
/** Normal blueprint. */ | |
BPTYPE_Normal UMETA(DisplayName="Blueprint Class"), | |
/** Blueprint that is const during execution (no state graph and methods cannot modify member variables). */ | |
BPTYPE_Const UMETA(DisplayName="Const Blueprint Class"), | |
/** Blueprint that serves as a container for macros to be used in other blueprints. */ | |
BPTYPE_MacroLibrary UMETA(DisplayName="Blueprint Macro Library"), | |
/** Blueprint that serves as an interface to be implemented by other blueprints. */ | |
BPTYPE_Interface UMETA(DisplayName="Blueprint Interface"), | |
/** Blueprint that handles level scripting. */ | |
BPTYPE_LevelScript UMETA(DisplayName="Level Blueprint"), | |
/** Blueprint that serves as a container for functions to be used in other blueprints. */ | |
BPTYPE_FunctionLibrary UMETA(DisplayName="Blueprint Function Library"), | |
BPTYPE_MAX, | |
}; |
# Blueprint Class
蓝图类,可以理解为蓝图系统运行的脚本。通过蓝图编辑器进行创建和修改。
# Blueprint Function Libraries
继承自 UBlueprintFunctionLibrary 类,里面定义了一组静态函数,主要用途是提供给其他蓝图或者业务使用。
# Blueprint Interface
蓝图接口,复数个函数的集合,类比 C++ 的 Interface。之所以有 Interface 的概念,还得从 UObject 说起,由于所有对象都是 UObject,因此多继承将变得非常麻烦(菱形继承问题),因此 Unreal 内基本上都是单继承,但是为了实现复用性,通常多继承需求会通过使用 Interface 来代替。
# Blueprint Macro Library
蓝图宏允许把一组编辑好的节点单独以宏的形式存储,提高复用性,有点蓝图子图的意味在里面
# Enumeration
也没啥好说的,定义在全局的枚举类型,不继承 UObject
# Structure
用来专门定义对象的数据结构,值得注意的是,Structure 并不继承自 UObject,纯纯的就是个结构体
USTRUCT([Specifier, Specifier, ...]) | |
struct FStructName | |
{ | |
GENERATED_BODY() | |
}; |
# Blueprint Level
关卡蓝图,每个关卡都有默认的关卡蓝图,这个蓝图不能单独创建,而是在创建 Level 的时候,会默认生成一个,只能编辑不能增删。
主要功能就是同步事件,类似关卡范围内的事件播报。
# 蓝图内各个控件概念及作用
# Graphs
编辑器独有的一个内容,用来展示图表,默认 Blueprint Class 都会有一个 EventGraph
# Pin
也被称为引脚,是定义一个节点输入输出的节点,如下是一个节点,包含三个引脚:
- Output:输出引脚
- Exec:执行引脚
- Input:Target 参数引脚
# Tunnel
通道,其实就是引脚和引脚之间的连线,表示一个上下游关系
# Functions
函数,很好理解,就是字面意思。但是 Unreal 里的函数又分为两个大类 ——Pure&&Impure,这里的分类还是更加侧重于编辑上
# Pure Funtion
也被叫做纯函数,定义上是指不修改状态或类成员的函数,在编辑层面上则是不存在 exec 引脚。
例如我这里定义了一个 Pure Node,接受两个 int 类型参数,返回一个 int 类型参数,勾选 Pure 选择框的时候,该节点将失去 exec 引脚
通常情况下 getattr 操作和运算符节点默认都是 Pure 节点。
失去 exec 引脚意味着该节点的运行不受 runtime 控制,而是在初始化阶段就完成了。
这个是该节点的内部逻辑,外层节点如果勾选了 Pure,那么内部逻辑的节点都会勾上 Pure,但是保留 exec 引脚
# Impure Function
非纯函数,指代一般的函数,带有 exec 引脚,会在运行过程中,根据 exec 的连线关系来依次执行。
# Macros
简单来说就是预制体,别的蓝图可以引用宏,而宏发生变更会影响所有引用的蓝图。
一般用来把一些重复性的流程简化为宏,可以减少编辑环境下复制粘贴工作量,例如红框里面的内容,其他蓝图也要,不想再复制一份
例如这里每次 tick 触发的时候计算一下 delta 时间和 30 求和然后输出一下(意义不明的逻辑)
为了重用 add 和 print 就可以把它们定义成一个宏节点,这样就可以在别的地方用了,也不需要拷贝大量节点,就能实现尽可能的复用
# Variables
变量,标识这个蓝图内定义的变量,可以在蓝图内部使用。蓝图内可以支持设置节点的初始值,并且支持 setattr 和 getattr 操作
这里定义了一个 getattr 和 setattr,可以看到 getattr 是没有 exec 引脚的,因为它默认是一个 pure 节点。
# Event Dispatchers
事件转发提供了全套的事件系统,通俗来说就是提供了一套对于 Event 的 bind、unbind、dispatch、listen。
可以在任意时间 bind 事件和 unbind 事件,例如这里通过叫 「test」 的 dispatcher 绑定和解绑了 test event 事件
这时候只要有地方触发了这个事件,就会执行 test event 后面的函数「Do Something」
触发事件通过 Call 对应的 dispatcher,例如这里我 Call test,就可以触发 test event 后续的操作。
# 代码层面的理解
前面说到,蓝图本质上就是对逻辑的扩展,那么回归到代码层面上再来理解一下蓝图。
蓝图层面的操作 | 代码层面的操作 |
---|---|
创建一个 Blueprint Class 文件,需要选择继承的文件 | 新建一个类,定义继承关系 |
定义 Variables、Function | 声明函数和变量 |
在 Graphs 里面链接起各个节点 Pin,Tunnel | 代码里面编写执行顺序,调用时机 |
当然,蓝图的功能还远不止这些,例如重写父类函数,蓝图之间相互调用等等。
# 总结
本文主要叙述了蓝图在编辑器层面的一些理解和用法,并引申到代码层面更进一步的理解。现在应该对于蓝图整个的组织形式,各个 UI 控件的定义和功能有了基本的认识。