前言

       近期的一个小研究,也是对UE的在一次深入学习。将柱状与曲线进行合并已3D的数字孪生的形式进行多维度的数据展示。
本次教程将不在涉及UE的基础使用说明,如果有哪些节点和逻辑不明白的朋友可以去翻看下我前面的《UE4之全流程开发基础知识》。同时本次使用的UE版本为UE5体验版,可能会与上期教程略有不同。

项目地址

百度云

https://pan.baidu.com/s/1ovqYBz2hssy10Nbd51GUYg    提取码:Xnjl

Github

https://github.com/AnzaiDesign/visualization 

A.准备基础模型

       首先我们需要准备一个模型,这个模型会在后面被蓝图自动生成。模型的样式形状各位可以根据自己的喜好自行修改,这里我就用了一个立方体。但是其中要主要的是,首先UE并没有特定的尺寸。所以最好用其他三维软件进行制作,并且各位请注意图中模型的实际轴坐标点,必须放置在模型的最下方,这样才能在后续的制作中已轴坐标进行修改模型。还有就是图中UE给咱们计算的“大约尺寸”这个数值,也需要咱们记好方便咱们后续根据这个数值去调整实际的图表尺寸。

B.准备字体

       创建一个字体并命名为“Oswald_Light”,这里的命名可以根据自己的喜好。

B.1.设置字体缓存类型

       设置字体缓存类型为“离线”。

B.2. 确认修改缓存类型

B.3. 选择所需字体

B.4.设置细节与页面详细信息

       具体这些参数为什么要这么设置,其实我也是按照官方的参数来的并没有深入的去了解。

B.4.1.细节

B.4.2. 页面详细信息

C.准备材质

       一个图表由1组或多组数据组成,每组数据均有标注元素、图表颜色和字体材质,随意我们最少需要3个材质来做支撑。这3个材质分别是:Histogram(图表颜色材质)、Name_tagging(标注元素材质)、Oswald_material(字体材质)。

C.1. Histogram

       首先我们需要一个可以用来区分每个数据组折线与柱状的材质。同时我想让其从顶部到底部进行一个渐变隐藏。

C.1.1. 材质属性

       既然是渐变隐藏,那么我们就需要将材质属性的混合模式调整为“半透明”模型。

C.1.2. Color/Color coefficient

       为了能够让对每组折线与柱状进行区分,我们这里需要创建一个4位参数“Color”与一个常量参数“Color coefficient”。这2个参数可以在后续的蓝图中通过创建动态材质实例对齐逐一修改。“Color coefficient”参数与“Color”参数相乘,在后续的蓝图中我们可以通过调整“Color coefficient”来控制其发光的亮度,变相的达到一种用户交互的功能。

C.1.3. UVW

       如果我们想要模型一直从上到下渐变隐藏,那么我就需要用到“Bounding Box Based”节点,也就是UVW节点。正常情况下我们仅需要输入UVW节点中B节点即可得到我们想要的效果。但是为了我们能够更好的修改并达到我们满意的效果,那么我们就需要通过“Power”权重节点来控制其范围。
首先我们将UVW节点的B输入到“Power”节点的”Base”作为基础。然后我们需要创建一个4维向量参数“Mask B”与一个常量参数“transparency coefficient”相乘后输出给“Power”的“Exp”,最后将”Power”输出给材质的透明度节点就可以实现随意控制范围。
“Mask B”参数,用来控制整体的透明度,B值如果为“0”那么整体将是不透明。
“transparency coefficient”参数,用来控制透明度的范围,数值越大透明的范围越大。

C.1.4. 材质实例

       完成上述的内容后,我们可以创建一个材质实例并赋予给基础模型,然后通过调整右侧细节面板内的各类参数来得到我们想要的想过。

C.2. Name_tagging

“Name_tagging”材质时用来设置数据点标注的材质,方法与“Histogram”大致相同。

C.3. Oswald_material

       “Oswald_material”材质是一个文本材质,主要用来渲染蓝图中的文本内容。其中的”Color”参数同样用于后续蓝图的颜色标注,就不做多余说明了。

C.3.1. 材质属性

       这里我们需要先将材质属性内的,混合模式更改为“已遮罩”模型,这样我们就可以使用“不透明蒙版”接口。

C.3.2. FontSampleParameter

       “FontSampleParameter”是UE的专门的字体纹理参数节点。注意这个并不是“Texture Sample”纹理节点,而且各位不要选错成“FontSample”节点,UE的文本纹理节点并不能直接右键转换为参数,所以我们一定要选择这个“FontSample”节点,这样后续如果我们想通过实例材质动态修改文本纹理就可以直接进行更改其参数。

  •  细节面板

       这里我们通过字体选择我们直接已经设置好的字体纹理。因为字体与字体的载量不一样,所以可能有些字体会有1+N个页面,所以我们需要在字体纹理页面这里设置我们所需的页面索引。

C.3.3. Lerp

       之后我们“FontSampleParameter”作为“Lerp”的“Alpha”,通过控制“Lerp”的A值和B值来活动一个不透明蒙版,这里要注意的是,AB值的反差越大其文字则越清晰。如果反正AB值的正负,则会获得另一种效果。

D.准备数据

       最后我们要准备一个供我们后续调用的数据表,具体怎么创建数据表可以查看我上期的教程。这里就不在说明了。

D.1. 表结构

       首先我们创建一个表结构并命名为“Spline_Points_Structural”。
       每个图表的数据均由数值与时间组合而成。如果按照上期教程所讲,那么若果有几组数据我们就需要几个数据表。但这次我准备通过数据表列与行的形式来获取所需要的数据,这样以来我们就可以仅用一个数据表就可以装下多组数据。

D.2. 表

       之后我们来创建一个数据表,并命名为“Spline_Points”。
       “Data 01 – 05”数列均是每组数据的所有参数。这样一来如果我们后续需要新增数据组,直接更改表结构即可。然后我们通过先获得列数据,然后再通过行名称或索引获取到指定的数据,并且每行数据都会有一个相同的时间参数。

E.世界场景设置

E.1. 玩家控制器

       首先创建了一个蓝图,选择“玩家控制器”类型并命名为“visualization_play”用来设置我们一些基础性的控制。

E.1.1. 细节面板

       这里我们主要设置一下细节面板中的“鼠标接口”,勾选上显示鼠标光标、启用点击事件、启用悬停事件。下方的默认鼠标光标类型可以自行选择。

E.2. 角色

       之后创建一个蓝图选择“角色”类型并命名为“visualization_role”。

E.2.1. 添加蓝图基础组件

       这里我为角色蓝图另外增加了2个组件“CineCamera”与“Decal”。“CineCamera”电影摄像机组件,确保运行后我们视窗的位置。“Decal”贴花组件,可以很好的告诉用户鼠标是否悬停在物体上,这个组件根据个人可有可无。因为在运行后我们并不需要显示任何角色模型,所以这里我也没有为网格体增加骨骼模型。

E.2.2. 图表事件

  • 开始运行事件

       当运行时我们需要启用“CineCamera”摄像机作为我们的主视角

  • Tick事件      通过获取玩家控制器的光标命中结果获取到光标位置与命中物体的法线方向。之后通过位置来设置“Decal”贴花组件的位置,再由物体法线方向设置“Decal”贴花组件的角度。这样“Decal”贴花组件就可以跟随光标在物体上显示。

E.3. 游戏模式基础

       创建蓝图选择“游戏模式基础”类蓝图并命名为“visualization_Basics”用来设置我们模式的一些基础内容。这个蓝图也是将我们创建的角色蓝图与玩家控制器蓝图组合成了一个蓝图,如果不想创建也可以通过世界场景设置修改游戏模式。不过最好还是自行创建一个新的。

E.3.1. 类

       这里只需要修改“类”中的,玩家控制器类为“visualization_play”默认pawn类为“visualization_role”即可。

E.4. 世界场景设置

       最后我们通过“世界场景设置”下的“游戏模式”分类中的“游戏模式重载”,选择我们创建的“visualization_Basics”游戏默认基础即可将角色模式与控制模式带入。

F.图表蓝图

       柱状图表与曲线图表均是有1+N个柱状与曲线组合而成。其功能是完全相同的,调用数据通过颜色与标注进行数据区分。只是它们所调用的数据和所使用的颜色与标注有所不同。
所以这里我们至需要创建一个基础的图表蓝图后,通过基础蓝图创建子集实例。再由图表主蓝图当做子集Actor组件进行调用。

F.1. Histogram_Columnar

       首先我们创建一个Actor蓝图,并命名为Histogram_Columnar。之后我可以可以基于这个蓝图来创建对应所需数量的子蓝图来创建我们所需的数据图表。

F.1.1. 添加蓝图基础组件

       首先我们需要为蓝图添加一些基础组件分别是“Spline”样条组件“Sphere”5个静态网格组件,这里为了方便管理我还用到了2个“Billboard”公示板组件,用来管理模型很方便。
这里要注意其层级关系,因为我们要确保所有功能性模型都与样条组件为相对位置,所以生成的和手动添加的模型都需要在样条组件的子集。

  • Spline样条组件

       既然我们是在制作一个曲线与柱状结合的图表,那么我们就需要使用到UE的“样条组件”。UE本身并没有真正意义上的样条,如果我想渲染出样条的样子。我们就需要根据“样条组件”上的样条点去生成足够多的模型,来达到视觉的一条曲线。

  • Sphere静态网格体组件

       这里添加的5个“Sphere”静态网格体组件是用于后续添加交互而添加的。毕竟用户需要知道具体位置的具体参数。

F.1.2. 创建“构建图表”函数

       这里我构建了几个函数之所以为什么要用英文就不多说了。
但是还要为上期教程重新补充说明下,函数与事件的区别。上期教程里提到函数与事件的区别是,函数有返回值而事件没有返回值。
这次要补充的是。函数会等待函数结果,有结果后才会继续执行,事件只是触发有没有结果都往后执行
函数可以使用局部变量,而事件不能使用局部变量。局部变量就是只可在当前函数中使用的变量。函数执行的顺序有保证,他会按照咱们所连接的顺序挨个执行。函数被调用时会变成一个事件。
       结合上述补充的内容,所以建议各位在之后的学习中尽量优先使用函数。这里我尽可能的将每个功能单独封装成一个函数,这样可以更清楚的了解每段内容的具体功能和实现方法。

F.1.2.a.Build Chart分组

       这里时初始化生成模型,并设置基础模型与生成模块的一下基础参数的函数分组。

F.1.2.a.1Build Chart 

       这个函数时用来根据样条创建基础的模型的。

  1. 构建样条点位置

           首先我们需要先设置好样条的每个点固定位置,来确定样条的长度与每个数据的位置。这里的样条有5个点,所以我创建了5个向量浮点并创建去设置向前样条“Spline”。各位可以根据自己喜好去调整样条点数量。

  2. 设置样条中心位置

           为了能让样条实时自动位于蓝图的中心位置,我们需要对样条的相对位置进行一下构建。
           这里我们在设置完成样条的样条点后,可以通过获取样条长度,在用样条长度除以2之后去设置样条的相对位置,即可达到样条实时自动位于中心位置。

  3. 创建样条模型

           UE的样条组件并不会被渲染显示出来,所以在我们设置好样条基础参数后,需要生成我们所需的样条模型,来供使用者查阅。

  • 判断是否需要生成模型

       UE本身并没有什么“扫描”“放样”等功能,而如果我们需要渲染一条曲线或者不规则的面,我们则需要足够多的模型去拓步。让其互相链接从视觉上达到一种假象,实则是由多个模型拼凑而成的。
所以首先为了避免运行无用程序降低运行速度,我们需要判断下是否需要生成模型。
这里我设置了一个整数变量,“Number of columns”既是生成模型的数量,我们通过判断这个变量是否大于0再去执行之后的程序。同时请公开这个变量,供之后在子蓝图中可以直接编辑调用。

  • 根据Number of columns生成对应数量的模型

       假设”Number of columns“变量为”5“,For loop从”0“循环”Number of columns“减”1“,共循环5次(这里为什么要从0开始同时为什么要减”1“,因为所有代码技术都是从”0“开始技术,”0“即为”1“所以我们需要进行减”1“计算)。
之后根据长度长度与模型数量获得平均样条长度,来循环5次获取5个平均点的样条距离处的变换。
       得到每处的变换后我们需要创建一个新的变换。首先我们需要每处的X、Y位置用于确定模型的平面位置。然后我们通过Z轴位置来设置模型的生长高度(这里就要说道为将基础模型的轴心放置在最下方了。首先UE并没有具体尺寸这项设定,所以我们需要通过设置模型的缩放来控制模型的高度生长。既然通过缩放那么我就必须只要基础模型的具体参数然后通过数学计算来得到想要的高度)。这里我运用了一个除法运算并建立了一个浮点变量“Model z-axis scaling”并对其公开,这样我们就可以通过这个浮点变量来控制模型生长的比例,控制其生产的高度不至于超出咱们所设想的高度。最后我们将创建的这个变换循环设置给添加的静态网格体。

  • 将添加的静态网格附加到样条并设置模型

       之后为了方便管理与随意更换模型样式,我们需要将添加的静态网格附加到“Spline”作为子集,然后通过静态网格体变量“Added static mesh volume”来设置已经静态网格体模型样式。后续我们只需要在编辑器里拖拽模型到这个变量即可修改咱们想用的模型。

  • 创建模型数组,模型的基础和历史变换数组

       完成上述的所有操作后,我们就可以在视口看到程序自己所生成的模型了。但是咱们的数据不可能只有这么几条,所以为了让图表是可以实时获取最新数据或循环展示所有数据。我们就需要创建一些基础参数。
首先我们需要将所有已经生成的模型添加到一个数组变量里“Static grid component array”供我们后续循环调用这些模型。然后我们还需要创建2个变换数组变换“Transform data old”与“Transform data Basics”。
“Transform data old“用来储存历史变换的数值用作以后新数据变换的插值变量。
“Transform data Basics”用来存储基础的信息用来设置其基础信息,因为咱们变换都是发生在“Z轴”的所以其他变换我们并不需要重新设置,这样做也是为了避免发生错误。

F.1.2.a.2.Build Chart Sphere

       Build Chart Sphere函数是专门用来设置5个Sphere静态网格体位于样条的对应位置与生长高度,函数的方法与Build Chart函数大致相同这里我着重说明其中的不同点。

  1. 判断是否生成模型获取样条每段长度

    ○ 这里在判断是否生成模型时多增加了一条分支,如果不需要生成模型则循环设置每个“Sphere”为游戏中隐藏。

    ○ For loop节点并未使用变量进行控制则是手动输入的从0到4。

    ○ 这里设置的模型是预先设置好的,所以需要创建一个数组并根据循环返回的次数去索引“GET”设置数组中的每一个元素。各位也可以在运行这条函数前就将“Sphere”创建成一个静态网格体数组变量进行调用。

  2. 创建并设置相对变换、创建模型基础和历史变换数组

    ○ 因为模型时预先设置好的所以不在需要生成添加静态网格体,我们仅需去设置每个模型的变换即可。

    ○ 预先设置好的模型无需再次创建静态网格体数组,只需要分辨创建对应的基础与历史变换数组即可。

  3. 总结

       之所以创建这个函数,是因为图表上的每一个曲线或柱状都需要拥有交互行为,为用户提供每个时间点每个数据组上的对应参数。既然如此我们就需要游泳交互事件的真是模型组件,供我们通过调用触发某些事件来运行交互程序。而通过程序生成添加的模型时无法创建交互事件的。所以我们需要手动添加所需的交互模型。

F.1.2.a.3.Angle display

       当用户去旋转图表时因为模型本身会遮挡注一些位置不容易被用户查看到,而且当用户旋转图表到一定角度时我们图表则会从曲线图变换成柱状图。所以我们需要根据用户旋转得角度来讲不容易被查阅或者不许要的数据进行隐藏,来提高用户的阅读效率。而这个Angle display函数就是做这个用的。

  1. 创建旋转角度

           首先为了避免常事件的Tick事件减慢允许速度,我们需要一个布尔变量“Left mouse button”,通过按住或松开鼠标左键开判断是否执行“Angle display”。之后我们还需要获取到蓝图当前的旋转角度并加上90来设置一个变量“Angle”。之所以要加上90只为了能够更好的控制蓝图该从那个方向进行隐藏。

    ○ Angle变量详解

     下方识图为上视图,上方是背景位置,下方是摄像机位置,中坚则是Actor主体位置。
    如图中间绿色圆圈是默认Actor的旋转角度,蓝色圆圈则是Actor旋转加90后的角度。不知为何当Actor默认旋转到-180°/180°时就会切换正负值。
    其次我们需要当用户顺时针旋转Actor时让生成的模型从右到左依次隐藏或逆时针时从左到右依次隐藏,然后当旋转90°后反转隐藏。那么首先我们需要计算出每个生成模型的隐藏角度(模型数量除以90°/-90°),然后我们再去实时判断Actor是否达到模型需要隐藏的角度。
    这时就会出现一个问题,因为我们所得到每个模型隐藏角度均在0°到正负90°之间,那么如果我们使用默认的旋转就需要复杂的计算来判断Actor是否抵达模型消失角度。所以为了省去后续的复杂计算就绪在Angle变量上增加一个90°的基数。
    简单点来说,就是需要将360°分成左右2个部分,4个区域分别是蓝色区域的90°至0°、0°至-90°、270°至180°、180°至90°。之后就需要考虑当旋转到每个区域时是从那个方向隐藏或显示。
    90°至0°:从右到左隐藏
    0°至-90°:从左到右显示
    270°至180°:从左到右隐藏
    180°至90°:从右到左显示
     如此一圈,不管用户是顺时针转还是逆时针转都会有很好的体验。

  2. 创建模型角度正负值变量

           首先我们创建2个函数局部变量,分别是“Static grid component Angle positive(模型数字平均旋转正角度)”、“Static grid component Angle negative(模型数字平均旋转负角度)”。
           然后我需要拿到之前“Build Chart ”函数中所创建的静态网格体数组变量“Static grid component array”。通过“LASTINDEX”获取到数组中最后一个的索引值,用起进行整数加法运算加“1”,然后再进行浮点除法运算除以“90”就可以获取到数组中平均每个模型的旋转角度(之所以要浮点除法是因为角度不可能都是整数)。


  3. 判断旋转所在左右那个部分

           首先在函数运行之初我们就需要根据“Angle”来判断下用户在向左右那个部分进行旋转,从而筛选掉2个程序。


  4. 四个区域的计算与判断逻辑

           这里我只讲解下根据样条组件所生成的模型隐藏方式,后方还有一组是用来隐藏“Sphere”组件的计算逻辑,整体是一样的。


    4.1.左部分


    ○ 判断左部分区域

           我们可以通过“Angle”来进行一个范围内浮点的判断,将之前设置的“Static grid component Angle positive”输入给Min,Max设置为“90”,如果返回Ture当前旋转角度则在“90°至0°”,反之则在“0°至-90°”。


    ○ 90°至0°区域

           当前角度如果位于“90°至0°”的区域里时,循环设置“Static grid component array”数组中的每一个模型的可视性,我们可以通过循环获取到没一个模型的索引值并进行加“1”运算,然后用当前整数乘以“Static grid component Angle positive”变量即可获取到每一个模型所需要隐藏的角度,之后在于“Angle”变量进行小于等于布尔判断并对其可视性进行设置。这样就可以实现不在可视范围内的模型被隐藏,而在可视范围内的模型一直是显示状态。这里我在执行设置可视性之前还增加了一个布尔判断,为了是避免发生错误。


    ○ 0°至-90°

           当前角度如果位于“0°至-90°”的区域里时,基本的运算与“90°至0°”的运算方法大致相同。只是我们的判断角度变成了负值,所以我们需要用每个模型的索引去乘以“Static grid component Angle negative”得到一个负值角度在与“Angle”进行大于布尔判断。


    4.2.右部分


    ○ 判断右部分区域

           通过当旋转值右侧部分后我们也需要一个区域判断,只是这个判断运行略有不同。这里”Angle”变量进行了一次减法运算减去了“90”,也就以为着我们让”Angle”变回了原始默认的数值,但“Angle”变量没有变。如果返回Ture当前旋转角度则在“90°至180°”,反之则在“180°至270°”。


    ○ 90°至180°区域

           当前角度如果位于“90°至180°”的区域里时,运算方法与“90°至0°”几乎一致,只是我们需要在“Angle”后进行一次减法运算,保证输入值是原始默认数值,之后角度判断变成了大于。


    ○ 180°至270°区域

           “180°至270°”的运算同样与“0°至90°”的运算大致相同,只是可以看到我在“Angle”之后不仅进行了一次减90的运算,还又进行了一次减180的运行。这样我就将“180°至270°”这个区域变相的变成了“-90至0°”的区域。然后再用负角度变量进行小于布尔运行去设置可视性。


    4.3.Angle变量补充详解

           通过下图在结合上述我所说的,可以看到黄圈最后通过运算后的真实角度。
           截止到这里,图表的基础蓝图构建功能就算基本完成。


F.1.2.b.Details分组

       “Details”是一个细节初始化分组,针对一些细节来进行初始化设置。


F.1.2.b.1.Initialize Color

       “Initialize Color”是用来初始化基础蓝图内组件颜色的一个函数,通过还可以通过这个函数来调用调整    “Sphere”的后续交互性功能。


  1. 函数输入

           这里我们利用函数输入创建几个输入接口,方便后续跨蓝图调用并传送变量值。

    ○ Name_Color

           线性颜色接口基础的数据区分颜色值,主要用来控制循环生成的模型颜色。

    ○ Color_quotient

           线性颜色接口,用来这时”Sphere”的颜色

    ○ Color_coefficient

           浮点接口,用来设置“Sphere”的交互发光强度。

    ○ New_Visibility

           布尔接口,用于初始化“Sphere”是否在游戏中隐藏,后续我们通过这个接口来控制交互“Sphere”的隐藏和显示。

  2. 循环设置生成模型的材质

           我们可以通过循环获取“Static grid component array”数组内模型的材质,将其创建为动态材质实例,在把这个动态材质重新设置给模型,最后我们就可以通过函数的输入接口来控制设置材质上的对应线性颜色参数。

  3. 设置Sphere的材质

           这里是“Sphere”模型的颜色与交互时让其提高自发光亮度,其实我们也可以通过创建数组的形式来循环设置。这里主要说一下为什么我这设置线性颜色时进行一次“Name_Color”与“Color_quotient”的乘法运算。

           首先当前这个数组不管是生成的模型还是咱们手动添加的模型,其颜色应该属于相同色相,但是我们又需要在交互时可以让用户很清楚的看到交互功能的位置,所以就需要对齐进行一个区分,那么我这里用着2个进行相乘,就会得到一个亮度更高的一个颜色,即不脱离当前色相也能很好的区分。

  4. 设置Sphere是否隐藏

           最后我们需要循环设置“Sphere”在初始时为隐藏状态,之后我们可以通过事件来调用函数循环修改为显示。

F.1.2.b.2.Tangent

       “tangent”函数是一个细节控制函数,众所周知样条不管在什么软件中都是右数个点串联而成,每个点都会有2个切线来控制其样条弧度,UE也不例外。所以这里为了避免因为切线设置错误导致样条不够美观,我们需要初始化一下样条的切线参数。

  1. 根据样条点数量设置循环次数

           我们通过获取样条点的数量,然后进行减法运算减“1”,来设置For loop的循环次数。

  2. 设置样条点进入与离开的切线

           每个样条点都有一个进入切线与离开切线,每条切线又有一组XYZ值。我们可以通过这些值来获得我们所想要的样条样式。这里我只是简单的用了3个浮点变量将其设置为了一个相同的数值,如果有需要的可以自行增加一些参数。

F.1.2.c.Load Data分组

       “Load Data”是针对后续的“Load Data”事件而封装的数据加载动画函数。

F.1.2.c.1.Start Data

  1. 函数输入

           添加“Start Data”函数的输入接口,“Return Value”字符串数组。这个接口在后续的事件调用时用来传送我们所需要的数据表数据。

  2. 创建变量获取行数据

           我们有5个“Sphere”数据点可以用来数据,所以我们需要创建对应的5个整数变量作为索引获取5个数据。这里我将其命名为“Row Index”。并且按照顺序分别设置默认值“0、1、2、3、4”。之后通过“Row Index”索引“GET”获取到“Return Value”字符串数组里的指定数据。

  3. 设置样条点  获取到5个点的数值后,分别去设置5个样条点的“Z”轴数值。

F.1.2.c.2.Set build model New Transform

  1. 创建新的变换并循环设置

           我们需要创建一个新的变换数组变量“Transform data new”,并将循环生成的变换“ADD”在这个变量里。之后我们可以通过之间创建的“Transform data old”与”Transform data new“进行一个插值动画。

  2. 返回节点

           这时就要用到返回节点,来确保只有等函数循环完成后才可进行后续的程序。

F.1.2.c.3.Set Sphere New Transform

       “Set Sphere New Transform”函数与“Set build model New Transform”的功能相同,也是生成一个新的变换“Sphere_new”变量。同时也要注意需要使用返回节点。

F.1.2.c.4.Data Over Animation

       “Data Over Animation”函数是用来将数据进行动画过度的函数。这里一共运行2段动画,分别是针对生成的模型与Sphere模型。思路一样我就讲解其中一个。

  1. 函数输入

           讲解函数之前我说过,函数不能使用时间轴节点。那么我就需要在调用时为其传送一个时间轴信息。那么我就需要在函数输入创建一个浮点接口“animation”。

  2. 根据Number of Columns创建For循环

           同样我们需要创建一个循环执行,让所有生成的模型来执行通一条命令,但是所执行的参数各不相同。

  3. 设置动画

           这里我们可以将For循环的次数当做索引值,来获取各类数组中的对应内容。然后通过之前我们创建的“Transform data old”插值变化至“Transform data new”这个变换从而得到移动过度动画。这里可以看到插值的输入我只使用了变换的缩放,而其位置则是采纳的“Transform data Basics”变换的参数,这样做的好处就是必变计算错误导致模型位置错乱,毕竟这个基础位置是不变的,我们只需要调整模型的缩放即可。

F.1.2.c.5.Change Transform

       当我们的过度动画执行完毕后,我们需要更换新老变换数据,从而得到一个持续连贯下去的动画循环。

       “Change Transform”函数就是这个功能的核心。当动画执行完毕,首先我们要“CLEAR”清除掉“Transform Data Old”变换数组内的所有内容。之后将“Transform data new”变换数组的内容设置为“Transform data old”。最后在将“Transform data new”清除。这样当下次动画开始时,就会已当前动画结束的位置为基础重新开始。

F.1.2.c.6.Replace Row Index

       在我们完成新老变换更换之后,我们需要重新获取新的数据参数,那么就需要对5个“Row Index”变量进行更改。在更改的同时还要考虑到如果“Row Index”运行到最后一个索引值时需要让其该更改第一个索引“0”。这样才能做到无限循环。

  1. 函数输入

           首先我们需要创建一个字符串数组输入接口“Return Value”用来获取列数据。

  2. 判断并设置索引

           接下来我们通过获取到的字符串数组来获取到“LASTINDEX”最后一个索引。在用“Row Index”与最后一个索引做等于布尔。如果“Row Index”等于最后一个索引,那么设置“Row Index”为“0”第一个索引。如果“Row Index”不等于最后索引,那么“Row Index”当前数值加“1”运算后再次设置。

    这样一来我们就可以确保,当动画循环到最后一个数据后重新重头开始,也可以让其正常的加“1”循环下去。


  3. 返回节点

           为了避免报错跳过我们需要在最后加上一个返回节点。


F.1.2.d.构建脚本

       所有函数都完成后,我们需要开始构建脚本了。

       这里我使用了一个“序列”节点,避免那个函数出问题后不在往后进行。

       首先我们需要先构建自动生成的模型与“Sphere”的位置,也就是“Build Chart ”和“Build Chart Sphere”。然后我们需要构建样条切线“Tangent”。最后同样为了避免错误我们需要将“Row Index”变量也构建一下(不知道为什么UE5的默认值有的时候总有问题)。


F.1.3. 图表事件


       在我们将所有函数构建完成后,就是要将其串联起来最终得到我们想要的效果。


F.1.3.a.Load data 

       当开始运行时,我们需要开始加载数据表里的数据,并且让以动画过度的形式循环加载。


  1. 将数据表列获取为字符串

           首先我们创建一个数据表变量“Spline_Points”与命名变量“Property Name”,并且对“Property Name”进行公开。这样我们就可以在不同的子蓝图里通过修改这个变量来调用不同的列数据。


  2. 加载数据设置生成模型与Sphere的新老变换之后就用到我们之前创建好的几个函数了。将获取的数据列字符串传输给“Start data”函数设置样条点位置,之后通过“Set build model New Transform”函数循环获取每个生成模型的新的变换数组,循环完成当前函数后,执行“Set Sphere New Transform”循环获取“Sphere”的新的变换数组,循环完成后执行后续动画内容。


  3. 从头开始播放动画

           开始从头播放时间轴动画(事件长度根据自己喜好自行设置,保证浮点时从0到1即可)。动画所执行的内容既是“Data Over Animation”,我们要将时间轴的浮点值传送给“Data Over Animation”的输入接口,从而达到插值动画。


  4. 动画播放完成执行

           动画播放完成执行“Change Transform”对新老变换进行清除和设置,设置完成后运行“Replace Row Index”根据数据表类字符串设置“Row Index”,设置完成后再次返回到事件开始位置再次循环。


  5. 注意事项

           这个事件中还有一个“Mouse_hover”与2个布尔判断,这2个位置会在后续的内容中说明作用。在当前事件没有这2处内容是可以完美循环获取数据的。


F.1.3.b.事件开始运行

       在开始运行时我们就让程序开始执行“Load data ”从而达到一个可控的Tick事件。


F.1.3.c.mouse_hover

       “mouse_hover”事件是为了当用户在与图表进行交互时,停止图表的数据加载让用户查看当前数据而存在的事件。

       首先我们需要创建一个“自定义事件”并设置一个布尔输入接口“Hover”。之后创建在时间轴节点前后各增加一个分支节点,将“Hover”参数赋予它们。

       现在来说一下这个看似简单的事件的功能逻辑。当鼠标悬停在图表时,触发“mouse_hover”事件,并且传输“Hover”变量为”False”,这时动画会播放到最后一针,但不会触发动画的完成事件。这样做可以让图表停止在正确的标注线上,而不是直接停止,直接停止则会出现显示数据与图表标注数据不符的现象。而当鼠标离开图表时,触发“mouse_hover”事件,并且传输“Hover”变量为”True”,则会根据当前时间轴停止的位置继续播放,而停止的位置是最后一针,那么时间轴则会触发完成事件之后后续事件,然后开始循环。


F.1.3.d.鼠标悬停事件

       创建好动画停止与继续的事件后,我们就可以通过UE蓝图的鼠标开始悬停与鼠标结束悬停事件来调用“mouse_hover”事件。

       因为我们后续是需要调用1+N个子集实例蓝图,所以当用户进行操作时是需要停止多个子集。为了避免发生错误,我们需要先创建一个布尔变量“Hover”。之后我们就需要通过“获取类的所有actor”节点来获取到所有的“Histogram_Columnar”蓝图,之后通过“For Each Loop”节点循环执行设置“Hover”变了并赋予执行“mouse_hover”事件。


F.1.3.e.小结

       最后剩下“mouse_hover_Sphere”里的种自定义事件“Columnar_Hidden”“Columnar_Show”因为是跨蓝图事件,暂时先不在这里说明。待我们将主蓝图创建完成后再来详细说明。


F.2. Histogram_Basics

“Histogram_Basics”蓝图将作为我们在场景中调用的主蓝图。我们通过这个蓝图可以添加1+N个“Histogram_Columnar”蓝图。在配合其他组件从而得到一个完整的图表。

F.2.1. 添加蓝图基础组件

首先我们可以看出,这次的组件结构非常的多。因为所有图表均由时间线、数据值标线、数据名称标注与数据图表构成。这样一来我们可以将其分成“Numerical line(数据值标线)”、“Name line(名称标线)”、“tagging(数据名称标注)”、“Time line(时间标线)”这4大类,其中所使用到的组件类型主要是“静态网格体组件”与“文本渲染组件”。下面我会挨个分开先把这些组件的具体作用讲解透彻。


  • 静态网格体组件

  1. 线

    就一个细长的立方体组件,主要用来当做线来时使用为用户划清边界与进行数据参考。


  2. 标注

    标注类一个静态网格组件,由一个平面模型构成。这里我命名为了“Plane”主要用于显示各类数据的颜色便于用户区分数据,其次拥有一个点击显示或隐藏数据的功能。

    创建好这个组件后,我们就需要将之前准备的“Name_tagging”材质创建一个子集实例材质赋予给这个静态网格体组件,供我们之后动态调用对应数据颜色使用。


  • 文本渲染组件

    文本渲染组件是用来将文本专为一种可视模型的组件。这个组件需要配合之前准备的“Oswald_material”文本材质来使用。

    首先设置材质的“元素0”与“文本材质”,之后选择对应的我们之前所使用的字体。剩下的就是一个基础的排版格式就不多说了。


  • Numerical line

    “Numerical line”是数据参数标线,我们需要让用户知道图表当前所在的对应数值位置。


  • Time line

    对于折线型图表,我们不仅需要数据参数的标线。还需要一个横向的时间标线。“Time Line”就是用于循环更新时间的一组功能组件。


  • tagging

    “Tagging” 是由数个“文本渲染组件”+”Plane”组件组合而成一个数据标注组件。其用途就是对数据折线进行颜色与文本标注的区分。其次为了可以使用户单独查阅某一组数据还增加了点击显示与隐藏的功能。


  • Name line

    当我们将图表旋转到一定角度,使图表变换成柱状图表时,那么我们将不在需要时间线的组件,将与之替代的是每组数据对应的名称。


  • Name Year

    当图表位于柱状图表模式的时候,虽然我们不需要时间线的显示方式了。但是数据还是需要进行更新,而更新这就需要向用户提供当前更新数据的具体时间时间。而“Name Year”这组组件就是用于想用户提示当前数据的时间的组件。


声明:* 本站所提供的资源均来源于互联网,站内所有文字、图片内容由网站会员上传而来,UI社不具备此内容的版权。由于将本站资源用于商业用途而引起的纠纷,本站不负任何责任。如果有侵犯到您的权益,请联系本站删除,谢谢合作!联系邮箱:Uishe#qq.com (请将[#]换成@)