蓝图实现任意类型数组排序 Implementation of wildcard array sort in blueprint

1. Overview

​本教程旨在讲解在虚幻引擎(UE4)蓝图(blueprint)中实现任意类型的数组排序,也就是实现泛型数组排序,在UE4的蓝图系统中用Wildcard(通配符)表示泛型。本教程基于选择排序(Selection Sort)和冒泡排序(Bubble Sort)原理,利用蓝图宏,实现了对任意类型数组(Generic TArray)排序的蓝图宏节点。

2. Required Knowledge

​ (1) 基本熟悉ue4,了解蓝图宏库(Blueprint Macro Library)的创建方法;
​ (2) Selection Sort 和 Bubble Sort 排序原理;

3. Why

​UE4的蓝图系统并未内置数组排序(Array Sort)的蓝图节点,但是对数组进行排序可以说是开发中无可避免的问题。虽然在使用C++进行开发时,可以轻易调用C++ STL的排序算法,并使用宏UFUNCTION(BlueprintCallable),将其暴露给蓝图;但是这种处理方式,对于随时新增加的类型(UStruct/UObject派生类),每一种类型的数据都要自定义一个C++版排序函数。既耗费了不必要代码修改和编译时间,又增加了代码冗余。 如果可以用一个节点来完成对任意类型数组排序,显然有极大的好处。
此外,虽然可以在UE4 C++中使用Wildcard 变量来实现数组排序,但是其实现过程较为复杂、繁琐,门框过高。还可能存在适用性的问题,可能无法同时对int,float,struct,object及其派生类(Actor)等都适用。

4. Sort Approach

(1)创建蓝图宏库,鼠标右键->Blueprints->Blueprint Macro Library ->All Classes->Object,以UObject作为蓝图宏库的基类。
(2)My Blueprint窗口,Add New创建二个宏Select Sort、Bubble Sort;
(3)选择排序(Select Sort)

Description:
选择排序(详情请查阅选择排序方法)
bGreater=( Array[min] >Array[i] ) ? true : false;
将Array[min]与Array[i]成员的大小比较结果连接上bGreater(pin)
内部循环根据bGreater(bool)值判断是否交换Array[min]与Array[i]成员位置
排序结束,返回有序数组

图1. 选择排序细节面板,(Array Pin 勾选Pass-by-Reference,以引用方式传递数据);

选择排序(Selection Sort)蓝图宏实现方法

图2. 选择排序蓝图宏;

(4)冒泡排序(Bubble Sort)

​ Description:冒泡排序(详情请查阅冒泡排序方法)
​ bGreater=( Array[j] >Array[j+1] ) ? true : false;
​ 将Array[j]与Array[j+1]的大小比较结果连接上bGreater(pin)
​ 内部循环根据bGreater(bool)值判断是否交换Array[j]与Array[j+1]成员位置
​ 排序结束,返回有序数组

图3. 冒泡排序细节面板,(Array Pin 勾选Pass-by-Reference,以引用方式传递数据);

冒泡排序(Bubble Sort)蓝图宏实现方法!

图4. 冒泡排序蓝图宏;

5. Usage

(1)以上第4步完成,即可任意蓝图中,context menu中输入sort关键词即可查找二个节点;

图5. 从蓝图中查找Bubble Sort/Selection Sort节点;

(2)任意类型数组引脚(pin)连接示例,下图以Bubble Sort节点为例,并随意选取Actor、Struct、Float、Int类型数组;

图6. 不同类型数组排序示例;

(3)排序节点连接方式示例,(数组元素类型必须包含可排序得变量,如float/int类型变量);

图7. Item数组排序示例,Score变量为本例排序指定关键字;

(4)排序方向,升序/降序示例

图8. a. 返回升序数组;

图9. b. 返回降序数组;

(5)二个以上排序变量蓝图引脚连接示例,该类情形最好自定义一个比较函数(Pure函数),如下图所示

图10. 蓝图引脚连接示例;

图11. 二个排序排序变量,大小比较方法示例,并该函数设置成Pure;

6. Shortage

由于冒泡排序和选择排序本身就属于低效的排序算法,此外相较于c++,蓝图执行效率差得多,因此以上二个蓝图泛型排序节点应当只用于长度较小的数组排序(length<100)。若数组长度超过一定值时,会产生明显的卡顿,甚至会直接停止运行,并显示以下错误提示。

LogScript: Warning: Runaway loop detected (over 1,000,000 iterations) - see log for stack trace
BP_HttpActotr_C /Game/Maps/UEDPIE_0_BeginMap.BeginMap:PersistentLevel.BP_HttpActotr_2
Function /Game/Blueprints/BP_HttpActotr.BP_HttpActotr_C:ExecuteUbergraph_BP_HttpActotr:0250

PIE: Error: Infinite loop detected. Blueprint: BP_HttpActotr Function: Branch Call Stack: Show

7. Conclusion

本文主要介绍使用UE4 蓝图宏实现任意类型数组排序的蓝图节点,可以在数组长度较小的情形下,对数组进行排序。由于排序算法和蓝图节点执行的效率均比较低,因此不建议在数组长度大的情形,使用以上节点进行排序。

原创文章,未经允许,禁止转载